Skip to content

Build, sign, and notarize binaries on Buildkite - #56

Merged
mokagio merged 5 commits into
mainfrom
ainfra-3535-sign-and-notarize-beeper-cli-builds-on-buildkite
Oct 30, 2026
Merged

mokagio merged 5 commits into
mainfrom
ainfra-3535-sign-and-notarize-beeper-cli-builds-on-buildkite

Conversation

@mokagio

@mokagio mokagio commented Oct 30, 2026 •

Copy link
Copy Markdown
Contributor

Closes AINFRA-3535.

Builds all four binaries on Buildkite and signs and notarizes the two macOS ones with the Automattic Developer ID, so any team member can cut a release, not just from Batuhan's Mac.

Each build saves the files a GitHub Release needs as artifacts: the four archives, homebrew.json, and binaries.json. They come from build-homebrew-archive.ts, so the layout matches packages/cli/dist/.

The build publishes nothing.

Tradeoffs

  • fastlane does the signing (fastlane/Fastfile), the same as our other CLIs, instead of sign-macos-binaries.ts.
    sign_macos_binaries keeps the script's contract: it signs every darwin-* entry in binaries.json and rewrites its checksum.
  • The signature matches 0.6.2: identifier beeper-darwin-<arch>, hardened runtime, no entitlements.
    I checked that a locally signed build still runs under the hardened runtime.

Publishing from a build

From the repo root, at the commit Buildkite built:

buildkite-agent artifact download 'packages/cli/dist/**' . --build <build-uuid>   # or download from the build page into the same paths
(cd packages/npm && bun run build)
(cd packages/cli && bun scripts/publish-local-release.ts)

How to test

Build 2 notarized both macOS binaries. Gatekeeper accepts the downloaded arm64 one as Notarized Developer ID. Download the macOS arm64 zip, unzip it, then run codesign -dvv bin/beeper and bin/beeper --version.

mokagio and others added 3 commits October 30, 2026 11:42
fastlane will fetch the Developer ID certificate and sign and notarize the macOS binaries on Buildkite.
`.xcode-version` selects the Buildkite agent image.

---

Generated with the help of Claude Code, https://code.claude.com

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Same lanes as the Day One CLI, so Automattic's CLIs sign the same way.
`sign_macos_binaries` keeps the `binaries.json` contract of `sign-macos-binaries.ts`: it updates the macOS checksums after signing, so the npm and Homebrew publish steps read the manifest unchanged.

No explicit signing identifier: the CLI never touches the Keychain, and the file-name default matches what 0.6.2 shipped with.

---

Generated with the help of Claude Code, https://code.claude.com

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Releases had to come from Batuhan's Mac, the only machine with the signing secrets.
The step builds all four binaries on one Mac agent, since Bun cross-compiles the Linux ones, so a release's artifacts come from one place.
It publishes nothing: the npm and Homebrew steps read the archived `binaries.json` and binaries.

The binaries go into a tarball because Buildkite artifacts drop the executable bit.

---

Generated with the help of Claude Code, https://code.claude.com

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@mokagio mokagio self-assigned this Oct 30, 2026
@mokagio
mokagio requested a review from batuhan October 30, 2026 00:48
mokagio and others added 2 commits October 30, 2026 13:36
---

Generated with the help of Claude Code, https://code.claude.com

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
`build-homebrew-archive.ts` reads each binary from the absolute `path` in `binaries.json`, which only exists on the agent that built it.
Archiving downstream from the uploaded binaries would fail, so the job now builds the same archives, `homebrew.json`, and `binaries.json` a GitHub Release carries.
Flagged by Codex review.

---

Generated with the help of Claude Code, https://code.claude.com

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@mokagio
mokagio marked this pull request as ready for review October 30, 2026 03:07
Copilot AI balanced review requested due to automatic review settings October 30, 2026 03:07

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has insufficient remaining quota.

An organization owner can choose the repository organization as the billing source for reviews requested by members with a paid Copilot license. Learn about Copilot code review billing.

@mokagio
mokagio requested a review from a team October 30, 2026 03:13
@iFixRobots iFixRobots mentioned this pull request Oct 30, 2026

@AliSoftware AliSoftware left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Downloaded the mac arm64 zip, unzipped it, and checked:

$ codesign -dvv "/Users/olivierhalligon/Downloads/bin/beeper"
Executable=/Users/olivierhalligon/Downloads/bin/beeper
Identifier=beeper-darwin-arm64
Format=Mach-O thin (arm64)
CodeDirectory v=20500 size=231615 flags=0x10000(runtime) hashes=7232+2 location=embedded
Signature size=9052
Authority=Developer ID Application: Automattic, Inc. (PZYM8XX95Q)
Authority=Developer ID Certification Authority
Authority=Apple Root CA
Timestamp=30 Oct 2026 at 03:59:08
Info.plist=not bound
TeamIdentifier=PZYM8XX95Q
Runtime Version=15.2.0
Sealed Resources=none
Internal requirements count=1 size=180

$ "/Users/olivierhalligon/Downloads/bin/beeper"  --version
@beeper/cli/0.6.2 darwin-arm64 node-v24.3.0

I left a note about how our way to install bun on CI is not idea in terms of security, but since this is the official way documented by Bun themselves, not sure if there are other solutions they provide…

fi

echo "--- :bun: install Bun $bun_version"
curl -fsSL https://bun.sh/install | bash -s "bun-v$bun_version"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wish there were a safer way to install a specific version of bun on the Mac; because curl … | bash doesn't feel super secure (the shell script we curl and run could end up being compromised one day…)

Any other, safer alternatives?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mokagio
mokagio merged commit 3a88738 into main Oct 30, 2026
7 of 8 checks passed
@mokagio
mokagio deleted the ainfra-3535-sign-and-notarize-beeper-cli-builds-on-buildkite branch October 30, 2026 19:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

3 participants