Automated store submission
August 13, 2026 · View on GitHub
Firefox (AMO) is automated; Chrome is a dashboard job by choice. The CWS API's only auth path is a Google Cloud OAuth app consented by the developer account, which we deliberately do not maintain. The scripts support Chrome regardless, so wiring it later is only the credential mint away. Every route is a manual trigger, because a store submission is a deliberate act; review queues at both stores still apply.
Primary — Actions: Actions → Store submit → Run workflow → enter the
release tag (Firefox on, Chrome off by default). The repo is public, so
hosted minutes are free. Needs the AMO values below as repo secrets
(gh secret set NAME --repo forgesworn/bark).
Fallback — local, from any machine with git, gh and Node:
npm run store:submit -- v1.3.7 --no-chrome # AMO, as the workflow does
npm run store:submit -- v1.3.7 # both stores (needs CWS creds)
npm run store:submit -- v1.3.7 --no-publish # CWS: upload without submitting
Chrome, per release: dashboard → the bark item → Package → upload
bark-vX.Y.Z.zip from the GitHub release → Submit for review, pasting
anything the listing needs from docs/store-listing.md.
The automated route downloads the release's own CI-built zips, cuts the AMO source zip and the release-notes changelog from the tag (so a moved-on working tree cannot leak into the submission), then submits package + source
- changelog-derived release notes to AMO. The AMO step fails loudly if the version has no changelog section.
Neither store API can create a listing — only update one — so the very first submission of a new extension is always a dashboard job. Bark's listings already exist on both stores.
Credentials
Six values, minted once (below). For Actions, store each as a repo secret;
for the local route, the scripts read the environment first, then
~/ops/bark-store.env (override the path with BARK_STORE_ENV). Keep that
file outside the repo, chmod 600, plain KEY=VALUE lines:
CWS_EXTENSION_ID=...
CWS_CLIENT_ID=...
CWS_CLIENT_SECRET=...
CWS_REFRESH_TOKEN=...
AMO_JWT_ISSUER=user:12345:67
AMO_JWT_SECRET=...
One-time: Chrome Web Store (a human job, ~15 minutes)
The CWS API acts as the developer account behind an OAuth refresh token; service accounts are not supported.
-
In console.cloud.google.com, signed in as the developer account: create a project (any name), then Enabled APIs & services → Enable → "Chrome Web Store API".
-
OAuth consent screen: External, fill the two required fields, and — this matters — set Publishing status to "In production". In "Testing" status Google expires every refresh token after seven days.
-
Credentials → Create credentials → OAuth client ID → Desktop app. Note the client ID and secret.
-
Mint the refresh token on any machine with a browser logged into the developer account:
node scripts/cws-mint-token.mjs <client_id> <client_secret> -
The extension ID is in the dashboard item URL (
chrome.google.com/webstore/devconsole/…/<ID>/…).
One-time: AMO (~2 minutes)
addons.mozilla.org/developers/addon/api/key/
→ generate new credentials; the issuer looks like user:12345:67.
The add-on is addressed by its gecko ID (bark@forgesworn.local, set in
esbuild.config.js); override with AMO_ADDON_ID if that ever changes.
Per release
Full step-by-step, including the version bump, is in releasing.md. The submission half is:
- Tag pushed and the release workflow green.
- Publish the draft release.
release.ymlsetsdraft: true, so the tag build lands as a draft and nothing consumes a draft — submitting before this fails withrelease not found(see below). Eithergh release edit vX.Y.Z --draft=falseor the Releases page. - Actions → Store submit → run with the tag — or locally,
npm run store:submit -- vX.Y.Z. - AMO release notes come from the version's changelog section automatically.
CWS has no per-version notes; keep the long description in
docs/store-listing.mdcurrent instead.
Failure notes
download release assets failedwithrelease not foundmeans the GitHub release is still a draft, not that the tag or credentials are wrong. Publish it (step 2 above) and re-run; nothing needs rebuilding.- CWS
publishreturns the review state, not instant publication; ITEM_PENDING_REVIEW is success. - AMO validation is polled for up to 2½ minutes; a validation failure prints the validator output and stops before any version is created.
- A CWS 401 usually means the refresh token died — re-run the mint script and update the env file; check the consent screen is still "In production".