diff --git a/.github/workflows/publish-workspace-server-image.yml b/.github/workflows/publish-workspace-server-image.yml index df0c3098..c7f3127f 100644 --- a/.github/workflows/publish-workspace-server-image.yml +++ b/.github/workflows/publish-workspace-server-image.yml @@ -73,7 +73,20 @@ jobs: # - canary-verify.yml runs smoke tests against them # - On green → canary-verify retags :staging- → :latest # - On red → :latest stays on the prior good digest, prod is safe - - name: Build & push platform image to GHCR (staging- only) + # Every push of :staging- also retags the same digest as + # :staging-latest so staging CP (which pins TENANT_IMAGE at + # :staging-latest) picks up new builds automatically — no more manual + # Railway env-var edits. Prod's :latest retag still happens in + # canary-verify.yml after the canary fleet greenlights this digest; + # :staging-latest is strictly the "most recent main build," not a + # canary-verified promotion. + # + # Before this, TENANT_IMAGE on Railway staging was pinned to a static + # :staging- and drifted months behind (2026-04-24 incident: + # canary tenant ran :staging-a14cf86, 10 days stale, which lacked + # applyRuntimeModelEnv and caused every E2E to route hermes+openai + # through openrouter → 401). See issue filed with this PR. + - name: Build & push platform image to GHCR (staging- + staging-latest) uses: docker/build-push-action@v6 with: context: . @@ -82,6 +95,7 @@ jobs: push: true tags: | ${{ env.IMAGE_NAME }}:staging-${{ steps.tags.outputs.sha }} + ${{ env.IMAGE_NAME }}:staging-latest cache-from: type=gha cache-to: type=gha,mode=max labels: | @@ -89,7 +103,7 @@ jobs: org.opencontainers.image.revision=${{ github.sha }} org.opencontainers.image.description=Molecule AI platform (Go API server) — pending canary verify - - name: Build & push tenant image to GHCR (staging- only) + - name: Build & push tenant image to GHCR (staging- + staging-latest) uses: docker/build-push-action@v6 with: context: . @@ -98,6 +112,7 @@ jobs: push: true tags: | ${{ env.TENANT_IMAGE_NAME }}:staging-${{ steps.tags.outputs.sha }} + ${{ env.TENANT_IMAGE_NAME }}:staging-latest cache-from: type=gha cache-to: type=gha,mode=max # Canvas uses same-origin fetches. The tenant Go platform