Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 20 additions & 6 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -89,13 +89,13 @@ jobs:
MACOS_CERTIFICATE_PWD: ${{ secrets.MACOS_CERTIFICATE_PWD }}
MACOS_KEYCHAIN_PWD: ${{ secrets.MACOS_KEYCHAIN_PWD }}
EXPECTED_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
REQUIRE_DEVELOPER_ID: ${{ github.event_name == 'push' || inputs.publish }}
REQUIRE_SIGNED_RELEASE: ${{ github.event_name == 'push' || inputs.publish }}
run: |
set -euo pipefail

fallback_to_adhoc() {
local reason="$1"
if [ "$REQUIRE_DEVELOPER_ID" = "true" ]; then
if [ "$REQUIRE_SIGNED_RELEASE" = "true" ]; then
echo "ERROR: $reason" >&2
exit 1
fi
Expand All @@ -104,7 +104,7 @@ jobs:
echo "mode=adhoc" >> "$GITHUB_OUTPUT"
}

if [ "$REQUIRE_DEVELOPER_ID" = "true" ] && [ -z "$EXPECTED_TEAM_ID" ]; then
if [ "$REQUIRE_SIGNED_RELEASE" = "true" ] && [ -z "$EXPECTED_TEAM_ID" ]; then
echo "ERROR: APPLE_TEAM_ID is required for public release signing." >&2
exit 1
fi
Expand Down Expand Up @@ -164,15 +164,15 @@ jobs:

APPLE_DEVELOPMENT=$(security find-identity -v -p codesigning "$KEYCHAIN_PATH" 2>/dev/null \
| awk '/Apple Development/ { print $2; exit }' || true)
if [ -n "$APPLE_DEVELOPMENT" ] && [ "$REQUIRE_DEVELOPER_ID" != "true" ]; then
if [ -n "$APPLE_DEVELOPMENT" ]; then

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Filter Apple Development identities by team

When APPLE_TEAM_ID is set (mandatory for push/publish releases) and the imported PKCS#12 contains multiple Apple Development identities, the security find-identity pipeline above keeps the first one and this changed condition accepts it without checking the team. The later TeamIdentifier validation then fails after the full build even if a matching development identity exists later in the same keychain, so release success depends on export order; filter Apple Development identities by EXPECTED_TEAM_ID like the Developer ID path.

Useful? React with 👍 / 👎.

echo "::add-mask::$APPLE_DEVELOPMENT"
echo "::warning::Using Apple Development signing; this build will not be notarized."
echo "::warning::Using Apple Development signing; this release will not be notarized."
Comment on lines +167 to +169

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Block public Apple Development releases

When this branch is taken for a tag push or publish=true run, the workflow now continues to the GitHub release and stable Homebrew cask publishing steps even though the artifact is only Apple Development-signed and explicitly not notarized. Apple’s distribution guidance says Mac apps distributed outside the Mac App Store need Developer ID signing/notarization for Gatekeeper, so this scenario publishes a ZIP that normal Homebrew/GitHub users cannot launch without disabling Gatekeeper; keep Apple Development signing limited to non-published validation builds or do not publish the cask/release from this path. See https://help.apple.com/xcode/mac/current/en.lproj/dev033e997ca.html

Useful? React with 👍 / 👎.

echo "identity=$APPLE_DEVELOPMENT" >> "$GITHUB_OUTPUT"
echo "mode=development" >> "$GITHUB_OUTPUT"
exit 0
fi

fallback_to_adhoc "The imported keychain has no usable Developer ID Application identity."
fallback_to_adhoc "The imported keychain has no usable Developer ID Application or Apple Development identity."

- name: Build and sign release app
id: app
Expand All @@ -183,6 +183,7 @@ jobs:
OPEN_IN_CODE_SIGNING: unsigned
SIGNING_IDENTITY: ${{ steps.signing.outputs.identity }}
SIGNING_MODE: ${{ steps.signing.outputs.mode }}
EXPECTED_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
run: |
set -euo pipefail

Expand Down Expand Up @@ -221,6 +222,19 @@ jobs:
ENTITLEMENTS=$(codesign -d --entitlements :- "$APP_PATH" 2>/dev/null)
grep -F 'com.apple.security.automation.apple-events' <<< "$ENTITLEMENTS" >/dev/null

if [ "$SIGNING_MODE" != "adhoc" ]; then
SIGNED_TEAM_ID=$(codesign -dvv "$APP_PATH" 2>&1 \
| sed -n 's/^TeamIdentifier=//p')
if [ -z "$SIGNED_TEAM_ID" ]; then
echo "Signed app has no team identifier." >&2
exit 1
fi
if [ -n "$EXPECTED_TEAM_ID" ] && [ "$SIGNED_TEAM_ID" != "$EXPECTED_TEAM_ID" ]; then
echo "Signed app team ID '$SIGNED_TEAM_ID' does not match APPLE_TEAM_ID '$EXPECTED_TEAM_ID'." >&2
exit 1
fi
fi

echo "path=$APP_PATH" >> "$GITHUB_OUTPUT"

- name: Notarize Developer ID app
Expand Down