Repository navigation
feat(ship): environment-level promote with SHA-ordering release resolution - #213
Merged
Merged
Conversation
…ution
Reworks prod promotion to match reality: production = "main at SHA X", so a
prod deploy ships everything merged to main — not one release's PRs. Item 4
of the Ship-model discussion.
Phase A — env-level "Deploy to production". Extracts the workflow dispatch out
of maybeAutoDispatchProductionDeploy into a reusable dispatchEnvDeployWorkflow,
and adds Service.PromoteEnvironment + POST /api/deploy_environments/{id}/promote
(member auth + GitHub token; 400 when the env has no deploy_workflow_filename).
Per-release PromoteRelease stays as the "ship up to release X" wrapper.
Phase B — ancestry/ordering resolver (the core). When a prod deploy lands,
linkProductionDeployForRelease now resolves the deploy's project (deploy→env),
picks a cutoff (the exact-SHA anchor's merged_at when present, else the deploy's
completed/triggered time), and advances EVERY non-terminal release for the
project merged at-or-before that cutoff — via the new
ListNonTerminalReleasesForProjectMergedAtOrBefore query + the shared
Service.ResolveReleasesForProdSHA. One deploy resolves all the releases it
shipped, instead of only the exact-SHA match. Falls back to the legacy
single-release link when the project can't be resolved (no regression). Ordering
heuristic per the design call; GitHub-compare ancestry is a future refinement
for out-of-order merges. Tests: ResolvesAllReleasesMergedBefore (3 releases all
advance) + SkipsReleasesMergedAfterDeploy (later-merged stays put).
Phase C — reconcile. POST /api/deploy_environments/{id}/reconcile runs the same
resolver off the env's current_sha + current_deployed_at, healing releases
stranded by the old exact-SHA-only linkage (e.g. verified-but-still-in-staging).
Phase D — UI. "Deploy to production" button on the Production env card with a
confirm dialog ("ships everything on main, not one release"),
usePromoteDeployEnvironment mutation + promoteDeployEnvironment API method +
schema, new i18n (en + zh-Hans).
go build + vet + sqlc current; new resolver tests + full Go suite pass;
core + views typecheck; 204 ship + 8 schema tests green.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Item 4 of the Ship-model discussion. Production = "main at SHA X", so a prod deploy ships everything merged — not one release's PRs. This makes the model honest.
Phases
dispatchEnvDeployWorkflowextracted from the per-release auto-dispatch) +PromoteEnvironment+POST /deploy_environments/{id}/promote(member auth + GitHub token; 400 if no deploy workflow configured). Per-releasePromoteReleasestays as the "ship up to release X" wrapper.merged_at, else deploy time), and advance every non-terminal release merged at-or-before it (ListNonTerminalReleasesForProjectMergedAtOrBefore→ResolveReleasesForProdSHA). One deploy resolves all the releases it shipped. Falls back to the legacy single-release link when the project can't be resolved. SHA-ordering heuristic (your pick); GitHub-compare is a noted future refinement.POST /deploy_environments/{id}/reconcileruns the same resolver off the env'scurrent_sha/current_deployed_at— heals releases stranded by the old exact-SHA linkage (e.g. your verified-but-"in-staging" ones).Test plan
go build/vet/sqlcclean; 2 new resolver tests (ResolvesAllReleasesMergedBefore,SkipsReleasesMergedAfterDeploy) + full Go suite pass; core+views typecheck; 204 ship + 8 schema tests green. Resolver reviewed by hand (cutoff + boundary correctness).deploy-prod.yml; on land, all in-staging releases ≤ the deploy advance to in_production/done; "reconcile" heals the currently-stuck releases.🤖 Generated with Claude Code