Skip to content

feat(ci): publish native macOS beta DMGs from a dedicated workflow - #362

Merged
lassejlv merged 1 commit into
mainfrom
feat/macos-native-release-workflow
Jul 24, 2026
Merged

feat(ci): publish native macOS beta DMGs from a dedicated workflow#362
lassejlv merged 1 commit into
mainfrom
feat/macos-native-release-workflow

Conversation

@lassejlv

Copy link
Copy Markdown
Owner

Adds .github/workflows/macos-native-release.yml: builds the native Swift host from macos/ for Apple silicon and Intel and publishes both DMGs.

Nothing published the native host before. macOS Native Swift gates it per PR and macOS Native Candidates keeps builds as Actions artifacts — both by design.

Shape

  • Separate from release.yml. Own trigger (macos-native-v* tag or manual dispatch), own prerelease, never marked latest. A native failure can neither block nor alter the GPUI desktop artifacts, and the two DMGs never share a release.
  • Versioning. crates/desktop_app/Cargo.toml stays authoritative and the build refuses a mismatched tag. A tag may carry -preview.N to republish the same app version; the version inside the bundle stays numeric.
  • Dry run. Dispatch with publish unchecked to run the full build and every gate without creating a release.

Jobs

Job Does
resolve Parses the tag/input, validates semver, matches it against the source version — fails before any macOS runner starts
verify Swift build with warnings-as-errors, full swift test, static readiness checks
build (arm64, x86_64) Unsigned DMG + release gates, stages publishable assets
publish Combined checksums, release notes, prerelease at the tag

Per-architecture gates: unsigned release readiness via build-dmg.sh (Mach-O arch, bundle manifest, read-only DMG mount, usable-window launch), isolated CLI install smoke, launch performance budget, a 30-second soak, and bundle/DMG corruption rejection. Render performance stays in macOS Performance, where a threshold miss should block a change rather than a release.

Artifacts

Published DMGs are renamed Termy-native-<version>-macos-<arch>.dmg. macos/scripts/build-dmg.sh emits Termy-<version>-macos-<arch>.dmg, the exact name the GPUI desktop app uses, so a downloaded file would otherwise carry no signal of which build it is — they install as the same Termy.app with the same bundle identifier. Each DMG ships a .sha256, a combined checksums.txt, and a .metadata file with source commit and toolchain versions. Launch/soak JSON reports stay as 30-day Actions artifacts.

Builds are unsigned; release notes carry the quarantine-clearing command. build-dmg.sh already accepts --sign-identity and notary credentials, so signing later is wiring, not packaging work.

Beta status

Records the native host's move from developer preview to public beta in macos/README.md, macos/roadmap.md, and CLAUDE.md.

Validation

  • Workflow YAML parses; job graph is resolve → verify → build (matrix) → publish.
  • Version-resolution logic exercised locally against tag push, dispatch, a -preview.N suffix, a malformed version, and a version that disagrees with Cargo.toml — accepts and rejects as intended.
  • Asset staging (copy, bare-filename checksum, metadata) run locally.
  • ./scripts/check-boundaries.sh passes except a pre-existing docs/configuration.md drift on main (theme_light default documented as termy, source says termy-light) — untouched here.
  • Untrusted inputs (inputs.version, github.ref_name) are passed through env: and only read as shell variables.

🤖 Generated with Claude Code

The native Swift host had no way to reach users: `macOS Native Swift` gates it
per PR and `macOS Native Candidates` keeps builds as Actions artifacts, both by
design. Add `macOS Native Release`, which builds arm64 and x86_64 DMGs and
publishes them.

It stays out of `release.yml` on purpose. The workflow triggers on its own
`macos-native-v*` tag or a manual dispatch, and publishes its own prerelease,
never marked latest, so a native failure can neither block nor alter the GPUI
desktop artifacts. `crates/desktop_app/Cargo.toml` stays the authoritative
version; a tag may add a `-preview.N` suffix to republish the same app version.

Per architecture the workflow runs the unsigned readiness gate (through
`build-dmg.sh`), the isolated CLI install smoke, the launch performance budget,
a 30-second soak, and the corruption-rejection regressions. Published DMGs are
renamed to `Termy-native-<version>-macos-<arch>.dmg` because the packaging
script emits the same file name the GPUI desktop app uses, and a downloaded
file carries no other signal of which build it is.

Builds are unsigned; the release notes carry the quarantine-clearing command.

Also records the native host's move from developer preview to public beta.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@lassejlv
lassejlv merged commit 7f20415 into main Jul 24, 2026
8 of 9 checks passed
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