clusev/.github
boban 10486672a5 ci: build+push prod images, gated auto-promote to public
Backbone sub-project #1, CI half (verified with actionlint; the runtime proof is
the first rc/stable tag push — these jobs cannot run locally).

- ci-staging.yml:
  - new `images` job (needs: test): buildx builds clusev-app (Dockerfile) +
    clusev-terminal (docker/terminal/Dockerfile) → private GHCR, tagged by
    version; then a framework smoke-boot (`php artisan route:list`) so a class
    stripped by export-ignore that is still reachable on boot fails before promote.
  - `deploy-staging` widened to any tag; pulls the CI-built private image
    (CLUSEV_IMAGE/CLUSEV_TERMINAL_IMAGE + CLUSEV_PULL=1) instead of building.
  - new gated `promote` job (needs: [test, images], if success + stable vX.Y.Z,
    no -rc): copy the exact image digests to the public GHCR, run promote.sh
    (leak-guard + export-ignore tree), write release-images.lock, push code+tag.
- promote-public.yml: repurposed as a guarded manual fallback mirroring the auto
  promote (image copy + lock + guard). Dropped the "beta channel" naming.
- promote-stable.yml: removed (no beta→stable step in a single-channel model).

Deploy inputs are GitHub vars/secrets (GHCR_OWNER, PUBLIC_GHCR_OWNER,
PUBLIC_REPO_SLUG, STAGING_*, GHCR_TOKEN, PUBLIC_REPO_TOKEN, PROMOTE_FORBIDDEN) —
never hardcoded.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-03 20:34:00 +02:00
..
workflows ci: build+push prod images, gated auto-promote to public 2026-07-03 20:34:00 +02:00
actionlint.yaml ci: test on v* tags, optional self-hosted staging deploy on betas 2026-06-22 21:03:14 +02:00