CI / lint (push) Successful in 3s
Build images / sign-extension (push) Successful in 4s
CI / extension-version (push) Successful in 3s
Build images / build-agent (push) Successful in 8s
CI / frontend-build (push) Successful in 22s
extension / lint (push) Successful in 25s
CI / backend-lint-and-test (push) Successful in 29s
Build images / build-web (push) Successful in 1m57s
Build images / build-ml (push) Successful in 2m38s
CI / integration (push) Successful in 3m50s
The guard asked whether a packaged extension file changed without the version moving. Since step 4 nobody moves the version by hand, so it was checking a fact that had stopped existing — and it was not merely dead weight: it would have failed the lane on every real extension change, demanding a bump that decides nothing. Removed rather than left running beside the new mechanism (rule 22). What replaces it is thinner and true. The extension-version lane now asserts the derivation resolves on this commit, that the derived value is the plain dotted-numeric shape AMO accepts, and that MAJOR.MINOR agrees between manifest.json and package.json. MAJOR.MINOR is the one part still hand-set, and packaging.sh reads it from manifest.json ALONE, so a divergence ships a version package.json disagrees with. The lane keeps fetch-depth: 0 — checking that the derivation survives a real checkout is half its remaining value. Deliberately not checked there: that the derived value beats what is already signed. That guard belongs in build.yml, where it compares against the real ext-* releases. Comparing against origin/main in a lane would be wrong, because dev legitimately derives a LOWER value whenever main is ahead on the extension, and a lane that fails for being behind is a lane people learn to ignore. packaging.sh is down to two consumers from three. version.spec.js's "ci.yml derives its pathspec" test would have gone red on that, so it is rewritten to assert the property rather than the consumer: no workflow inlines an :(exclude)extension/ literal, across all three. That keeps the #2397 anti-regression value while surviving consumers coming and going. A second test pins build.yml to packaging.sh version and fails if it goes back to grepping the committed value — which is not a style regression but the #3092 bug itself. build.yml joins extension.yml's trigger paths, since the suite now asserts against it. The lockstep test narrows from the whole version string to MAJOR.MINOR. The committed patch numbers are inert now; asserting on them would fail for a difference that changes nothing. Docs. extension/README.md's Release section described extension.yml signing on main and committing the XPI into frontend/public/ — untrue since 2026-05-25, and it told the reader to hand-bump both files, which is now exactly the wrong instruction. Rewritten, with a Versioning section that says plainly that editing the patch number does nothing and why the key is commit time rather than a count. ci-requirements.md drops the third packaging.sh consumer and names every job that needs full history. Root README no longer claims the extension is signed on main only.
88 lines
3.8 KiB
YAML
88 lines
3.8 KiB
YAML
name: extension
|
|
# Lint + unit tests. The sign-and-publish dance moved into build.yml's
|
|
# `sign-extension` job (2026-05-25) — `:latest` now always bundles the XPI
|
|
# because sign-extension runs as a build-web dependency in the SAME workflow,
|
|
# eliminating the prior race between build.yml and a separate extension.yml.
|
|
# Signed XPIs are cached in Forgejo Release Assets named `ext-<version>`.
|
|
on:
|
|
push:
|
|
branches: [dev, main]
|
|
paths:
|
|
- 'extension/**'
|
|
- '.forgejo/workflows/extension.yml'
|
|
# test/version.spec.js asserts things ABOUT the other two workflows —
|
|
# that neither inlines the packaged-file set, and that build.yml derives
|
|
# the shipped version rather than reading it out of the repo. A
|
|
# workflow-only edit can therefore break this suite, so it has to trigger
|
|
# it. build.yml joined the list at milestone 271 step 5, when the spec
|
|
# started asserting against it.
|
|
- '.forgejo/workflows/ci.yml'
|
|
- '.forgejo/workflows/build.yml'
|
|
pull_request:
|
|
branches: [main]
|
|
paths:
|
|
- 'extension/**'
|
|
- '.forgejo/workflows/ci.yml'
|
|
- '.forgejo/workflows/build.yml'
|
|
workflow_dispatch:
|
|
|
|
jobs:
|
|
lint:
|
|
runs-on: python-ci
|
|
container:
|
|
image: node:24-bookworm-slim
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
# Not --no-save: vitest and web-ext are both real devDependencies now,
|
|
# and the suite needs vitest resolvable from node_modules.
|
|
- name: Install dev dependencies
|
|
run: cd extension && npm install --no-audit --no-fund
|
|
- name: Lint
|
|
run: cd extension && npm run lint
|
|
# Pure-logic specs over lib/url.js and lib/platforms.js plus manifest /
|
|
# package version-consistency checks. No browser, no network.
|
|
- name: Unit tests
|
|
run: cd extension && npm run test:unit
|
|
|
|
# Everything else about packaging is asserted against our own declaration
|
|
# of what ships. This is the only check that asks web-ext what it ACTUALLY
|
|
# put in the archive. Until now that was an unverified assumption about
|
|
# glob semantics — and a fragile one: `test/**` reaches web-ext intact
|
|
# only because callers `set -f` first, so losing that quoting would
|
|
# silently start shipping dev files with no other signal.
|
|
- name: Verify XPI contents
|
|
run: |
|
|
set -eu
|
|
command -v unzip >/dev/null 2>&1 || { apt-get update -qq && apt-get install -y -qq unzip; }
|
|
cd extension
|
|
npm run build
|
|
ZIP=$(ls web-ext-artifacts/*.zip | head -1)
|
|
echo "=== packaged entries in $ZIP ==="
|
|
unzip -Z1 "$ZIP" | sort
|
|
echo "=== end ==="
|
|
ENTRIES=$(unzip -Z1 "$ZIP")
|
|
fail=0
|
|
# Must NOT ship: repo infrastructure with no business in a user's browser.
|
|
for pat in 'test/' 'scripts/' 'vitest.config.js' 'package.json' 'package-lock.json' 'README.md' 'node_modules/' 'web-ext-artifacts/'; do
|
|
if echo "$ENTRIES" | grep -q "^$pat"; then
|
|
echo "ERROR: '$pat' was packaged into the XPI but must not be"
|
|
fail=1
|
|
fi
|
|
done
|
|
# Must ship: if an exclusion pattern ever over-matches, the extension
|
|
# breaks at runtime rather than at build time, so assert presence too.
|
|
for req in 'manifest.json' 'lib/url.js' 'lib/api.js' 'lib/platforms.js' 'lib/cookies.js'; do
|
|
if ! echo "$ENTRIES" | grep -q "^$req$"; then
|
|
echo "ERROR: '$req' is missing from the XPI"
|
|
fail=1
|
|
fi
|
|
done
|
|
for dir in 'background/' 'popup/' 'options/' 'content/' 'icons/'; do
|
|
if ! echo "$ENTRIES" | grep -q "^$dir"; then
|
|
echo "ERROR: nothing from '$dir' was packaged"
|
|
fail=1
|
|
fi
|
|
done
|
|
[ "$fail" -eq 0 ] || exit 1
|
|
echo "XPI contents verified."
|