Skip to content

Bake channels: a bake reaches buyers only after its smoke clone passes - #310

Open
vsilent wants to merge 1 commit into
devfrom
feature/bake-channels
Open

vsilent wants to merge 1 commit into
devfrom
feature/bake-channels

Conversation

@vsilent

@vsilent vsilent commented Oct 26, 2026

Copy link
Copy Markdown
Collaborator

Stage 4 of config/docs/BAKE_PIPELINE_PLAN.md.

Problem. Clone picks the newest healthy snapshot. A fresh bake reaches buyers immediately, whether or not its smoke clone passed.

Change

  • Migration 20261026100000_baked_snapshot_channels:
    • baked_snapshot_channels: one pointer per stack/provider/channel (unstable / latest / stable);
    • baked_snapshots.gated;
    • Casbin rule for the new route (group_admin, admin_service).
  • POST /api/admin/bake records the snapshot as gated and points unstable at it, in one transaction.
  • New POST /api/admin/bake/{id}/promote (bake job id). After a green smoke clone it moves latest ← unstable and stable ← old latest, using helpers::bake_registry::promote_ladder.
    • The stack's pointers are locked during the move.
    • Only the current unstable can be promoted: 409 otherwise, and 409 while the bake is not done.
    • A repeated promote is a 200 no-op.
  • baked_snapshot::resolve / resolve_latest (clone and validate) pick latest, then stable, then the newest ungated healthy snapshot.
    • Snapshots recorded before this migration, and by the bake binary, are ungated, so existing Quick Deploy links behave as before.
  • Why gated exists (not in the plan): without it, a bake whose smoke failed would lose its unstable pointer at the next bake and become "newest healthy". There is a test for this.

Tests. tests/bake_channels.rs, 4 tests, written failing first:

  • an unpromoted bake is never served, not even by its version;
  • promotion order and stable;
  • a failed bake stays hidden after the next bake;
  • legacy and unknown snapshots cannot be promoted;
  • the HTTP route returns 409 / 403 / 200 / no-op / 404.

Unchanged and green: admin_bake, migration_boot_contract, quick_deploy_server_type, and --lib (2302). clippy reports nothing in the changed files.

Follow-up, not in this PR. awesome-selfhosted-stacker scripts/bake_pipeline.py must call /promote after a green smoke clone. Until then, new API bakes stay on unstable and are not served.

🤖 Generated with Claude Code

A bake started from POST /api/admin/bake now lands on the `unstable`
channel, which no buyer gets. POST /api/admin/bake/{id}/promote (called by
the harness after a green smoke clone) moves it to `latest`; the previous
`latest` becomes `stable`. Clone and validate resolve `latest`, then
`stable`, then the newest ungated snapshot, so stacks baked before this
change (and by the `bake` binary) keep working.

- migration: baked_snapshot_channels (pointer per stack/provider/channel),
  baked_snapshots.gated, Casbin rule for the promote route
- db::bake_registry: point, state, promote (one transaction, pointers
  locked; only the current `unstable` can be promoted; a repeat is a no-op)
- `gated` keeps a bake whose smoke failed hidden after the next bake
  replaces the `unstable` pointer

Tests: tests/bake_channels.rs (written failing first).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@vsilent

vsilent commented Oct 26, 2026

Copy link
Copy Markdown
Collaborator Author

Re-verification: the test run I re-did just before committing this PR was silently skipped, because the local test Postgres had gone down when the disk filled up. Re-run today against real Postgres, with no skips: bake_channels 4/4, admin_bake 2/2, quick_deploy_server_type 2/2, migration_boot_contract 11/11, --lib 2302 — all green.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants