Skip to content

Continuous deployment: release every green merge to main - #34

Merged
subev merged 5 commits into
mainfrom
ci/continuous-deployment
Oct 7, 2026
Merged

subev merged 5 commits into
mainfrom
ci/continuous-deployment

Conversation

@subev

@subev subev commented Oct 7, 2026

Copy link
Copy Markdown
Owner

Every push to main whose Test run passes is tagged, built, notarised, published, pushed to GHCR and bumped in the Homebrew tap, with no manual step.

  • deploy.yml (new): workflow_run on Test → release.mjs --yes → dispatch release.yml and docker.yml on the tag → watch the build → ship.mjs --unattended.
  • release.yml: dispatched on a tag, it builds that tag. Dispatched on main, it still cuts a version as before.
  • ship.mjs --unattended: no prompt. It refuses a build that wasn't notarised or isn't the newest, and writes the tap with TAP_TOKEN; without the token it warns and skips the tap.

Merge only after v26.1007.3 is published, otherwise the first automatic release leaves it as a draft.

Needs a TAP_TOKEN secret in the release environment: a fine-grained PAT with Contents read/write on subev/homebrew-libratory only.

Verification: actionlint passes on deploy.yml. Not run end to end. The merge of this PR is the first real run.

subev added 5 commits October 7, 2026 16:18
Releases were cut and published by hand (pnpm release, then pnpm ship),
which is review nobody has time for. deploy.yml now runs when Test
passes on main: release.mjs tags the commit, Release and Docker image
are dispatched on the tag (a tag pushed with the workflow token starts
no workflow by itself), and ship.mjs --unattended publishes once the
build passes. Problems are fixed forward.

It skips a tested commit main has already moved past, whose own run
deploys the newer one, and a commit that already carries a tag.
--unattended refuses, rather than warns about, a build the notary did
not accept or one a newer release has overtaken. release.yml builds a
tag when dispatched on one instead of cutting another version. The tap
is bumped with TAP_TOKEN from the release environment; without it the
release still ships and the run warns.

actionlint passes on deploy.yml. The first real run is the merge of
this commit.
With every green merge released automatically, the local review is the
only look a change gets before users have it, and nothing enforced it.
A review is now recorded as a git note under refs/notes/review on the
exact commit reviewed (pnpm review:stamp), covering it and its ancestors
back to where the branch left main; a commit added afterwards is not
covered. .githooks/pre-push (installed by pnpm install through
core.hooksPath) refuses a push to main with an uncovered commit and
pushes the notes with every push; deploy.yml runs the same check before
tagging, as the backstop for --no-verify and merges made on GitHub. No
model runs in either: the note is the evidence.

release.mjs no longer commits the version: it tags main's head and
pushes the tag, and release.yml stamps the version into the desktop
package from the tag before building. Main then changes only through
reviewed merges. It refuses commits not yet on origin/main and a commit
that is already released.

Verified in a scratch repo: unreviewed branch refused, stamped branch
covered, a commit after the stamp refused, merge commit covered, direct
commit on main refused; the hook refused and then allowed a push to a
bare remote and pushed the notes; feature-branch pushes are unaffected.
The desktop app gives its server a PATH of bundled tools, Homebrew and
/usr/bin, and macOS keeps mkdir and rm only in /bin, so the BgTTS
install shipped in 26.1007.3 stopped at its first line with "mkdir:
command not found". The script now appends the system directories to
whatever PATH it is given.

Reproduced with the app's PATH under env -i (exit 127), then the same
run built a venv end to end with the fix.
A run dispatched on a tag is not guaranteed to be listed under the tag's name the way a tag push is; deploy.yml and ship.mjs now find it by the tagged commit, which is the same either way. Checked against the v26.1007.3 build.
@subev
subev merged commit 2b77687 into main Oct 7, 2026
10 checks passed
@subev
subev deleted the ci/continuous-deployment branch October 7, 2026 13:58
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