ci: the tests gate the publish — ci.yml folds into build.yml
CI and images / lint (push) Successful in 3s
CI and images / extension-version (push) Successful in 3s
extension / lint (push) Successful in 21s
CI and images / frontend-build (push) Successful in 21s
CI and images / backend-lint-and-test (push) Successful in 31s
CI and images / integration (push) Successful in 2m10s
CI and images / sign-extension (push) Successful in 3s
CI and images / build-agent (push) Successful in 6s
CI and images / build-web (push) Successful in 1m51s
CI and images / smoke-web (push) Successful in 57s
CI and images / promote (push) Skipped
CI and images / lint (push) Successful in 3s
CI and images / extension-version (push) Successful in 3s
extension / lint (push) Successful in 21s
CI and images / frontend-build (push) Successful in 21s
CI and images / backend-lint-and-test (push) Successful in 31s
CI and images / integration (push) Successful in 2m10s
CI and images / sign-extension (push) Successful in 3s
CI and images / build-agent (push) Successful in 6s
CI and images / build-web (push) Successful in 1m51s
CI and images / smoke-web (push) Successful in 57s
CI and images / promote (push) Skipped
Operator, 2026-09-23: *"tighten the gate so :dev can't publish on red tests"*, then *"I don't want failing builds to publish anywhere going forward."* Run 7348 is the worked example. The backend unit lane went red on `2f8f0bc` and `build-web` pushed `:dev` in the same minute, because the lanes and the build were SEPARATE WORKFLOWS on the same push trigger. Neither could see the other's verdict. `:dev` was a "it built" signal, never a "it passed" one, and nothing about that was visible from either run. Two workflows cannot express the gate. A `needs:` edge only exists inside one graph. So `ci.yml`'s five lanes move into `build.yml` and `ci.yml` is deleted; `sign-extension`, `build-web` and `build-agent` now need all five. Nothing here is a new mechanism — it is the same edge that has gated `promote` since milestone 362 step 4, and it keeps that step's hardest-won property: **not running is not the same as passing.** `needs` treats a SKIPPED dependency as unsatisfied, so a lane that silently skips itself blocks the publish exactly as a failing one does. Run 5290 is why that is worth stating. Scope, said plainly rather than implied: - Gated: every image tag (`:dev`, `:latest`, `:c-<sha>`), the weekly base refresh, and the `ext-<version>` signed-XPI release asset — `sign-extension` publishes too, so it is gated with the rest. - Not gated, deliberately: `extension.yml` publishes nothing, and `release.yml` runs on a `v*` tag, generates notes rather than an artifact, and its commit already went through main's gated build. - `pull_request` (Renovate bumps into `dev`) comes across with the lanes. Its runs are the lanes and nothing else, via an `if:` on each publishing job rather than an inference from the `needs` chain. The cost, accepted knowingly: this workflow queues per branch and never cancels, so on two pushes in quick succession the second's lint feedback waits out the first's build. A slower red beats a fast red that ships. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LVjrnpQjRgHdvq95rASoiR
This commit is contained in:
+5
-4
@@ -46,8 +46,8 @@ per `docs/process.md`'s "add deps to the image when used by >1 project".
|
||||
- Integration uses Fabled-Git Actions `services:` + socket-discovered bridge IPs
|
||||
because `act_runner` (swarm-runner v0.6+) puts services on the default
|
||||
bridge with no embedded DNS. The pattern is documented in the rulebook's
|
||||
`fabled-git.md` "CI philosophy" section and FC's `ci.yml` is the canonical
|
||||
example.
|
||||
`fabled-git.md` "CI philosophy" section and FC's `build.yml` integration lane
|
||||
is the canonical example.
|
||||
- No `package-lock.json` is tracked yet (FC's `feedback_no_local_runs`
|
||||
memory bans `npm install` locally). Using `npm install` rather than
|
||||
`npm ci` until a lockfile lands.
|
||||
@@ -83,7 +83,7 @@ per `docs/process.md`'s "add deps to the image when used by >1 project".
|
||||
digit `0` or starts 1-9, and there are at most four. `2026.08.29.0201` is
|
||||
rejected; `2026.8.29.201` is the same value one character narrower per
|
||||
segment, and rule 148 defines comparison as numeric per segment, so nothing is
|
||||
reordered. `ci.yml`'s `extension-version` lane asserts the derived string
|
||||
reordered. `build.yml`'s `extension-version` lane asserts the derived string
|
||||
against that exact regex, plus a `YYYY.M.D.HHMM` shape check that would catch
|
||||
a regression to the pre-318 `1.0.<minutes>` — which AMO would accept and which
|
||||
orders below everything already signed. Checking here is the whole point: AMO
|
||||
@@ -91,7 +91,8 @@ per `docs/process.md`'s "add deps to the image when used by >1 project".
|
||||
`scripts/artifacts.sh version extension` **delegates** to `packaging.sh` so
|
||||
the two cannot answer differently.
|
||||
- Every job that derives anything checks out with `fetch-depth: 0` — all four
|
||||
`build.yml` jobs, `ci.yml`'s `extension-version` and `backend-lint-and-test`
|
||||
publishing `build.yml` jobs, its `extension-version` and `backend-lint-and-test`
|
||||
lanes
|
||||
(for `tests/test_artifact_paths.py` and `test_artifact_identity.py`), and
|
||||
`release.yml`, which additionally walks the tag graph. A depth-1 clone sees
|
||||
one commit and derives a wrong, too-low value **rather than failing**, so the
|
||||
|
||||
Reference in New Issue
Block a user