diff --git a/.github/actions/import-macos-cert/action.yml b/.github/actions/import-macos-cert/action.yml index c2808293d2..223d2c317a 100644 --- a/.github/actions/import-macos-cert/action.yml +++ b/.github/actions/import-macos-cert/action.yml @@ -24,6 +24,15 @@ outputs: Compose's macOS signing, whose certificate lookup doesn't resolve the search list reliably on CI runners the way bare `codesign` does. value: ${{ steps.import.outputs.keychain }} + identity: + description: > + The imported certificate's full "Developer ID Application: NAME (TEAMID)" + common name, resolved from the keychain (empty when signing=false or if it + could not be parsed). `codesign` accepts a SHA-1 hash or a CN substring, + but Compose's MacSigner runs `security find-certificate -c ` + after prepending "Developer ID Application: " — so it only works with the + exact common name. Feed this to Compose's `signing.identity`. + value: ${{ steps.import.outputs.identity }} runs: using: composite @@ -62,5 +71,20 @@ runs: # explicit keychain can read the `keychain` output below. security default-keychain -d user -s "$KEYCHAIN" rm -f "$CERT_PATH" + # Resolve the certificate's exact common name. Compose's MacSigner maps + # its identity to a cert via `security find-certificate -c ` (after + # prepending "Developer ID Application: " when absent), so it needs the + # full CN — a SHA-1 hash or partial name in the secret signs fine with + # bare `codesign` but yields "Could not find certificate ...". Pull the + # canonical name straight from the keychain so the caller is independent + # of whatever form the MAC_SIGN_IDENTITY secret takes. + IDENTITY_NAME="$(security find-identity -v -p codesigning "$KEYCHAIN" \ + | grep -o '"Developer ID Application:[^"]*"' | head -1 | tr -d '"' || true)" echo "signing=true" >> "$GITHUB_OUTPUT" echo "keychain=$KEYCHAIN" >> "$GITHUB_OUTPUT" + echo "identity=$IDENTITY_NAME" >> "$GITHUB_OUTPUT" + if [[ -n "$IDENTITY_NAME" ]]; then + echo "::notice::Resolved signing identity: $IDENTITY_NAME" + else + echo "::warning::Could not resolve a 'Developer ID Application' identity from the keychain; callers will fall back to the MAC_SIGN_IDENTITY secret." + fi diff --git a/.github/workflows/create-release.yml b/.github/workflows/create-release.yml index cc99337105..93e647773e 100644 --- a/.github/workflows/create-release.yml +++ b/.github/workflows/create-release.yml @@ -119,8 +119,13 @@ jobs: env: # Empty on non-macOS legs and on the macOS leg when no cert is # configured — the gradle macOS{} block skips signing when the - # identity is blank. - AMETHYST_MAC_SIGN_IDENTITY: ${{ steps.mac_keychain.outputs.signing == 'true' && secrets.MAC_SIGN_IDENTITY || '' }} + # identity is blank. Prefer the full common name resolved from the + # keychain over the raw secret: Compose's signer maps the identity via + # `security find-certificate` and only matches the exact "Developer ID + # Application: …" CN, whereas the secret may be a hash or partial name + # (which bare codesign accepts but Compose does not). Fall back to the + # secret if resolution failed. + AMETHYST_MAC_SIGN_IDENTITY: ${{ steps.mac_keychain.outputs.signing == 'true' && (steps.mac_keychain.outputs.identity || secrets.MAC_SIGN_IDENTITY) || '' }} # Explicit keychain for Compose's MacSigner. Its `security # find-certificate` lookup doesn't resolve the imported cert via the # search list on these runners ("Could not find certificate ... in