• admin released this 2026-05-21 10:36:40 -06:00 | 9 commits to main since this release

    Release v2.10.2 (a7d3dd7)

    Downloads
  • admin released this 2026-05-20 11:38:36 -06:00 | 14 commits to main since this release

    Patch on top of v2.10.0 bringing in HLS (21208b5), docs refresh (1f240ad), campaign card tweaks (3f6102c), and the gancio config-init sidecar fix (a82e959). Cut to make semver-latest point at HEAD.

    Downloads
  • admin released this 2026-05-18 14:34:20 -06:00 | 16 commits to main since this release

    Changes since v2.9.13

    • Docs: DEV_WORKFLOW.md now reflects the 5-image build pipeline (api, admin, media-api, nginx, ccp-agent) instead of the outdated 4-image description.
    • UI: Public campaigns list card layout — title moved below the cover photo instead of overlaying it, so titles remain legible when no cover image is set.

    Images

    All 5 service images published to gitea.bnkops.com/admin:

    • changemaker-api:3f6102c + :latest
    • changemaker-admin:3f6102c + :latest
    • changemaker-media-api:3f6102c + :latest
    • changemaker-nginx:3f6102c + :latest
    • changemaker-ccp-agent:3f6102c + :latest

    Third-party image mirrors unchanged from previous release.

    Install

    curl -fsSL https://gitea.bnkops.com/admin/changemaker.lite/raw/branch/main/scripts/install.sh | bash
    

    Upgrade existing install

    ./scripts/upgrade.sh                  # source install
    ./scripts/upgrade.sh --use-registry   # fast path: pull pre-built images
    
    Downloads
  • admin released this 2026-04-30 19:37:44 -06:00 | 16 commits to main since this release

    Highlights

    HLS Adaptive Bitrate Streaming (with MP4 fallback)

    Videos now stream as multi-bitrate HLS (360p / 720p / 1080p) instead of a single MP4 served via HTTP range requests. Range-request bursts were the root cause of stutter through the Newt tunnel; HLS chunks are small and tunnel-friendly, and the player adapts bitrate to bandwidth.

    What's new:

    • New BullMQ hls-transcode queue (in-process worker, concurrency 1) that runs FFmpeg single-pass with aligned keyframes
    • Master + variant playlists served at /api/{videos|public}/{id}/hls/* with HMAC-signed URLs
    • Player prefers HLS when ready; MP4 fallback engages automatically on 2 NETWORK_ERRORs
    • useHls() hook lazy-imports hls.js (~75 KB gzipped) — never enters the main bundle
    • Native HLS on Safari / iOS, hls.js on Chrome / Firefox / Edge
    • ShortsPage prefetches the next 3 master manifests via <link rel="prefetch">
    • Hover-preview cards stay on MP4 (avoids 200 ms hls.js init latency)

    Operator opt-in:

    • Feature flag: ENABLE_HLS_TRANSCODE (default false) — when off, uploads are tagged SKIPPED and the player falls back to MP4 (fully reversible)
    • Backfill existing videos: docker compose exec api npm run backfill:hls (~2 min per 1080p video, ~30 / hour throughput)
    • media-api resource limits bumped to 4 CPU / 2 GB for FFmpeg headroom
    • Schema migration 20260430225432_add_hls_fields adds HlsStatus enum + 6 fields on Video + index — applies automatically on prisma migrate deploy

    Video serving fixes

    • New per-URL HMAC media signing (POST /api/media/sign) replaces the legacy ?token=<JWT> pattern that was removed server-side on 2026-04-12. Admin previews of unpublished media work again, and signature TTL refresh logic prevents mid-playback expiry.
    • useSignedMediaUrl hook caches signed URLs in-memory and de-duplicates in-flight sign requests, so a 50-thumbnail list issues 50 requests on first mount and zero on subsequent renders within TTL.
    • Cleanup of legacy media URL helpers across VideoCard, VideoPlayer, VideoViewerModal, AlbumCard, AlbumDetailDrawer, PhotoCard, PhotoViewerModal.

    Docs & screenshots

    • Added 13 mobile/desktop screenshots covering volunteer flows: dashboard, achievements, activity, canvass map, discover, feed, friends, notifications, profile, routes, shifts.
    • Updated volunteer docs (achievements.md, canvassing.md, index.md, shifts.md, social.md) to reference the new screenshots.
    • Removed the public SECURITY_REDTEAM_2026-04-12.md writeup from the repo (red-team artifacts shouldn't ship in the source tree).

    Upgrade notes

    • Schema migration runs automatically on first start: prisma migrate deploy is part of the api entrypoint.
    • HLS is off by default. Set ENABLE_HLS_TRANSCODE=true in .env and restart api + media-api to enable. Then run docker compose exec api npm run backfill:hls to transcode pre-existing videos.
    • Disk planning: HLS variants add ~1.5–2× the original MP4 size per video (3 renditions + segments). Check df -h /media/local/hls before backfilling a large library.
    • No breaking changes for existing MP4 streaming — the fallback path is preserved.

    Install / Upgrade

    # New install
    curl -fsSL https://gitea.bnkops.com/admin/changemaker.lite/raw/branch/main/scripts/install.sh | bash
    
    # Upgrade existing install
    ./scripts/upgrade.sh
    # Or fast-path with pre-built images:
    ./scripts/upgrade.sh --use-registry
    

    Commits in this release

    • 1f240ad Docs updates
    • 21208b5 feat(media): HLS adaptive bitrate streaming with MP4 fallback
    • 2ae7d8b Bug fixes for video serving and updates to documentation for mobile use screenshots
    Downloads
  • admin released this 2026-04-30 19:07:17 -06:00 | 16 commits to main since this release

    Release v2.9.13 (1f240ad)

    Downloads
  • admin released this 2026-04-23 11:47:02 -06:00 | 19 commits to main since this release

    Release v2.9.12 (aba935c)

    Downloads
  • admin released this 2026-04-23 10:54:24 -06:00 | 20 commits to main since this release

    Release v2.9.11 (4ccc433)

    Downloads
  • admin released this 2026-04-16 20:55:15 -06:00 | 22 commits to main since this release

    Release v2.9.10 (6d562da)

    Downloads
  • admin released this 2026-04-16 15:17:54 -06:00 | 27 commits to main since this release

    Install flow follow-up — extract preservation + release drift protection

    Two small but real polish items landed right after v2.9.8 based on friction observed during the v2.9.8 end-to-end test. Both commits are scripts-only; no image rebuild.

    Upgrade notes: Safe upgrade. The behaviour changes only manifest in failure/build paths — happy-path installs are identical to v2.9.8.


    Patch 1 — scripts/install.sh preserves extract on config-wizard failure

    Commit: 20f4bcd3

    Previously, when config.sh could not start (classic case: curl | ssh bash over non-interactive SSH failing at /dev/tty), the cleanup trap removed $INSTALL_DIR because .env hadn't been written yet. The 15 MB tarball had already extracted cleanly — but the user was forced to re-download to retry on a console.

    New EXTRACT_COMPLETE state flag: the trap now distinguishes "extract OK, wizard didn't run" from "extraction itself failed". First case preserves the dir and prints a resumption hint:

    [INFO]  Tarball extracted to /tmp/test-install-dir — preserving.
    [INFO]  To finish setup on an interactive console:
               cd /tmp/test-install-dir && bash config.sh
    [ERROR] Configuration wizard could not run (likely no TTY available).
    

    The user can then cd into the preserved dir and complete setup on a real console, zero re-download.


    Patch 2 — scripts/build-release.sh whitelist parity check

    Commit: 5d497b79

    During the v2.9.8 sprint we added three scripts (pangolin-teardown.sh, ccp-deregister.sh, validate-env.sh) and had to manually remember to add each to build-release.sh's shipping whitelist. Forgetting is silent — the script just doesn't ship, breaking the release in subtle ways.

    Replaced the implicit for-loop with two explicit arrays and a pre-build assertion:

    RUNTIME_SCRIPTS=(...)     # ship in tarball
    DEV_ONLY_SCRIPTS=(...)    # stays on dev/build machines
    

    Every scripts/*.sh must be classified as one or the other. An unclassified script aborts the build with a clear error naming the file, so the next sprint can't silently ship a broken tarball.

    Side-effect fixes from this audit:

    • register-with-ccp.sh is now shipped (was only in source, needed for retrofitting CCP onto existing installs)
    • update-env.sh is now shipped (safe .env updater used by upgrade flows)

    Release tarballs now contain 20 scripts (up from 17 in v2.9.8).


    Verified end-to-end

    On marcelle:

    • curl -fsSL .../install.sh | bash -s -- --dir /tmp/test-install-dir --version v2.9.9 over non-TTY SSH → extract preserved, resumption hint printed, /tmp/test-install-dir/ retained
    • ./scripts/build-release.sh --dry-run with a hypothetical unclassified scripts/*.sh → aborts with named error
    • ./scripts/build-release.sh --tag v2.9.9 --upload → succeeds on fresh tag without --replace (validates the v2.9.8 safety going the right direction)
    • Marcelle's live v2.9.8 install continued to run through the test (no teardown needed)
    Downloads
  • admin released this 2026-04-16 13:21:44 -06:00 | 29 commits to main since this release

    Installation UX & CCP Integration Polish

    This release is the outcome of an end-to-end install-testing sprint on a clean host. Ten friction points surfaced — all addressed. No image rebuilds in this release (changes are scripts + docs); the v2.9.7 container images are still current.

    Upgrade notes: Safe upgrade for existing installs — no schema changes, no breaking flag changes. ./scripts/upgrade.sh picks up the new tarball; admin users can re-run bash config.sh to regenerate the Next Steps block if desired (not required).


    Install flow hardening

    Host-port preflight in install.sh (commit a7daf5ff)

    The installer now runs ss -Htln against the ~14 required ports before downloading the tarball and aborts with specific remediation hints if any are bound. Catches the cockpit-on-9090 class of collision that previously manifested as a partial-stack startup failure mid-compose up.

    [OK]    Prerequisites OK
    [OK]    Docker daemon is running
    [OK]    Disk space: 143677MB available
    [OK]    Host ports available
    [INFO]  Downloading Changemaker Lite v2.9.8...
    

    Admin password persistence (commit b92ca4f3)

    When config.sh -y is run without --admin-password, the auto-generated password is now written to data/admin-credentials.txt (mode 0600) in addition to being printed once to stdout. Users piping output to tee or missing the scroll no longer lose the password. Explicit --admin-password is never persisted.

    Pangolin credential smoke test (commit b92ca4f3)

    config.sh -y now verifies --pangolin-api-key/--pangolin-org-id against /org/:id/resources before committing them to .env. Typos and revoked keys fail fast with a clear message instead of surfacing much later as a broken Newt tunnel. Skip with --skip-pangolin-check for offline bootstrap.

    Next Steps surface new tools (commit a7daf5ff)

    After config.sh -y completes, the Next Steps block now points users at:

    • bash scripts/test-deployment.sh --wait 60 — verify the install is healthy
    • bash scripts/validate-env.sh — re-check .env + host ports
    • bash scripts/pangolin-teardown.sh — clean reset before reinstall

    Also notes the realistic first-boot timing (~3 min image pulls + ~90s stabilization) so brief unhealthy statuses don't confuse first-time users.


    New scripts

    scripts/pangolin-teardown.sh (commit 6602d14e, shipped in release)

    Wrapper for wiping a Pangolin org's resources + sites before a fresh install. Reads credentials from .env or takes --api-url/--api-key/--org-id flags. Dry-run by default; --yes to execute. Deletes resources before sites to avoid orphans. Safety via --keep-site-ids.

    scripts/ccp-deregister.sh (commit e8c862f7, shipped in release)

    Companion to pangolin-teardown.sh for installs that phone-home registered with a Changemaker Control Panel. Removes the CCP-side Instance row during teardown. Without this, a stale row blocks re-registration of the same slug. Dry-run by default. Matches by agentUrl (default from .env), --slug, or --instance-id.

    Full teardown sequence for a CCP-registered install:

    bash scripts/ccp-deregister.sh --token $ADMIN_TOKEN --yes
    bash scripts/pangolin-teardown.sh --yes
    docker compose --profile monitoring down -v --remove-orphans
    sudo rm -rf ~/changemaker.lite
    

    Changemaker Control Panel integration

    Tunnel cleanup on deleteInstance (commit 6602d14e)

    CCP admins clicking "Delete Instance" previously left the Pangolin site + all its resources orphaned for the lifetime of the org. Now deleteInstance() calls teardownTunnel() before composeDown when pangolinSiteId is set. Best-effort with try/catch matching the existing Docker-cleanup tolerance pattern — if Pangolin API is unreachable, the delete still completes.

    Slug conflict returns clean 409 (commit b8ec6286)

    The agents/registrations/:id/approve handler previously leaked a raw PrismaClientKnownRequestError on slug uniqueness violations. Now returns a 409 SLUG_CONFLICT with a message pointing at the fix:

    "Slug 'changemakerlite' is already in use by another Instance. Delete
    the stale instance first (DELETE /api/instances/:id) or run
    scripts/ccp-deregister.sh from the target host."
    

    Agent poll rate limit + exponential backoff (commit c8d0e9fe)

    Split the one-size-fits-all rate limiter:

    • /register keeps the strict 10/15min (invite-code brute force is the real attack surface)
    • /poll gets a new looser limiter at 180/15min (one poll per ~5s upper bound)

    Agent-side: replaced the fixed 30s setInterval with a self-scheduling setTimeout loop that backs off exponentially on HTTP 429 (30s → 60s → 120s → 300s cap) and resets to 30s on any successful poll. Fixes the "agent wedged at 429, restart required" workaround that bit us at the 15-minute approval SLA mark.


    Release hygiene

    build-release.sh --replace safety (commit 8fdcded2)

    --upload now checks for an existing release at the given tag before POSTing. If found and --replace is not set, errors out with a clear warning. Prevents the silent-overwrite problem where users on a version see "no update available" because the upgrade-check compares tags, but the tarball contents have changed underneath them. --replace remains available for deliberate test-bench iteration (DELETE + recreate).

    Shipped scripts added to tarball whitelist

    scripts/build-release.sh now includes validate-env.sh, pangolin-teardown.sh, and ccp-deregister.sh in the release tarball. Previously these existed in source but weren't packaged.


    Documentation

    Docs are the point of truth; all the above is reflected in:

    • mkdocs/docs/docs/getting-started/prerequisites.md — new warning covering cockpit and host-port collisions
    • mkdocs/docs/docs/getting-started/installation.mdtest-deployment.sh workflow, admin password file, teardown sequence
    • mkdocs/docs/docs/getting-started/first-steps.md — where to find the generated password
    • mkdocs/docs/docs/getting-started/control-panel.md — new "Registering an Existing Install (Phone-Home)" section with rate-limit + backoff behaviour and the ccp-deregister.sh teardown path
    • README.md — Quick Start block reflects reality including useful-tools list
    • DEV_WORKFLOW.md--replace safety for release hygiene

    Verified end-to-end

    The release was validated on a clean Ubuntu Server test bench (hostname marcelle): teardown → fresh install via install.shconfig.sh -y --enable-all with --ccp-* flags → docker compose up -dtest-deployment.sh --wait 60:

    • 37/37 passed, 0 warnings, 0 skipped (all containers healthy, API responding, tunnel subdomains reachable, DB seeded)
    • CCP registration round-trip works first-try (certs delivered on 2nd poll, ~60s)
    • SLUG_CONFLICT 409 surfaces correctly when re-registering without deregister
    • ccp-deregister.sh --yes unblocks re-registration cleanly
    • build-release.sh --upload refuses to overwrite existing tag without --replace
    Downloads