feat: the extension adds Discord channels to an artist you pick, and its tests gate the XPI (milestone 429)
CI and images / lint (push) Successful in 2s
CI and images / extension-version (push) Successful in 2s
CI and images / extension-test (push) Successful in 20s
CI and images / frontend-build (push) Successful in 24s
CI and images / backend-lint-and-test (push) Successful in 32s
CI and images / integration (push) Successful in 2m22s
CI and images / build-agent (push) Successful in 5s
CI and images / sign-extension (push) Successful in 3m13s
CI and images / build-web (push) Successful in 1m42s
CI and images / smoke-web (push) Successful in 54s
CI and images / promote (push) Successful in 1s
CI and images / lint (push) Successful in 2s
CI and images / extension-version (push) Successful in 2s
CI and images / extension-test (push) Successful in 20s
CI and images / frontend-build (push) Successful in 24s
CI and images / backend-lint-and-test (push) Successful in 32s
CI and images / integration (push) Successful in 2m22s
CI and images / build-agent (push) Successful in 5s
CI and images / sign-extension (push) Successful in 3m13s
CI and images / build-web (push) Successful in 1m42s
CI and images / smoke-web (push) Successful in 54s
CI and images / promote (push) Successful in 1s
Server (#4420) - extension_service gains a Discord pattern (server or channel, jump links, ptb/canary; not DMs or threads), mirrored in platforms.js and pinned by the shared artist-url-samples.json. - probe on a Discord URL matches the source by ids under any artist, reports a whole-server source as covering the channel, suggests the artist who owns another source on the same server, and names server/channel via the stored token (best-effort, bounded, no rate-limit waits). - quick-add takes artist_id / artist_name; Discord URLs are stored canonical. Extension (#4421, #4422) - Content script on discord.com; SPA navigation by URL polling (the old pushState patch ran in the isolated world and never fired); stale probes are dropped. - Discord chip opens an Add panel: this channel or the whole server, and the suggested artist / a search / a new name. - Popup: sources show artist, platform and state; a Discord token export is verified by FC and the result shown. Token capture covers ptb/canary. - Pure logic in lib/chip.js and lib/popup-format.js, with specs. CI (#4423) - extension.yml's lane (web-ext lint, vitest, XPI contents) moves into build.yml as extension-test and joins the needs of sign-extension, build-web and build-agent. As a separate workflow it gated nothing: a red extension suite still signed and shipped the XPI (rule 177). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LVjrnpQjRgHdvq95rASoiR
This commit is contained in:
@@ -242,7 +242,7 @@ jobs:
|
||||
# rather than left running beside the new mechanism (rule 22).
|
||||
#
|
||||
# Two things are still worth asserting, and this is the only lane that can:
|
||||
# the extension.yml suite runs on node:24-slim, which is exactly why
|
||||
# the extension-test lane runs on node:24-slim, which is exactly why
|
||||
# version.spec.js sticks to packaging.sh's git-free subcommands.
|
||||
# 1. the derivation actually resolves on this commit
|
||||
# 2. the derived string is one AMO will accept, checked against Mozilla's
|
||||
@@ -378,6 +378,76 @@ jobs:
|
||||
- run: npm run test:unit
|
||||
- run: npm run build
|
||||
|
||||
# The extension's lane: web-ext lint, the vitest suite, and the check that
|
||||
# asks web-ext what it ACTUALLY packaged. Moved in from `extension.yml`
|
||||
# (deleted) at milestone 429 — the same move `ci.yml` made on 2026-09-23 and
|
||||
# for the same reason: a separate workflow cannot gate this one, so a red
|
||||
# extension suite still let `sign-extension` sign and `build-web` ship the
|
||||
# XPI. It is a lane in THE GATE now. Its old path filter is gone with it; a
|
||||
# filter here would make the lane skip, and a skipped lane blocks the publish.
|
||||
#
|
||||
# The vitest suite is also the JS half of the #3093 artist-pattern mirror —
|
||||
# the Python half runs in backend-lint-and-test — so until this move one half
|
||||
# of that guard could fail without stopping anything.
|
||||
extension-test:
|
||||
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' 'lib/chip.js' 'lib/popup-format.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."
|
||||
|
||||
# Single integration job — collapsed from a 3-way shard split on 2026-06-04.
|
||||
# The shards existed to parallelize ~8.5min of integration tests; once the
|
||||
# throwaway Postgres runs with fsync OFF (the durability step below) the whole
|
||||
@@ -521,7 +591,8 @@ jobs:
|
||||
# itself through a job-level `if:` that could not read `env`, and a design
|
||||
# where only a FAILED gate blocks would have published unverified images
|
||||
# while reporting success.
|
||||
needs: [lint, extension-version, backend-lint-and-test, frontend-build, integration]
|
||||
needs: [lint, extension-version, backend-lint-and-test, frontend-build, extension-test,
|
||||
integration]
|
||||
# A pull_request run is the lanes and nothing else. This is the ONLY thing
|
||||
# separating "validate a Renovate bump" from "publish a Renovate bump", so
|
||||
# it is stated on each publishing job rather than inferred from a `needs`
|
||||
@@ -859,7 +930,7 @@ jobs:
|
||||
# default behaviour is exactly what we want: a failed sign skips build-web
|
||||
# rather than shipping an image without its XPI.
|
||||
needs: [sign-extension, lint, extension-version, backend-lint-and-test,
|
||||
frontend-build, integration]
|
||||
frontend-build, extension-test, integration]
|
||||
# The lanes in that list are THE GATE (2026-09-23) — see sign-extension's
|
||||
# copy of this comment for why, including the property that a SKIPPED lane
|
||||
# blocks as firmly as a failing one. They are repeated here rather than
|
||||
@@ -2083,7 +2154,8 @@ jobs:
|
||||
# itself through a job-level `if:` that could not read `env`, and a design
|
||||
# where only a FAILED gate blocks would have published unverified images
|
||||
# while reporting success.
|
||||
needs: [lint, extension-version, backend-lint-and-test, frontend-build, integration]
|
||||
needs: [lint, extension-version, backend-lint-and-test, frontend-build, extension-test,
|
||||
integration]
|
||||
# What `promote` needs to publish this image once the smoke has passed:
|
||||
# the manifest this run built (empty on a reuse hit) and every tag it
|
||||
# belongs under. Same meaning as build-web's outputs of the same names.
|
||||
|
||||
Reference in New Issue
Block a user