Skip to content

ci: enable wxt-based store submissions from GitHub Actions#342

Merged
vict0rsch merged 18 commits intorefactor-es-modulesfrom
build-wtx-submit
Apr 20, 2026
Merged

ci: enable wxt-based store submissions from GitHub Actions#342
vict0rsch merged 18 commits intorefactor-es-modulesfrom
build-wtx-submit

Conversation

@vict0rsch
Copy link
Copy Markdown
Owner

TL;DR

Overhaul the GitHub Actions setup so the extension can be submitted to the Chrome Web Store and Firefox Add-ons from CI. Extracts reusable _build.yml and _test-matrix.yml workflows, adds npm run submit* scripts backed by wxt submit, bumps wxt to 0.20.25, reads the manifest version from package.json, and tightens workflow security (scoped secrets, SHA-pinned third-party action, least-privilege GITHUB_TOKEN, excludeSources hardening).

Breaking changes

None for end users. Internally:

  • 🟡 secrets: inherit on reusable workflow calls is replaced with explicit pass-through. Any future reusable workflow added here will need to declare the secrets it needs in workflow_call.secrets.
  • 🟡 submit.yml no longer gates on a separate _build.yml job — it gates on test-matrix only and does its own npm run zip. The build gate was redundant with the submit job's own build step.

Changes

  • Submit-to-stores workflow (submit.yml, new _build.yml, new _test-matrix.yml): Manual-dispatch workflow with target (both/chrome/firefox) and dry_run (default true) inputs. Uses npx wxt submit with store credentials scoped per step.
  • npm submit scripts (package.json): Add submit, submit:chrome, submit:firefox and their :dry-run variants. Globs are quoted so wxt (not the shell) expands them.
  • Manifest version sourcing (wxt.config.js): Read the manifest version from package.json so there is a single source of truth.
  • wxt bump: ^0.20.20^0.20.25.
  • Firefox sources zip (wxt.config.js): Add excludeSources so extra/, docs/, test/, scripts/, CNAME, mkdocs.yml, and (defense-in-depth) any .env*, keys.json, credentials*, *.pem, *.key never end up in the AMO sources zip.
  • Security hardening (workflows):
    • secrets: inherit → explicit VICT0RSCH_GITHUB_PAT: ${{ secrets.VICT0RSCH_GITHUB_PAT }}.
    • nick-fields/retry pinned to SHA (ce71cc2…, v3.0.2).
    • The PAT is passed via the step's env: instead of interpolated into the shell command string.
    • Explicit permissions: contents: read on every workflow file.
  • Meta test (test/test-meta.js): Parse both test.yml and _test-matrix.yml now that the matrix lives in the reusable workflow.
  • Docs (contributing.md): New section documenting each workflow, how to dispatch a submission, and the required secrets.
  • Source review (SOURCE_CODE_REVIEW.md, new): Reproducible build instructions for Mozilla reviewers.
  • .gitignore: Ignore .env (bare) and .env* variants.

Review hints

  • .github/workflows/submit.yml is the one file worth reading top to bottom. Credential scoping per store-submit step, explicit secrets pass-through to _test-matrix.yml, workflow-level contents: read, static concurrency.group, dry-run by default.
  • wxt.config.js:96gecko.id is papermemory@vict0rsch (must match what AMO already has on file for the live listing; any other value either gets rejected or creates a new listing).
  • test/test-meta.js now reads both workflow files; the error message was updated accordingly.
  • Not affected: no JS source code under src/ or entrypoints/ is changed. This PR is CI, build config, docs, and the meta test only.
  • Needs a secret named VICT0RSCH_GITHUB_PAT in repo Actions secrets for the test matrix to pass (same as before).
  • Store credentials (CHROME_*, FIREFOX_*) need to be configured before the first real (non-dry-run) submission. Default dry_run: true is the intended first-use path.

Add submit, submit:dry-run, and per-browser variants (submit:chrome,
submit:firefox, and their :dry-run counterparts) so credentials and
individual store uploads can be exercised locally without going through
CI.

Made-with: Cursor
The manifest version was previously hardcoded in wxt.config.js, so
bumping a release meant updating two files in lockstep. Read it from
package.json via createRequire instead — package.json is now the single
source of truth for the extension version.

