ci: build darwin releases with cgo so macOS Keychain backend is present [INT-446]#164
Conversation
…resent [INT-446] Release binaries were built CGO_ENABLED=0 on ubuntu-latest, so 99designs/keyring's `//go:build darwin && cgo` Keychain backend was never compiled in and credstore failed closed on macOS for every user who upgraded since the credential-store migration. Split the goreleaser build: darwin builds with CGO_ENABLED=1 (fully-keyed per-arch CC overrides) on a pinned macos-15 runner; linux/windows stay CGO-off static (their backends are pure Go; cgo there would regress glibc portability). Verify before publish: `goreleaser check`, snapshot build, then a pre-publish gate that proves the darwin binaries carry the Keychain backend (arm64 functional config-show check; amd64 Security.framework link check) and that both darwin archives exist exactly once — a backend-less darwin binary can never be published silently. Harden the Homebrew checksum step against empty SHAs. No Go source change. Both macOS arches (Intel + Apple Silicon) still produced. Closes #163
|
Findings
The PR adheres to the converged INT-446 plan. The diff is scoped to The pre-publish gate is sound: snapshot build happens before publish, artifact lookup uses |
Problem
Released
slckmacOS binaries fail closed on every credential op..goreleaser.yamlsetCGO_ENABLED=0and the release job ran onubuntu-latest;99designs/keyring's Keychain backend is//go:build darwin && cgo, so with cgo off it was never compiled in. On macOScredstoreauto-selects the Keychain backend thenkeyring.OpenreturnsErrNoAvailImpl→ fail-closed. Every Mac user who upgraded since the credstore migration (#158) is broken. Verified macOS-only (Windows wincred and Linux godbus secret-service are pure Go, fine underCGO_ENABLED=0).Fix (pipeline-only — no Go source change)
.goreleaser.yaml: split builds —slck-darwin(CGO_ENABLED=1, fully-keyed per-archCC=xcrun clang -arch …overrides fordarwin_amd64_v1/darwin_arm64_v8.0) +slck-unix-win(CGO_ENABLED=0static).nfpms.ids: [slck-unix-win](not the deprecatedbuilds). Both macOS arches (Intel + Apple Silicon) still produced — the split is by GOOS, not arch.release.yml: goreleaser job → pinnedmacos-15(cgo+darwin can't cross-compile from Linux). Restructured to verify before publish:goreleaser check→release --snapshot(no publish) → pre-publish gate → realrelease --clean --release-notes. The gate parsesdist/artifacts.jsonand asserts: arm64 binary functionally reportsbackend=keychain backend_source=auto credential_ref=slack-chat-api/default(isolated HOME/XDG,-u SLACK_CHAT_API_KEYRING_BACKEND); amd64 binary linksSecurity.framework(necessary cgo signal for the slice the runner can't execute); both darwin archives present exactly once. A backend-less darwin binary can no longer be published silently.update-homebrewchecksum step (set -euo pipefail+ non-empty SHA assertions) so a renamed/missing archive can't publish a broken cask.Non-goals
workflow_dispatchTAG: github.ref_name || inputs.tagbug is out of scope (only affects the dispatch path; this fix uses the tag-push path) — separate ticket.Validation
goreleaser checkpasses; both cgo cross-builds succeed locally (arm64 native + amd64 cross, correct Mach-O archs, amd64 links Security.framework); the gate's functional assertion reproduced on real hardware (backend=keychain/auto).Release mechanics
auto-release.ymlGate-1 is a path filter (**.go|go.mod|go.sum); a pipeline-only diff matches none, so this is aci:commit that does not auto-release. After merge the corrected release is cut by a deliberate annotated tag push (release.ymlon: push: tags: v*).Pilot for the cross-CLI CGO regression (Jira INT-446, child of INT-310); verified on a non-dev Mac before any fan-out to nrq/gro/atlassian.
Closes #163