From fd53737403510f3595ee40df7aa56a81006941ea Mon Sep 17 00:00:00 2001 From: sneak Date: Mon, 2 Nov 2026 03:34:38 +0000 Subject: [PATCH] docs: second rework of the release procedure after review Apply the five wording findings of the second review verbatim: the owner's rule as one lead-in with three acts, the yarn source without a pronoun, the workflow definition with its file first, the two e2e jobs named with their scripts, and the manifest version tied to step 2. The same three faults were fixed elsewhere: pronouns with two candidates, phrases that arrive after the words they belong to, and terms used before they were defined. Model: fable-5-1 --- docs/RELEASE.md | 75 +++++++++++++++++++++++++++---------------------- 1 file changed, 41 insertions(+), 34 deletions(-) diff --git a/docs/RELEASE.md b/docs/RELEASE.md index 1bd6ea8..0d91a1b 100644 --- a/docs/RELEASE.md +++ b/docs/RELEASE.md @@ -1,13 +1,13 @@ # Releasing AutistMask -A release is a tagged commit on `main` and the two archives that `make package` -writes from that commit. This file is the procedure, in order. +A release is a tagged commit on the `main` branch and the two archives that +`make package` writes from that commit. This file is the procedure, in order. -The owner ([@sneak](https://sneak.berlin)) alone decides three things: +Only the owner ([@sneak](https://sneak.berlin)): -- whether and when a release is tagged; -- the tags: only the owner creates, moves or deletes a tag; -- where the archives are published. +- decides whether and when a release is tagged; +- creates, moves or deletes a tag; +- decides where the archives are published. Anyone can run steps 1 to 4. No script in this repository uploads or publishes the archives. None signs them, and none packs a CRX (Chrome's packaged extension @@ -16,16 +16,17 @@ file). ## Terms - The tracker is the repository's Gitea site (Gitea is the software that hosts - the repository): https://git.eeqj.de/sneak/AutistMask. Its Actions page, - https://git.eeqj.de/sneak/AutistMask/actions, lists the workflow runs. -- A workflow is a list of jobs that the tracker runs on every push, from a file - under `.gitea/workflows/`. Each job runs one script on the tracker's runner - (the machine that runs jobs). + the repository): https://git.eeqj.de/sneak/AutistMask. The tracker's Actions + page, https://git.eeqj.de/sneak/AutistMask/actions, lists the workflow runs. +- A workflow is a file under `.gitea/workflows/` that lists jobs. The tracker + runs every workflow on each push. Each job runs one script on the tracker's + runner (the machine that runs jobs). - The release commit is a commit on `main`. Releases are tagged from `main` only (`TODO.md`, Workflow). -- A clean checkout is a working tree at the release commit where - `git status --porcelain` prints nothing. The build stamps the commit hash into - the extension and appends `-dirty` when the tree has local changes. +- A clean checkout is a working tree (the checked-out files) at the release + commit where `git status --porcelain` prints nothing. The build stamps the + commit hash (the commit's id) into the extension and appends `-dirty` when the + tree has local changes. - A tag is a name that git attaches to one commit. Release tags read `vX.Y.Z`, such as `v0.1.0`. - A digest is the sha256 hash of a file (a fixed-length fingerprint of its @@ -39,8 +40,9 @@ file). step 1. `make package` needs no Docker. - Node and yarn. Both come from the system when present. Otherwise `script/bootstrap` installs Node through a pinned (fixed-version) install of - nvm, a Node version manager. It installs yarn through corepack (Node's package - manager installer) or, failing that, through `npm` (Node's package manager). + nvm, a Node version manager. `script/bootstrap` installs yarn through corepack + (Node's package manager installer). When no corepack is found, + `script/bootstrap` installs yarn through `npm` (Node's package manager). ## Procedure @@ -51,23 +53,25 @@ every push. `script/cibuild` runs: - `script/bootstrap`, which installs the dependencies; - `script/check`, which is what `make check` runs; -- the Docker image build. +- the Docker image build (an image is Docker's packaged form of a program). `script/check` runs: - `script/test`: the tests, in Docker; -- `script/lint`, in Docker, which runs three checks: +- `script/lint`, which runs three checks in Docker: - ESLint, a code checker; - `prettier --check .`, the formatting check; - `script/check-censored`, which fails when the name that `RULES.md` bars appears outside its allowed places; - `script/fmt-check`: `prettier --check .` again, on the host. -The `e2e` workflow (`.gitea/workflows/e2e.yml`) runs the two browser suites on -every push, as two jobs. A red `e2e` job does not fail the `check` run. +The `e2e` workflow (`.gitea/workflows/e2e.yml`) has two jobs. One runs +`script/test-e2e`, the browser tests in Chrome. The other runs +`script/test-e2e-firefox`, the browser tests in Firefox. A red `e2e` job does +not fail the `check` run. -Run `script/cibuild` on the clean checkout. It runs the same steps as the -`check` run, and it must exit 0. +Run `script/cibuild` on the clean checkout. `script/cibuild` runs the same steps +as the `check` run, and must exit 0. Check: on the Actions page, the `check` run for the release commit succeeded, and both `e2e` jobs for that commit succeeded. `script/cibuild` exited 0 on the @@ -108,7 +112,7 @@ make package `make build`: -- runs `build.js`. It writes `dist/chrome/`, `dist/firefox/` and a build +- runs `build.js`. `build.js` writes `dist/chrome/`, `dist/firefox/` and a build receipt. The receipt lists every file that `build.js` wrote, with each file's digest. The receipt lives outside the repository and is deleted when the build ends; @@ -127,9 +131,11 @@ make package - empties `release/`; - refuses a symbolic link (a file that points at another file) under `dist/`; - checks that the archive is self-contained: every file that the manifest or the - popup's HTML page names is inside the browser's directory. The manifest is - `manifest.json`, the file that describes the extension to the browser; -- checks that the `version` in each `manifest.json` is the tree's version; + popup's HTML page names is inside the browser's directory (`dist/chrome/` or + `dist/firefox/`). The manifest is `manifest.json`, the file that describes the + extension to the browser. The popup is the window that the toolbar button + opens; +- checks that the `version` in each `manifest.json` is the version from step 2; - writes one archive per browser; - reads each archive back; - compares every member (a file inside the archive) with `dist/` byte for byte; @@ -147,7 +153,7 @@ release/SHA256SUMS ``` The `.xpi` is Firefox's add-on package file (an add-on is Firefox's word for an -extension). It is not signed. +extension). The `.xpi` is not signed. `make package` prints a line that starts `Not shipped` and names `styles.css`. This is expected: each archive holds its own copy of the stylesheet. @@ -159,18 +165,19 @@ version from step 2. From `release/`, run `sha256sum -c SHA256SUMS`. -The archives are deterministic for a given `dist/`. `script/lib/zip.js`: +The archives are deterministic for a given `dist/`: the same `dist/` always +gives the same bytes. `script/lib/zip.js`: - sorts the members; -- sets every timestamp to 1980-01-01; +- sets every member's timestamp (its recorded date) to 1980-01-01; - compresses each member the same way every time. `dist/` itself carries the build date. `build.js` compiles the build date, a UTC (universal time) day, into the extension. So two builds of the same commit on the same UTC day give byte-identical archives. Builds on different days differ. -Check: `sha256sum -c` prints `OK` for both archives. A second `make package` -from another clean checkout of the same commit, on the same UTC day, gives the +Check: `sha256sum -c` prints `OK` for both archives. On the same UTC day, a +second `make package` from another clean checkout of the same commit gives the same `SHA256SUMS`. ### 5. Tag the release commit @@ -185,7 +192,7 @@ git push origin vX.Y.Z ``` `-a` makes an annotated tag: a tag that carries a message and records who made -it and when. `v0.1.0` is one. +the tag and when. `v0.1.0` is one. Once the tag exists, `git describe --tags` on the release commit prints `vX.Y.Z`. `script/cibuild` and `script/docker` pass that value to the Docker @@ -210,10 +217,10 @@ Chrome loads the extension from a directory: Chrome then reports the extension id `gipbhkogfopeahplcjhipkgpcimdpkip`. The id is the fixed string that identifies the extension to Chrome; the `key` in -`manifest/chrome.json` sets it. +`manifest/chrome.json` sets the id. Release builds of Firefox refuse to install an unsigned add-on. Desktop Firefox -115 or newer, in any edition, loads the `.xpi` as a temporary add-on from its +115 or newer, in any edition, loads the `.xpi` as a temporary add-on from the `about:debugging` page. Firefox unloads a temporary add-on when Firefox exits. The section "Installing on Firefox" in `README.md` has the details.