ci(cd-infra): exclude brouter-host so a docs edit stops deploying the flagship #31
No reviewers
Labels
No labels
dependencies
major
security-pin
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
trails-cool/trails!31
Loading…
Reference in a new issue
No description provided.
Delete branch "ci/cd-infra-exclude-brouter-host"
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?
infrastructure/brouter-host/**belongs tocd-brouter, butcd-infra's filter was a bareinfrastructure/**— so anything under that directory fired both workflows. On 2026-07-27 a README-only edit redeployed BRouter on the dedicated host and ran a full infra deploy on the flagship (SIGHUP prometheus, restart loki/promtail, reload caddy) for no reason.CLAUDE.md has documented this exclusion since the workflow was written — "
infrastructure/(exceptbrouter-host/**)". It never existed. This makes the docs true rather than rewording them to match a weaker reality.Why the implementation was worth reading first
pathsandpaths-ignorecan't be combined for one event, so this needs a negative pattern insidepaths. Forgejo's docs mention neither negation norpaths-ignore, so I checked the v16.0.1 source instead of guessing — and the failure mode justifies it:A malformed pattern doesn't fail loudly. It
breaks out without matching, which would silently stop infra deploys altogether. Exactly the class of bug this repo has been chasing all week.What the code actually does:
CompilePatternstrips a leading!and setsNegative: true— so it cannot error on this inputSkipevaluates the sequence per changed file with later matches winning, so the negative pattern must come after the positive one (it does)Verified semantics
Reimplemented the compiled matcher and ran the real pattern list over six scenarios:
infrastructure/brouter-host/README.mdinfrastructure/brouter-host/poi-extract/poi-extract.shinfrastructure/docker-compose.ymlinfrastructure/Caddyfile+brouter-host/x.mdinfrastructure/scripts/poi-import.shapps/journal/app/root.tsxThe mixed case is the one that matters: a commit touching brouter-host and real infrastructure still deploys, because the non-excluded file stays matched. A naive
paths-ignorewould have got that wrong.Verifying after merge
This PR's own CI can't test the trigger — it's a
push-to-mainfilter. The real confirmation is the next brouter-host-only change:cd-broutershould run andcd-infrashould not. Worth watching for, since a mistake here is silent in the direction of "infra never deploys".`infrastructure/brouter-host/**` belongs to cd-brouter, but cd-infra's filter was a bare `infrastructure/**`, so anything under it fired BOTH workflows. On 2026-07-27 a README-only change to that directory redeployed BRouter on the dedicated host *and* ran a full infra deploy on the flagship — SIGHUP prometheus, restart loki/promtail, reload caddy — for no reason. CLAUDE.md has documented this exclusion since the workflow was written ("`infrastructure/` (except `brouter-host/**`)"). It never existed. This makes the docs true rather than rewording them. `paths` and `paths-ignore` cannot be combined for one event, so this uses a negative pattern inside `paths`. That is not syntax worth guessing at here: Forgejo compiles these with act's `workflowpattern` and, per v16.0.1 `modules/actions/workflows.go`, a compile error `break`s out without incrementing matchTimes — i.e. a malformed pattern would silently stop infra deploys altogether rather than failing loudly. Verified against the actual implementation rather than the docs, which mention neither negation nor paths-ignore: - `CompilePattern` strips a leading `!` and sets Negative, so it cannot error on this input - `Skip` evaluates the sequence per changed file with later matches winning, so the negative pattern must follow the positive one (it does) Simulated the compiled semantics over six scenarios; the notable one is that a commit touching brouter-host *and* other infrastructure still deploys, because the non-excluded file stays matched: infrastructure/brouter-host/README.md -> no run infrastructure/brouter-host/poi-extract/poi-extract.sh -> no run infrastructure/docker-compose.yml -> run infrastructure/Caddyfile + brouter-host/x.md -> run (mixed) infrastructure/scripts/poi-import.sh -> run apps/journal/app/root.tsx -> no run Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01X8hNxgYp777FRqYtVmQNaU