Repository navigation
feat(release): package and distribute macOS builds via GitHub Releases and Homebrew - #17
Conversation
…s and Homebrew openhwp shipped v0.1.0 with no downloadable artifact. `deno desktop` was only ever run locally, so there was nothing for users to install and nothing a Homebrew cask could point at. Add a Release workflow, triggered by the GitHub Release that release-please publishes. That event only fires because release-please now runs with an app token (#16); under GITHUB_TOKEN it would not have. macOS signing is handled by `deno desktop` itself. With desktop.macos.codesignIdentity set it signs the bundle — including the CEF framework and the five helper apps — and applies Hardened Runtime and a secure timestamp. Verified against a local build: helper identifiers are derived correctly (dev.pleaseai.openhwp.helper, .helper.gpu), so no hand-rolled inside-out codesign pass is needed. Only notarization is manual, via notarytool with an App Store Connect API key, followed by stapling. The identity is injected in CI rather than committed: with codesignIdentity in deno.json, any contributor without the certificate would fail to build. Two details the build depends on. deno desktop has no universal-binary flag, so arm64 and x86_64 are built on separate runners and the cask carries both. And CFBundleName is derived from the --output filename, so builds land in a per-arch directory and are renamed afterwards — `-o OpenHWP-darwin-arm64.dmg` would otherwise name the application that. Signing degrades honestly: with no certificate configured the build emits a warning and produces an ad-hoc bundle, and the verify step fails if a certificate was supplied but the result is still ad-hoc. The cask is the tap's first (it holds CLI formulae today), so the job creates Casks/. packaging/homebrew/openhwp.rb is the reviewable copy of the generated template, mirroring the convention in pleaseai/shunt. JSR publishing is present but gated off. @openhwp does not exist on jsr.io yet, and the package would not be runnable regardless: it is the shell entrypoint, and the studio bundle it needs is gitignored and absent from the package. The job is documented as namespace reservation and stays disabled until the scope is created and JSR_PUBLISH_ENABLED is set.
There was a problem hiding this comment.
Code Review
This pull request adds a new Homebrew cask configuration file (openhwp.rb) for the OpenHWP desktop editor. The review feedback suggests two improvements: removing a relative directional reference ("below") in the comments to prevent future dangling references, and removing the redundant verified parameter from the url stanza since the download URL host matches the homepage host.
…mage `deno desktop` signs the .app it emits but leaves the .dmg container unsigned, so `codesign -dv` on the .dmg reports "code object is not signed at all" regardless of how the app was signed — the ad-hoc guard could never fire. Verify the .app instead (rejecting ad-hoc signatures and a missing Team ID), then sign the .dmg with a secure timestamp before notarizing it, which is what Apple expects of a stapled disk image.
Greptile SummaryThe PR adds an automated macOS release pipeline.
Confidence Score: 5/5The PR appears safe to merge. No blocking failure remains; the workflow now exits before building or publishing when the signing certificate is absent.
|
| Filename | Overview |
|---|---|
| .github/workflows/release.yml | Adds fail-closed signing, notarization, release-asset upload, Homebrew cask updating, and gated JSR publishing; the previously reported unsigned-publication path is closed by rejecting absent signing credentials. |
| packaging/homebrew/openhwp.rb | Adds a reviewable reference copy of the generated architecture-aware Homebrew cask. |
Flowchart
%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[Release published or manual dispatch] --> B[Build arm64]
A --> C[Build x86_64]
B --> D[Sign and notarize DMG]
C --> D
D --> E[Upload artifacts and checksums]
E --> F[Update Homebrew cask]
E --> G{JSR publishing enabled?}
G -->|Yes| H[Publish namespace package]
G -->|No| I[Skip JSR publishing]
Reviews (3): Last reviewed commit: "fix(release): fail the build when signin..." | Re-trigger Greptile
Drop the redundant `verified:` from the cask url — its host matches the homepage host, so `brew audit` flags it — and remove a relative directional reference from the placeholder comment. Applied to both the reviewable copy and the authoritative heredoc template in the release workflow.
… are missing The certificate step previously fell back to an ad-hoc signature with only a warning. Every trigger for this workflow — a published release or a manual dispatch — attaches its artifacts to a GitHub Release and publishes them through the Homebrew tap, so that fallback would ship a build Gatekeeper refuses to open on any machine but the runner that produced it. Treat a missing certificate, signing identity, or App Store Connect key as a hard error, which also removes the now-redundant `signed` output and its conditionals.
|



Summary
openhwp shipped v0.1.0 with no downloadable artifact.
deno desktophad only ever been run locally, so there was nothing for users to install and nothing a Homebrew cask could point at. This adds the packaging pipeline and wires up distribution.Triggered by the GitHub Release that release-please publishes. That event only fires because release-please now runs with an app token (#16) — under
GITHUB_TOKENit would not have, so this is a direct dependency on that fix.build-macosrelease-assetsSHA256SUMS, attach all assets to the releaseupdate-homebrew-caskCasks/openhwp.rbinpleaseai/homebrew-tappublish-jsrSigning is simpler than expected
deno desktopsigns macOS bundles itself. Withdesktop.macos.codesignIdentityset it signs the app including the CEF framework and its five helper apps, and applies Hardened Runtime plus a secure timestamp.I verified this against a real local build rather than trusting the docs — helper identifiers come out correctly derived (
dev.pleaseai.openhwp.helper,dev.pleaseai.openhwp.helper.gpu), so no hand-rolled inside-outcodesignpass is needed. Only notarization is manual (notarytool+stapler).The identity is injected in CI, not committed: with
codesignIdentityindeno.json, any contributor without the certificate would fail to build.Two build details worth knowing
macos-14,macos-15-intel) and the cask carries both.CFBundleNamefollows the--outputfilename. I hit this locally:-o OpenHWP-probe.appproduced an app literally named "OpenHWP-probe". So builds go to a per-arch directory and are renamed after, keeping the app namedOpenHWP.Signing degrades honestly rather than silently: with no certificate the build warns and produces an ad-hoc bundle, and the verify step fails if a certificate was supplied but the output is still ad-hoc.
Required before this can produce a distributable build
Secrets/variables on the repo or org:
APPLE_CERTIFICATE_P12_BASE64,APPLE_CERTIFICATE_PASSWORDAPPLE_SIGNING_IDENTITYDeveloper ID Application: … (TEAMID)APPLE_API_KEY_ID,APPLE_API_ISSUER_ID,APPLE_API_KEY_P8_BASE64APP_IDandPRIVATE_KEY(tap token) already resolve for this repo.JSR is deliberately gated off
jsr.io/@openhwpcurrently 404s, and the package would not be runnable anyway:apps/desktopis the shell entrypoint, and the studio bundle it requires is gitignored and therefore absent from the package —deno run jsr:@openhwp/desktopwould exit with "studio bundle not found".So the job is documented as namespace reservation and stays disabled behind
JSR_PUBLISH_ENABLED. Create the scope, link this repo for OIDC, then set the variable. Shipping it ungated would fail every release.Verification
ruby -c.deno fmt --check/deno lintpass.deno desktopbuild confirmed the bundle layout, ad-hoc signature, CEF framework + 5 helpers, and identifier derivation.release: published.workflow_dispatchwith a tag is provided for a dry run against an existing release.Checklist
packaging/homebrew/Summary by cubic
Build and ship signed, notarized macOS installers on every published release, then update the Homebrew cask so users can install via downloads or
brew install pleaseai/tap/openhwp. Runs afterrelease-pleasecreates a GitHub Release (enabled by the app-token fix in #16).New Features
OpenHWP.dmgfordarwin-arm64anddarwin-x64, verifies the.appsignature, signs the.dmgwith a timestamp, notarizes vianotarytool, staples, uploads, andSHA256SUMS; hard-fails if signing or notary credentials are missing.pleaseai/homebrew-tapCasks/openhwp.rbwith version and per-arch checksums; cask template passesbrew audit(dropsverified:on the url).JSRpublish step (namespace reservation only) behindJSR_PUBLISH_ENABLED.Migration
APPLE_CERTIFICATE_P12_BASE64,APPLE_CERTIFICATE_PASSWORD,APPLE_API_KEY_ID,APPLE_API_ISSUER_ID,APPLE_API_KEY_P8_BASE64.APPLE_SIGNING_IDENTITY(e.g., Developer ID string).Written for commit 6072a8e. Summary will update on new commits.