Add tooling and CI integration to sign Mac CLI#77
Conversation
Scaffolds the `set_up_signing` lane that fetches the Developer ID Application certificate via `fastlane match` (readonly) from Automattic's S3 bucket on the Buildkite signing agents. This is cert delivery only — the build/sign/notarize steps land separately. Part of AINFRA-2466. The `Gemfile` pins `multi_json` because the latest released fastlane (2.235.0) crashes at startup on Ruby 3.3+ without it; see the comment for the upstream cause and the fastlane fix that makes it removable. Generated by the apple:ruby-fastlane-setup Claude Code skill. --- Generated with the help of Claude Code, https://code.claude.com Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughAdds Fastlane-based code signing automation and a Buildkite macOS signing pipeline: pins Fastlane gems and multi_json, configures Bundler, defines Fastlane signing constants and lanes to fetch signing artifacts from S3, and adds CI scripts/pipeline steps to build, sign, notarize, and publish macOS binaries. ChangesFastlane Code Signing Automation
Buildkite macOS signing pipeline
sequenceDiagram
participant Developer
participant Buildkite
participant Script
participant Fastlane
participant EnvManager
participant S3
Developer->>Buildkite: push / trigger pipeline (mac)
Buildkite->>Script: run .buildkite/commands/sign-macos-binaries.sh
Script->>Fastlane: install_gems && bundle exec fastlane set_up_signing
Fastlane->>EnvManager: initialize(env_file_name: 'bridge-manager.env')
Fastlane->>EnvManager: validate CODE_SIGNING_ENV_VARS / ASC_API_KEY_ENV_VARS (conditional)
Fastlane->>S3: sync_code_signing(request: macOS Developer ID, team: PZYM8XX95Q, storage options)
S3-->>Fastlane: certificate & provisioning profiles
Script->>Script: build binaries (amd64, arm64), sign & notarize
Script-->>Buildkite: upload artifacts (bbctl-macos-*, sha256sums.txt)
🎯 3 (Moderate) | ⏱️ ~20 minutes 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
Add `.bundle/config` (mirroring platform-imessage): `BUNDLE_PATH: vendor/bundle` keeps gems in the repo and out of the agent's system Ruby, and `BUNDLE_FORCE_RUBY_PLATFORM` pins the pure-Ruby gem variants so the lock is portable between a developer's Mac and the CI agents. Regenerate `Gemfile.lock` from a fresh resolve so its `PLATFORMS` is `ruby` only, and gitignore the vendored `vendor/bundle/`. --- Generated with the help of Claude Code, https://code.claude.com Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Pin `~> 2.235` (fastlane) and `~> 14.6` (wpmreleasetoolkit), the current latest on RubyGems, instead of stale floors. Lock regenerated from a fresh resolve. --- Generated with the help of Claude Code, https://code.claude.com Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Builds the macOS binaries with Go, fetches the Developer ID cert via
`fastlane set_up_signing`, and signs + notarizes them with the a8c-ci-toolkit
`sign_and_notarize` command (no entitlements — plain CLI under hardened
runtime). Signed `bbctl-macos-{amd64,arm64}` + `sha256sums.txt` are uploaded as
build artifacts; runs on every build, mirroring the platform-imessage pipeline.
Publishing the signed binaries to GitHub Releases is intentionally out of scope
here: `gh` auth on the mac agents is unverified, and whether release publishing
moves off GitHub Actions is still open. The toolkit pin is temporary (a branch)
until the command ships in a tagged release.
---
Generated with the help of Claude Code, https://claude.ai/code
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.buildkite/shared-pipeline-vars:
- Around line 11-12: CI_TOOLKIT_PLUGIN_VERSION is set to a mutable branch and
used to build CI_TOOLKIT_PLUGIN, which makes CI behavior changeable; update
CI_TOOLKIT_PLUGIN_VERSION from the branch name (mokagio/macos-sign-and-notarize)
to an immutable ref (a released tag or specific commit SHA) and ensure
CI_TOOLKIT_PLUGIN is constructed from that pinned value so
.buildkite/pipeline.yml always uses a fixed plugin revision.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: c385ee50-6f86-43b4-b969-46b5baf107db
📒 Files selected for processing (3)
.buildkite/commands/sign-macos-binaries.sh.buildkite/pipeline.yml.buildkite/shared-pipeline-vars
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
- GitHub Check: build-docker (amd64)
- GitHub Check: lint
- GitHub Check: build-docker (amd64)
- GitHub Check: build-docker (arm64)
- GitHub Check: lint
🔇 Additional comments (2)
.buildkite/pipeline.yml (1)
4-21: LGTM!.buildkite/commands/sign-macos-binaries.sh (1)
3-30: LGTM!
Track the latest macOS signing image (26.5) via `.xcode-version` instead of hardcoding it, matching the platform-imessage convention. bbctl is a Go CLI with no Xcode dependency — the image only supplies codesign/notarytool and the WWDR intermediates — so it tracks latest rather than pinning a version. --- Generated with the help of Claude Code, https://claude.ai/code Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The Xcode 26.5 image's clang cannot compile `nokogiri` 1.19.3 from source (`gumbo.c: 'nokogiri_gumbo.h' file not found`), which fails `bundle install` in the signing job. `fastlane` pulls `nokogiri` in transitively via `wpmreleasetoolkit`, and `.bundle/config` forces the Ruby (source) platform, so the precompiled darwin gem is never used. Pin to 26.3, which compiles it, and record the reason as a note in `.xcode-version`. The `shared-pipeline-vars` parser now skips comment and blank lines so the note doesn't leak into `IMAGE_ID`. --- Generated with the help of Claude Code, https://claude.com/claude-code Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: Gio Lodi <giovanni.lodi42@gmail.com>
`mokagio/macos-sign-and-notarize` is a moving ref; pinning the current tip (`8a67edf`, "Log applied cert/team after signing") makes the signing build reproducible until the command ships in a released tag. --- Generated with the help of Claude Code, https://claude.com/claude-code Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
--- Generated with the help of Claude Code, https://claude.com/claude-code Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Buildkite now compiles, signs, and notarizes the macOS binaries on a real Mac and publishes them under the same names. The unsigned GitHub Actions copies were redundant and unused, so stop building and uploading them. --- Generated with the help of Claude Code, https://claude.com/claude-code Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
There was a problem hiding this comment.
Pull request overview
This PR introduces a Ruby/fastlane-based macOS code-signing and notarization workflow executed in Buildkite, and removes the macOS build artifact path from GitHub Actions to reduce CI surface area there.
Changes:
- Add fastlane tooling (Gemfile/Gemfile.lock + Fastfile) to fetch Developer ID signing material in CI.
- Add a Buildkite pipeline + command script to build, sign, notarize, and publish macOS CLI artifacts with checksums.
- Remove macOS binary builds/uploads from the existing GitHub Actions workflow and build-all script.
Reviewed changes
Copilot reviewed 10 out of 12 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| Gemfile.lock | Adds locked Ruby dependencies needed for fastlane/code-signing tooling. |
| Gemfile | Declares fastlane + plugin dependencies and documents the multi_json workaround. |
| fastlane/Fastfile | Defines the set_up_signing lane to sync Developer ID signing certs in CI. |
| fastlane/.gitignore | Ignores fastlane-generated outputs within the fastlane/ directory. |
| ci-build-all.sh | Removes macOS builds from the GitHub Actions “build all” script. |
| .xcode-version | Pins the Buildkite macOS/Xcode image version used for building/signing. |
| .gitignore | Ignores Bundler’s vendor/bundle/ directory used for CI installs. |
| .github/workflows/go.yaml | Removes upload steps for macOS artifacts in GitHub Actions. |
| .bundle/config | Configures Bundler to install into vendor/bundle and to use the Ruby platform. |
| .buildkite/shared-pipeline-vars | Exports image/plugin variables used when uploading the Buildkite pipeline. |
| .buildkite/pipeline.yml | Adds Buildkite step to build + sign + notarize macOS binaries and upload artifacts. |
| .buildkite/commands/sign-macos-binaries.sh | Implements the macOS build/sign/notarize command sequence for Buildkite. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| # TEMPORARY: pinned to a commit on the `mokagio/macos-sign-and-notarize` branch | ||
| # adding the macOS `sign_and_notarize` command. Revert to a released tag | ||
| # (>= the version that ships it) before merging. | ||
| CI_TOOLKIT_PLUGIN_VERSION='8a67edfc19a7fd04de7033d790bd1a7a4f0f8b4d' | ||
| export CI_TOOLKIT_PLUGIN="automattic/a8c-ci-toolkit#$CI_TOOLKIT_PLUGIN_VERSION" |
| # fastlane <= 2.235.0 crashes at startup on Ruby 3.3+ with "multi_json is not | ||
| # part of the bundle": Google stopped pulling multi_json transitively | ||
| # (googleapis/google-api-ruby-client#26611) and fastlane eagerly loads its | ||
| # Google Play actions, which require it through representable. fastlane re-added | ||
| # it as a direct dependency for 2.236.0 (fastlane/fastlane#30062) — drop this | ||
| # line once the lock is on fastlane >= 2.236.0. |
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
See AINFRA-2466.
Generated by Claude (Opus 4.8) on behalf of @mokagio with approval.
Checkout the artifacts in the latest Buidkite build to confirm the code signing and notarization: https://buildkite.com/automattic/bridge-manager/builds/9/list?jid=019eaf13-4942-499d-a1df-f7821a5f5dcf&tab=artifacts