Made-with: Cursor
Move the body of build.yml and test.yml's test-matrix job into
workflow_call-only files (_build.yml, _test-matrix.yml) so the submit
workflow can reuse them as gating jobs without duplicating configuration.
build.yml and test.yml now just delegate to the reusable workflows;
behavior is unchanged for push and pull_request events.

The leading underscore in the filenames signals "not a top-level
workflow" — they only run via workflow_call.

Made-with: Cursor
Rewrite submit.yml around wxt submit with safer defaults:

- Manual dispatch only (no auto-submission on release) so publishing to
  the stores is always a deliberate act.
- New target input (both / chrome / firefox) and dry_run input
  (default true) so credentials can be validated without uploading and
  partial failures can be retried for a single store.
- Gate submission on the reusable _test-matrix.yml and _build.yml
  workflows so store submissions can't ship a broken build.
- Split Chrome and Firefox into separate steps, each scoped to only
  its own secrets.
- Use npm ci (not npm install) and enable npm cache for deterministic,
  fast builds.
- Quote zip globs so wxt does the expansion, not the shell.
- Add a submit-stores concurrency group to queue overlapping dispatches.

Made-with: Cursor
Add a Github Workflows section after Tests describing the four workflow
files, the submit.yml dispatch inputs (target, dry_run), required
secrets grouped per store, local npm script equivalents, and the
concurrency guard.

Made-with: Cursor
The gecko.id must match what AMO has on file for the existing
paper-memory listing (version 1.0.3). The previous change to
"paper-memory" is not a valid Mozilla extension id (must be either
email-style or a UUID in braces) and would have been rejected by
AMO, or orphaned existing users if it had gone through.

Made-with: Cursor
The test-matrix job's strategy.matrix.include moved from test.yml into
the reusable _test-matrix.yml. Parse both workflow files so the meta
test keeps catching test-*.js files that are not wired into CI.

Made-with: Cursor
The submit job already runs `npm ci && npm run zip`, which covers
everything the separate _build.yml job did. Keeping it as a needs:
gate only duplicated work and created the false invariant that the
validated zip was the submitted one (it wasn't \u2014 submit rebuilt
from scratch). The real gate is test-matrix.

Made-with: Cursor
Without quotes, the shell expands `dist/*-chrome.zip` before wxt sees
it. If dist/ contains multiple versioned zips (likely after repeated
local runs), a single --chrome-zip flag would receive multiple paths
and wxt would misparse or pick the wrong version. Matches the quoting
already used in submit.yml.

Made-with: Cursor
Replace `secrets: inherit` with an explicit pass-through of only the
secret `_test-matrix.yml` declares as required. Also move the
github_pat interpolation out of the `command:` string into the
step's `env:` block, which avoids interpolating secrets directly
into shell strings.

Made-with: Cursor
This action receives VICT0RSCH_GITHUB_PAT via env, so pinning to a
mutable major tag (v3) is a supply-chain risk. Pin to the immutable
commit SHA for v3.0.2 with a trailing tag comment for future
upgrades.

Made-with: Cursor
Default GITHUB_TOKEN permissions depend on repo settings and can
include write access. Declare `contents: read` at the top of every
workflow file so the token is guaranteed read-only regardless of
repo defaults.

Made-with: Cursor
- Add bare `.env` to .gitignore (`.env.*` glob requires at least
  one char after the dot, so a plain `.env` would NOT be matched).
- Add defensive excludes for `.env*`, `keys.json`, `credentials*`,
  `*.pem`, `*.key` to wxt's excludeSources so any stray secret file
  in the workspace is kept out of the Firefox sources zip uploaded
  to AMO.

Made-with: Cursor
- Correct workflow file count (four \u2192 five) in the workflow table.
- Clarify that submit.yml gates on test-matrix only (build gate was
  dropped as redundant with the submit job's own zip step).
- Fix wording about which ref the submit workflow uses.
- Update a matrix entry label now that the matrix definition lives
  in _test-matrix.yml, not test.yml.

Made-with: Cursor
@vict0rsch vict0rsch merged commit 47fe49e into refactor-es-modules Apr 20, 2026
8 of 11 checks passed
@vict0rsch vict0rsch deleted the build-wtx-submit branch April 20, 2026 12:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant