Files
AutistMask/docs/RELEASE.md
clawbot a1f082d686
check / check (push) Failing after 1s
e2e / e2e-chrome (push) Failing after 1s
e2e / e2e-firefox (push) Failing after 1s
docs: a release procedure from a green main to tagged, packaged artifacts (closes #387)
Add docs/RELEASE.md, linked from README.md's Release Artifacts section, giving
the release procedure as a numbered list: confirm main is green in CI, confirm
the one version in package.json and the two manifests matches the intended tag,
make package from a clean checkout, verify SHA256SUMS, create the annotated tag
vX.Y.Z, then distribute per browser. Each step names who performs it, marks the
owner-only ones, and states the check that it worked. Every repo command cited
(make setup, make check, make package) exists on next; tagging and verification
use standard git and coreutils, and the CRX pack line is README's own.

The per-browser distribution step is written as pending the owner's choice on
issue 386, with the Firefox and Chrome options named but none presented as
settled. Docs only: no code or test changes.

Model: opus-4-8
2026-09-21 22:00:18 +02:00

5.4 KiB

Releasing AutistMask

This is the procedure that turns a green main into a tagged, packaged release. It gathers into one place what is otherwise spread across the Makefile and three README.md sections, so the person cutting a release does not have to reconstruct the order from them.

There is one version, declared in three files (package.json, manifest/chrome.json, manifest/firefox.json), and make package builds and packages but publishes nothing. make build and make package can be run by anyone; tagging, signing, packing a CRX and any upload need credentials only the owner (@sneak) holds and are marked owner-only below. Releases are tagged from main (see the Workflow section of TODO.md), so the "release commit" throughout is the main commit the milestone PR merged.

Procedure

  1. Confirm main is green in CI. The check workflow (.gitea/workflows/check.yml) runs script/cibuild, i.e. docker build ., and the Dockerfile runs make check as a build step, so a green check run is a green make check. Find the run for the exact release commit on the tracker's Actions view. Check: that commit's check run succeeded; running make check on a clean checkout of the commit reproduces it and exits 0.

  2. Confirm the version matches the intended tag. package.json, manifest/chrome.json and manifest/firefox.json must all declare the same X.Y.Z. make build fails when they disagree, but nothing checks that they equal the tag you mean to create — that is this manual step. Check: all three files read the same X.Y.Z, and it is the version you intend to tag vX.Y.Z.

  3. Build and package from a clean checkout of that commit. From a fresh clone, or a working tree with no local modifications (git status clean), checked out at the release commit: run make setup, then make package. make package runs make build first, so the archives can only be made from a dist/ verified against that build's own receipt as a release (not debug) build. It writes three files into release/: autistmask-chrome-<version>.zip, autistmask-firefox-<version>.xpi, and SHA256SUMS. Check: those three files exist and <version> in the archive names is the version confirmed in step 2. The Firefox .xpi is unsigned (see step 6 and "Installing on Firefox" in README.md).

  4. Verify SHA256SUMS. The archives are deterministic — sorted entries, fixed timestamps, fixed compression — so a second make package from another clean checkout of the same commit produces byte-identical files. Verify the recorded digests against the files with sha256sum -c SHA256SUMS, run from release/. To confirm reproducibility, run make package again on a separate clean checkout and compare the digests. Check: sha256sum -c reports OK for every file, and an independent build's digests match.

  5. Tag the release commit. (owner-only) Create an annotated tag vX.Y.Z on the release commit and push it: git tag -a vX.Y.Z (with a message), then git push origin vX.Y.Z. Check: git tag lists vX.Y.Z, and git rev-parse vX.Y.Z^{commit} resolves to the release commit.

  6. Distribute per browser. (owner-only; pending the owner's choice on #386) How 1.0.0 is distributed on each browser is not yet decided; it is the open question on that issue, and the concrete steps cannot be written until the owner records a choice there. These steps need credentials only the owner holds. The options under consideration are:

    • Firefox — the packaged .xpi is unsigned, and release Firefox and ESR refuse an unsigned add-on:
      • (a) AMO self-distribution signing (unlisted): submit the .xpi to AMO with the owner's credentials; AMO returns a signed .xpi installable on every Firefox, with nothing listed publicly.
      • (b) AMO listed: as (a), plus a public AMO listing and review.
      • (c) Ship the unsigned .xpi and state that Firefox support means Developer Edition, Nightly, or an Unbranded build with xpinstall.signatures.required set to false.
    • Chrome — the repo packs no CRX and publishes nothing; the extension id is fixed by the key in manifest/chrome.json:
      • (a) Chrome Web Store (unlisted): upload the .zip with the owner's developer account; the store delivers installs and updates.
      • (b) Self-hosted CRX signed with the private key the owner holds (chrome --pack-extension=dist/chrome --pack-extension-key=<path to the .pem>), installable only via enterprise policy on Windows and macOS, so realistically Linux-only.
      • (c) "Load unpacked" from dist/chrome/ only, as today.

    Once the owner decides, the chosen steps — including which credentials they need and who holds them — are written into this section and README.md's installation sections are updated to match, which is part of the definition of done of #386. Check: for a store or AMO route, the artifact installs from the store or AMO on a clean browser profile; for the CRX or unpacked route, the documented load succeeds and Chrome reports the extension id gipbhkogfopeahplcjhipkgpcimdpkip.