publish-image: auto-promote runtime_image_pins after push (RFC #529 Layer A) #16

Open
hongming wants to merge 1 commits from rfc-529-layer-a-auto-promote-pin into main
Owner

Summary

After Build & push succeeds, this workflow now POSTs the just-pushed digest to the controlplane admin endpoint POST /cp/admin/runtime-image/promote so runtime_image_pins.codex auto-bumps with each green publish — closing the gap documented in reference_codex_pin_no_autopromoter_exists.

Gitea 1.22.6 has no on: workflow_run, so promotion has to live as a terminal job in this same workflow (cannot be a separate workflow listening on publish-image SUCCESS).

Changes (~55 LoC, additive)

  • Push step gets id: push so its outputs.digest is addressable
  • publish job exposes outputs.digest = steps.push.outputs.digest
  • New promote-pin job: needs: [resolve-version, publish], if: success() && github.ref == 'refs/heads/main', POSTs {template_name, image_digest, git_sha, notes} with Bearer CP_ADMIN_API_TOKEN. Fail-loud on non-2xx — no silent strand.

Verified against vendor / source

API shape confirmed against molecule-controlplane/internal/handlers/pin_runtime_image.go PromoteRuntimeImageRequest struct + runtimeImagePinTemplates catalog at HEAD; live GET /cp/admin/runtime-image returns existing pins (sanity check that endpoint is reachable + auth shape works).

Secrets / persona

CP_ADMIN_API_TOKEN repo secret already provisioned on this repo (matches SSOT /shared/cp-admin-api-token). Persona widened: devops-engineer (publish-runtime cascade owner) per feedback_no_new_identities_widen_existingno new identity minted.

RFC scope

Layer A only. Layer B (fleet rollout) and Layer C (in-use safety) are explicitly out of scope; tracked as separate phases under RFC molecule-ai/internal#529.

Test plan

  • CI green on this PR (ci.yml + secret-scan.yml)
  • On merge, watch publish-image run: Push step exposes digest, promote-pin job logs HTTP 2xx + notice::runtime_image_pins.codex bumped
  • Read back GET /cp/admin/runtime-image — pin row for codex shows the new digest + git_sha matching this PR's merge commit
  • If promote fails (network / 5xx), the operator-config drift-reconcile cron (separate PR) catches it within 60s

Refs

  • RFC molecule-ai/internal#529 (Layer A)
  • reference_codex_pin_no_autopromoter_exists (original gap)
  • feedback_no_new_identities_widen_existing (persona policy)
  • feedback_check_vendor_docs_and_actual_source_before_guess_api_shape (API shape verified against pin_runtime_image.go)
## Summary After Build & push succeeds, this workflow now POSTs the just-pushed digest to the controlplane admin endpoint `POST /cp/admin/runtime-image/promote` so `runtime_image_pins.codex` auto-bumps with each green publish — closing the gap documented in [`reference_codex_pin_no_autopromoter_exists`](https://git.moleculesai.app/molecule-ai/internal/issues/209). Gitea 1.22.6 has no `on: workflow_run`, so promotion has to live as a terminal job in this same workflow (cannot be a separate workflow listening on publish-image SUCCESS). ## Changes (~55 LoC, additive) - Push step gets `id: push` so its `outputs.digest` is addressable - `publish` job exposes `outputs.digest = steps.push.outputs.digest` - New `promote-pin` job: `needs: [resolve-version, publish]`, `if: success() && github.ref == 'refs/heads/main'`, POSTs `{template_name, image_digest, git_sha, notes}` with Bearer `CP_ADMIN_API_TOKEN`. Fail-loud on non-2xx — no silent strand. ## Verified against vendor / source API shape confirmed against `molecule-controlplane/internal/handlers/pin_runtime_image.go` `PromoteRuntimeImageRequest` struct + `runtimeImagePinTemplates` catalog at HEAD; live `GET /cp/admin/runtime-image` returns existing pins (sanity check that endpoint is reachable + auth shape works). ## Secrets / persona `CP_ADMIN_API_TOKEN` repo secret already provisioned on this repo (matches SSOT `/shared/cp-admin-api-token`). Persona widened: `devops-engineer` (publish-runtime cascade owner) per [`feedback_no_new_identities_widen_existing`](https://git.moleculesai.app/molecule-ai/internal/issues/100) — **no new identity minted**. ## RFC scope Layer A only. **Layer B** (fleet rollout) and **Layer C** (in-use safety) are explicitly out of scope; tracked as separate phases under RFC molecule-ai/internal#529. ## Test plan - [ ] CI green on this PR (ci.yml + secret-scan.yml) - [ ] On merge, watch publish-image run: Push step exposes digest, promote-pin job logs HTTP 2xx + `notice::runtime_image_pins.codex bumped` - [ ] Read back `GET /cp/admin/runtime-image` — pin row for `codex` shows the new digest + git_sha matching this PR's merge commit - [ ] If promote fails (network / 5xx), the operator-config drift-reconcile cron (separate PR) catches it within 60s ## Refs - RFC molecule-ai/internal#529 (Layer A) - `reference_codex_pin_no_autopromoter_exists` (original gap) - `feedback_no_new_identities_widen_existing` (persona policy) - `feedback_check_vendor_docs_and_actual_source_before_guess_api_shape` (API shape verified against `pin_runtime_image.go`)
hongming added 1 commit 2026-05-19 02:14:58 +00:00
publish-image: auto-promote runtime_image_pins after push (RFC #529 Layer A)
CI / validate (push) Blocked by required conditions
CI / validate (pull_request) Blocked by required conditions
CI / Adapter unit tests (push) Successful in 1m46s
CI / Template validation (static) (push) Successful in 2m11s
CI / Template validation (static) (pull_request) Successful in 31s
CI / Adapter unit tests (pull_request) Successful in 1m16s
CI / Template validation (runtime) (push) Failing after 42s
CI / T4 tier-4 conformance (live) (push) Failing after 3s
CI / Template validation (runtime) (pull_request) Failing after 41s
CI / T4 tier-4 conformance (live) (pull_request) Failing after 3s
1a9b47c360
After Build & push succeeds, POST the just-pushed digest to the CP admin
endpoint POST /cp/admin/runtime-image/promote so runtime_image_pins.codex
auto-bumps with each green publish — closing the gap documented in
reference_codex_pin_no_autopromoter_exists (no on:workflow_run on Gitea
1.22.6, so promotion has to live as a terminal job in this same workflow).

Changes (53-55 LoC additive, no behavior change to existing build/push):
  - Push step gets id: push so its outputs.digest is addressable
  - publish job exposes outputs.digest = steps.push.outputs.digest
  - new promote-pin job (needs: [resolve-version, publish], if success() +
    main only) POSTs {template_name, image_digest, git_sha, notes} with
    Bearer CP_ADMIN_API_TOKEN; fail-loud on non-2xx (no silent strand).

Secrets: CP_ADMIN_API_TOKEN repo secret provisioned (matches SSOT
/shared/cp-admin-api-token). Persona widened: devops-engineer
(publish-runtime cascade owner) per feedback_no_new_identities_widen_existing
— no new identity minted.

Scope (RFC #529): Layer A only. Layer B (fleet rollout) and Layer C
(in-use safety) are explicitly out of scope for this PR.

Verified shape against handlers/pin_runtime_image.go @ molecule-controlplane
HEAD (field names: template_name / image_digest / git_sha / notes; catalog
includes claude-code, codex, hermes, openclaw, autogen).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
agent-dev-a approved these changes 2026-05-24 23:07:36 +00:00
agent-dev-a left a comment
Member

Cross-author LGTM — clean implementation.

Cross-author LGTM — clean implementation.
Some checks are pending
CI / validate (push) Blocked by required conditions
CI / validate (pull_request) Blocked by required conditions
Required
Details
CI / Adapter unit tests (push) Successful in 1m46s
CI / Template validation (static) (push) Successful in 2m11s
CI / Template validation (static) (pull_request) Successful in 31s
CI / Adapter unit tests (pull_request) Successful in 1m16s
CI / Template validation (runtime) (push) Failing after 42s
CI / T4 tier-4 conformance (live) (push) Failing after 3s
CI / Template validation (runtime) (pull_request) Failing after 41s
CI / T4 tier-4 conformance (live) (pull_request) Failing after 3s
Checking for merge conflicts…
View command line instructions

Checkout

From your project repository, check out a new branch and test the changes.
git fetch -u origin rfc-529-layer-a-auto-promote-pin:rfc-529-layer-a-auto-promote-pin
git checkout rfc-529-layer-a-auto-promote-pin
Sign in to join this conversation.
No Reviewers
2 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: molecule-ai/molecule-ai-workspace-template-codex#16