Skip to content

feat(release): tag-driven release and install#60

Merged
0xnirapod merged 5 commits into
mainfrom
release-pipeline
Jun 12, 2026
Merged

feat(release): tag-driven release and install#60
0xnirapod merged 5 commits into
mainfrom
release-pipeline

Conversation

@0xnirapod

@0xnirapod 0xnirapod commented Jun 12, 2026

Copy link
Copy Markdown
Member

Tag-driven release: cut a tag, the workflow builds, gates, and publishes. One version source (VERSION); the helper bundle, the CLI, and package.json read or mirror it.

What's here

  • scripts/release.sh (make release VERSION=x.y.z) cuts the release: semver (optionally -prerelease), on main, clean tree, tag free, ahead of the last tag, CI green on HEAD. Bumps VERSION and the mirrors, commits, tags, pushes.
  • .github/workflows/release.yml runs on a v* tag: asserts the tag equals VERSION, builds the .app and CLI ad-hoc, gates them through the fence (static and --bundle) and the non-SEP tests, then packages a tag-pinned source tarball, an ad-hoc .app zip, and SHA256SUMS, publishes the release, and opens the Homebrew formula bump PR.
  • Formula/simenclave.rb builds from source. The url points at the release-attached tarball, the one SHA256SUMS covers, and the bump reuses that published checksum, so the formula and the checksums pin the same artifact. The interposer is never built or shipped here.
  • scripts/install.sh is the curl | sh path: clones a validated version tag and builds locally.

CI

The portable lane is split into commitlint (always-on, the required check) and lint (biome, path-filtered). The macOS build runs only on native, build, and script changes; the fence skips docs-only changes. A docs change no longer fires the macOS runner.

Hardening folded in

  • The formula pins the attached tarball (the auto-archive it pointed at was not in SHA256SUMS).
  • build-menubar-app.sh runs under set -e, so a failed copy cannot produce a signed-but-partial bundle; CFBundleShortVersionString is numeric even for a prerelease tag.
  • install.sh only follows a vX.Y.Z tag, not an arbitrary branch ref.

Custody gate: PASS (dev tool, the developer's own Mac SEP, no user keys or funds). Fence: static and bundle both pass on the built .app.

Cuts v1.0.0-beta once merged.

A VERSION source of truth (the .app's CFBundleShortVersionString and the CLI version follow it),

scripts/release.sh (a guarded cut: semver ahead of the last tag, clean main, CI green; then bump,

commit, tag, push), and .github/workflows/release.yml (on the tag: build the .app + CLI, the fence

static + bundle gates and the non-SEP tests, a tag-pinned source tarball + ad-hoc .app zip +

SHA256SUMS, notes from the commits, the GitHub Release, then the Homebrew formula bump as a PR).

Formula/simenclave.rb builds from source and ad-hoc signs; locally built is never quarantined and

the Secure Enclave works ad-hoc. scripts/install.sh is the curl|sh path. The README records the

Gatekeeper reality. make release VERSION=x.y.z drives it. The interposer is never built or shipped.
Split the portable lane into commitlint (always-on, the required check) and lint
(biome, path-filtered to the JS/TS/JSON tree). Gate the macos build on native, build,
and script paths, and skip the fence on docs-only changes. A README edit no longer
spends a macOS runner; the required commitlint check still gates every PR.
Drop the Gatekeeper and no-notarization rationale from the README install section. The
two install commands and a one-line note are enough; the reasoning is not the reader's
concern.
The formula bump pointed at GitHub's auto-generated archive, which SHA256SUMS does not
cover, so the published checksums protected nothing the formula consumed. Point the url
at the release-attached git-archive tarball and reuse its SHA256SUMS entry, so the
formula and the checksums pin the same byte-stable artifact.

Also: set -e in build-menubar-app.sh so a failed copy cannot yield a signed-but-partial
bundle; derive a numeric CFBundleShortVersionString so a prerelease tag stays a valid
plist version; allow a -prerelease suffix in the cut guard and mark prerelease releases;
and guard install.sh to follow a version tag, not an arbitrary branch ref.
Set VERSION and its mirrors (the CLI constant, package.json) to the first release tag.
The bundle reports 1.0.0, the CLI and package report 1.0.0-beta.
@0xnirapod
0xnirapod merged commit 6066ff5 into main Jun 12, 2026
4 checks passed
@0xnirapod
0xnirapod deleted the release-pipeline branch June 12, 2026 14:25
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