Skip to content

ci: restore macOS Keychain for cfl and jtk darwin releases [INT-450]#376

Merged
rianjs merged 1 commit into
mainfrom
fix/INT-450-darwin-cgo-keychain
May 19, 2026
Merged

ci: restore macOS Keychain for cfl and jtk darwin releases [INT-450]#376
rianjs merged 1 commit into
mainfrom
fix/INT-450-darwin-cgo-keychain

Conversation

@rianjs
Copy link
Copy Markdown
Contributor

@rianjs rianjs commented May 19, 2026

Summary

  • Split each goreleaser config into a {tool}-darwin build (CGO_ENABLED=1, xcrun clang) and a {tool}-unix-win build (CGO_ENABLED=0), covering both amd64 and arm64 for each GOOS group
  • Move both release-cfl.yml and release-jtk.yml goreleaser jobs from ubuntu-latest to macos-15 so cgo+darwin compiles natively
  • Add a pre-publish gate to each workflow: goreleaser check → snapshot build → assert Security.framework linked in amd64 binary and keychain (auto) reported by the arm64 binary's config show → publish only if gate passes
  • Pin nfpms.ids to each tool's unix-win build id so deb/rpm packages never pull a darwin binary

Fixes [INT-450] / Closes #375

Root cause

99designs/keyring/keychain.go is //go:build darwin && cgo. With CGO_ENABLED=0 (the previous build), the init() that registers the macOS Keychain backend is never compiled in. At runtime, credstore auto-selects BackendKeychain then keyring.Open returns ErrNoAvailImpl, failing closed on every macOS credential op since the credstore migration.

Files changed

  • .goreleaser-cfl.yml — split single build into cfl-darwin (CGO=1) + cfl-unix-win (CGO=0); nfpms.ids: [cfl-unix-win]
  • .goreleaser-jtk.yml — split single build into jtk-darwin (CGO=1) + jtk-unix-win (CGO=0); nfpms.ids: [jtk-unix-win]
  • .github/workflows/release-cfl.ymlmacos-15 runner; install-only goreleaser; check → snapshot → gate → publish; verify release notes
  • .github/workflows/release-jtk.yml — same restructure; preserves jira-ticket-cli alias cask sed step and tag-rename dance

Test plan

  • goreleaser check -f .goreleaser-cfl.yml exits 0
  • goreleaser check -f .goreleaser-jtk.yml exits 0
  • cfl arm64 + amd64 CGO builds: correct Mach-O arch, Security.framework linked on amd64
  • jtk arm64 + amd64 CGO builds: correct Mach-O arch, Security.framework linked on amd64
  • cfl functional gate: cfl --output json config show with isolated HOME/XDG reports keychain (auto)
  • jtk functional gate: jtk config show with isolated HOME/XDG reports keychain (auto)
  • All 6 checks above passed locally on darwin/arm64

Split each goreleaser build into a darwin (CGO_ENABLED=1, xcrun clang)
target and a linux/windows (CGO_ENABLED=0) target so that
99designs/keyring's keychain.go (//go:build darwin && cgo) is compiled
into the macOS binaries. Without cgo the init() that registers the
Keychain backend is omitted; credstore auto-selects BackendKeychain then
keyring.Open returns ErrNoAvailImpl, failing closed on every macOS
credential op since the credstore migration.

Move both release jobs to macos-15 (cgo+darwin cannot cross-compile from
Linux). Restructure each job: goreleaser install-only → check → snapshot
→ pre-publish gate → publish. Gate asserts Security.framework is linked
in the amd64 binary (otool) and that the arm64 binary's config show
reports keychain backend auto-selected (functional, isolated HOME/XDG,
no real token required). nfpms.ids pins each tool's unix-win build id so
deb/rpm never pull a darwin binary.

Closes #375
@rianjs
Copy link
Copy Markdown
Contributor Author

rianjs commented May 19, 2026

No findings.

I verified PR #376’s actual diff is limited to the expected four files. Both GoReleaser configs match the template: split *-darwin/*-unix-win builds, fully keyed darwin overrides with quoted CC=..., preserved dir: tools/{cfl,jtk}, nfpms.ids pinned to unix/win builds, and unfiltered archives remain safe because GOOS sets are disjoint.

The workflow ordering is correct in both release files: install/check, temp semver tag, snapshot build with GORELEASER_CURRENT_TAG, pre-publish gate, real publish with TAP_GITHUB_TOKEN, tag rename, then release-note verification. The cfl and jtk gates both reach keyring.InspectForTool -> OpenNoMigrate; a CGO-disabled darwin binary would not render keychain (auto), so the grep cannot pass vacuously. amd64 Security.framework and both-arch Mach-O checks are present for both tools.

Bash/tooling looks macOS-safe: no sed -i, no Bash 4-only constructs, quoted paths, set -euo pipefail on the new multi-command gate/release-note steps, and GH_TOKEN is present on gh release steps. I also ran goreleaser check -f .goreleaser-cfl.yml, goreleaser check -f .goreleaser-jtk.yml, and git diff --check; all passed.

@rianjs rianjs merged commit 16e7373 into main May 19, 2026
7 checks passed
@rianjs rianjs deleted the fix/INT-450-darwin-cgo-keychain branch May 19, 2026 20:16
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.

cfl+jtk macOS binaries fail closed: CGO_ENABLED=0 strips the Keychain backend [INT-450]

1 participant