make prod: the whole Prod deploy in one command (#34) #44
No reviewers
Labels
No labels
needs-info
needs-triage
ready-for-agent
ready-for-human
wontfix
needs-info
needs-triage
ready-for-agent
ready-for-human
review/merge-ready
review/needs-fix
review/needs-human
review/needs-review
wayfinder:grilling
wayfinder:map
wayfinder:prototype
wayfinder:research
wayfinder:task
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
olympus/infra-forge!44
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "hermes/34-make-prod"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
make prodcomposes the six-step Prod deploy as one command, each step reaching its own Target's gate by re-invoking make.The layers run Guest, then Edge, then service: the runner's config polls the WAN-published URL and the role waits for the runner to appear online, which needs the Edge in place first.
The recipe is
$(MAKE) $(PROD_STEPS)(plus.NOTPARALLEL), not a flat shell recipe — so each step runs as its own Target with its own gate, environment and secret-file refusal, and the run stops at the first failing step. A flat recipe would abandon the run after its first failing line and could not carry the steps' own recipes at all.Evidence
make -n prod→make: *** No rule to make target 'prod'. Stop.After:
make -n prod→make snapshot guest edge service verify state-backup, then the six steps' composed commands in order (snapshot→guest→edge→service→verify→state-backup), the apply gate composed twice (one per OpenTofu Stack, wordprod), andedgecarrying-var-file=forgejo.tfvars.prodrecipe and stubbing the six leaves:After: prints
STEP snapshot…STEP verify, stops at the failingverify(exit 2), never reachesstate-backup— identical at-j1and-j4(.NOTPARALLEL).make fmtclean.make helpand a baremakelistprodand deploy nothing.Merge Danger
Door: two-way — the change is the Makefile and its docs;
git revertrestores the prior state, and no infrastructure is touched.Blast Radius: low — repo-root tooling and docs only; no role, provider or state change.
Code review — two axes (Standards / Spec)
Fixed point:
main(37c1835) →hermes/34-make-prod(c8134e4), 1 commit.Diff:
Makefile+22/−1,README.md+27/−19,docs/runbooks/0001-deploy-and-rollback.md+33/−0.Spec: #34.
Standards
Hard violation (documented standard)
README.mdnow links into the docs tree: "are in runbook 0001 (docs/runbooks/0001-deploy-and-rollback.md)." That contradictsdocs/index.md"Conventions for these docs": "the README does not link in here yet." Backticked rather than a markdown link, which softens it, but the pointer into docs is new and the convention forbids it. (The runbook's own new anchors —#2-the-guest--tofu,#3-the-edge--tofunpm,#4-the-service--ansible— all resolve; no breach there.)Documented vocabulary (
GLOSSARY.md;domain.md"Don't drift to synonyms the glossary explicitly avoids")Targetlists_Avoid_: recipe, rule, task. Here "recipe" is make's own term, distinct from Target, so judgement call — but it is the avoided synonym.Stack= an OpenTofu working directory; there are two. Loose drift from the defined term (judgement).Baseline smells (all judgement calls)
PROD_STEPS := …; README's six-line block; runbook's six-row table. One canonical list, referenced.Whence; archaic, doesn't reveal it holds "where the step is defined". Rename to "See"/"Defined by".prod:is effectively one line,$(MAKE) $(PROD_STEPS). The documented composition design endorses it (repo overrides the baseline), so suppress unless the runbook rationale counts as the real body.Secrets/Privacy: no plaintext secret added;
forgejo.thepit.spaceis public-by-design, allowed by AGENTS.md. No breach.Spec
(a) Missing / partial
fmt,validate,ssh, and the plan/check targets appear only in prose, not the command list.(b) Scope creep (not asked for)
.NOTPARALLEL:— new file-global behaviour; the spec never mentions parallelism. Self-justified as guarding "an inherited MAKEFLAGS", but an unrequested change to the whole file's semantics.docs/runbooks/0001-deploy-and-rollback.md(+33) — criteria only name README ("README's Running section documentsmake prod…"). Harmless, coherent, but extra.(c) Implemented but wrong
-k(keep-going), on the command line or via inheritedMAKEFLAGS..NOTPARALLEL:neutralises-jbut nothing neutralises-k: with a mirror ofprod's structure,make prod -kandMAKEFLAGS=-k make prodboth run the later step after a failure, directly contradicting the acceptance criterion — on the exact class of inherited flag the new comment worries about. A-S/MAKEFLAGS reset in the recipe would be needed.Re-verified on a mirror of the recipe: default and
-j4stop at the failing step;-kandMAKEFLAGS=-kcontinue to the next step.Summary — Standards: 1 hard violation (README links into
docs/) plus ~5 judgement calls; worst = the documented docs-convention breach. Spec: all 4 acceptance criteria met, but one is wrong under-k; worst = the stop-on-first-failure hole (verified). No single winner picked across axes.Addressed in
f883c04. Point by point:Standards
docs/. Removed. The README no longer names anydocs/path; it says only that the runbook is underdocs/. The raw commandsand the apply-gate prose stay in the runbook; the README stays thin.
Target's avoided synonym). Gone from the new Makefilecomment and the new runbook prose. (The residual uses at runbook 137/293/318
are pre-existing — the state-backup section — and out of this diff's scope;
happy to fold a sweeping rename in if wanted.)
the README and the runbook.
composition rationale are now stated once, in the Makefile comment; the runbook
keeps only what a reader running it needs (the order, and that the composition
refuses the inherited flags). The six-step list legitimately appears in three
places —
PROD_STEPSis the source, and a README block and a runbook table areeach that surface's own view — extracted into a shared file would be coupling,
not a saving.
Whence. Renamed toDefined by.Spec
-kdefeats stop-on-first-failure — the real bug. Confirmed on a mirror:inherited
MAKEFLAGS=-kranstate-backupafter the failingverify.prodnow passes
-Sto its recursive make, which clears the inherited-kexactlyas
.NOTPARALLELclears-j. Re-verified: default,-k,-k -j4, andinherited
MAKEFLAGS=-k(with and without-j4) all stop at the failing step..NOTPARALLELscope creep. Kept: it is the same guarantee as the fixabove, for the parallel flag, and the comment now states both together.
runbook is where the procedure (and the gates) live.
surface: the six steps,
guest-plan/edge-plan/service-check, andssh/fmt/validate.No change to the six-step order, the per-step gates, or the environment word.