Skip to content

Commit 12f7fc9

Browse files
committed
Try again?
1 parent 0ad52ad commit 12f7fc9

File tree

1 file changed

+69
-45
lines changed

1 file changed

+69
-45
lines changed

projects/macos/ecode/sign.sh

Lines changed: 69 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -7,21 +7,15 @@ DIRPATH="$(dirname "$CANONPATH")"
77
cd "$DIRPATH" || exit
88

99
# This script handles code signing and notarization for the macOS app.
10-
# It's designed to be called from the CI environment.
11-
#
1210
# It expects the following environment variables to be set for real signing:
1311
# - MACOS_CERTIFICATE_P12_B64: The base64 encoded .p12 certificate.
1412
# - MACOS_CERTIFICATE_PASSWORD: The password for the .p12 certificate.
1513
# - MACOS_APPLE_ID: Your Apple ID email used for notarization.
1614
# - MACOS_NOTARIZATION_PASSWORD: An app-specific password for your Apple ID.
1715
# - MACOS_TEAM_ID: Your Apple Developer Team ID.
18-
#
19-
# If these variables are not set, it will fall back to ad-hoc (self) signing for .app bundles
20-
# and skip notarization for .dmg files.
2116

2217
# The first argument is the path to the artifact, relative to this script's location.
2318
ARTIFACT_PATH="$1"
24-
# The entitlements file is in the same directory as this script.
2519
ENTITLEMENTS_PATH="entitlements.plist"
2620

2721
if [[ -z "$ARTIFACT_PATH" ]]; then
@@ -38,12 +32,10 @@ fi
3832
if [[ -z "$MACOS_CERTIFICATE_P12_B64" ]]; then
3933
if [[ "$ARTIFACT_PATH" == *.app ]]; then
4034
echo "No signing certificate found. Performing ad-hoc signing..."
41-
# Find and sign all binaries within the app bundle
4235
find "$ARTIFACT_PATH/Contents/MacOS/" -type f -exec codesign --force --sign - {} \;
4336
codesign --force --sign - "$ARTIFACT_PATH"
4437
echo "Ad-hoc signing complete."
4538
fi
46-
# For .dmg files, we just skip if no credentials
4739
exit 0
4840
fi
4941

@@ -54,25 +46,54 @@ KEYCHAIN_NAME="build.keychain"
5446
KEYCHAIN_PASSWORD="a-very-secure-password"
5547
CERTIFICATE_P12_PATH="certificate.p12"
5648

57-
# Decode the certificate
58-
echo "$MACOS_CERTIFICATE_P12_B64" | base64 --decode > "$CERTIFICATE_P12_PATH"
49+
# Check if keychain already exists
50+
if [[ -f "$HOME/Library/Keychains/$KEYCHAIN_NAME-db" ]]; then
51+
echo "Keychain $KEYCHAIN_NAME already exists. Reusing it..."
52+
security unlock-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN_NAME"
53+
else
54+
echo "Creating temporary keychain: $KEYCHAIN_NAME"
55+
security create-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN_NAME"
56+
security default-keychain -s "$KEYCHAIN_NAME"
57+
security set-keychain-settings -t 3600 -u "$KEYCHAIN_NAME"
58+
59+
# Decode and import the certificate
60+
echo "Decoding certificate..."
61+
echo "$MACOS_CERTIFICATE_P12_B64" | base64 --decode > "$CERTIFICATE_P12_PATH"
62+
if [[ ! -s "$CERTIFICATE_P12_PATH" ]]; then
63+
echo "Error: Certificate file is empty or invalid."
64+
exit 1
65+
fi
5966

60-
# Create a temporary keychain
61-
security create-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN_NAME"
62-
security default-keychain -s "$KEYCHAIN_NAME"
63-
security unlock-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN_NAME"
64-
security set-keychain-settings -t 3600 -u "$KEYCHAIN_NAME"
67+
echo "Importing certificate into keychain..."
68+
security import "$CERTIFICATE_P12_PATH" -k "$KEYCHAIN_NAME" -P "$MACOS_CERTIFICATE_PASSWORD" -T /usr/bin/codesign -T /usr/bin/security
69+
if [[ $? -ne 0 ]]; then
70+
echo "Error: Failed to import certificate."
71+
exit 1
72+
fi
6573

66-
# Import the certificate into the keychain
67-
security import "$CERTIFICATE_P12_PATH" -k "$KEYCHAIN_NAME" -P "$MACOS_CERTIFICATE_PASSWORD" -T /usr/bin/codesign -T /usr/bin/security
74+
# Allow codesign access
75+
echo "Setting keychain partition list..."
76+
security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k "$KEYCHAIN_PASSWORD" "$KEYCHAIN_NAME" > /dev/null
77+
if [[ $? -ne 0 ]]; then
78+
echo "Error: Failed to set keychain partition list."
79+
exit 1
80+
fi
81+
fi
6882

69-
# Allow codesign to access the certificate
70-
security set-key-partition-list -S apple-tool:,apple: -s -k "$KEYCHAIN_PASSWORD" "$KEYCHAIN_NAME" > /dev/null
83+
# Debug: List certificates
84+
echo "Listing certificates in keychain for debugging..."
85+
security find-certificate -a -p "$KEYCHAIN_NAME"
86+
87+
# Ensure keychain is unlocked
88+
echo "Ensuring keychain is unlocked..."
89+
security unlock-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN_NAME"
7190

7291
# Find the signing identity
92+
echo "Searching for signing identity..."
7393
SIGNING_IDENTITY=$(security find-identity -v -p codesigning "$KEYCHAIN_NAME" | grep "Developer ID Application" | head -n 1 | awk -F '"' '{print $2}')
7494
if [[ -z "$SIGNING_IDENTITY" ]]; then
75-
echo "Error: Signing identity not found in keychain."
95+
echo "Error: No Developer ID Application signing identity found."
96+
security find-identity -v -p codesigning "$KEYCHAIN_NAME"
7697
exit 1
7798
fi
7899
echo "Using signing identity: $SIGNING_IDENTITY"
@@ -82,26 +103,23 @@ echo "Using signing identity: $SIGNING_IDENTITY"
82103
# Function to sign the .app bundle
83104
sign_app() {
84105
echo "Signing application bundle at: $ARTIFACT_PATH"
85-
# Sign all dylibs, frameworks and executables from the inside out
86106
find "$ARTIFACT_PATH" -depth -name "*.dylib" -o -name "*.framework" -o -path "$ARTIFACT_PATH/Contents/MacOS/*" -type f | while read -r comp; do
87107
echo "Signing component: $comp"
88-
codesign --force --verify --verbose --sign "$SIGNING_IDENTITY" --options runtime --timestamp "$comp"
108+
codesign --force --verbose --sign "$SIGNING_IDENTITY" --options runtime --timestamp "$comp"
89109
done
90110

91111
echo "Signing main application bundle with entitlements..."
92-
codesign --force --verify --verbose --sign "$SIGNING_IDENTITY" --entitlements "$ENTITLEMENTS_PATH" --options runtime --timestamp "$ARTIFACT_PATH"
112+
codesign --force --verbose --sign "$SIGNING_IDENTITY" --entitlements "$ENTITLEMENTS_PATH" --options runtime --timestamp "$ARTIFACT_PATH"
93113
echo "App signing complete."
94114

95-
# Notarize the app: Zip it first (Apple recommends zipping apps for submission)
115+
# Notarize the app
96116
ZIP_PATH="${ARTIFACT_PATH%.*}.zip"
97117
echo "Zipping app for notarization: $ZIP_PATH"
98118
ditto -c -k --sequesterRsrc --keepParent "$ARTIFACT_PATH" "$ZIP_PATH"
99119

100-
# Temporary file to store the command's output
101120
local notary_output_file
102121
notary_output_file=$(mktemp)
103122

104-
# Submit for notarization
105123
echo "Notarizing app zip..."
106124
if ! xcrun notarytool submit "$ZIP_PATH" \
107125
--apple-id "$MACOS_APPLE_ID" \
@@ -128,43 +146,49 @@ sign_app() {
128146
cat "$notary_output_file"
129147
rm "$notary_output_file"
130148

131-
# Staple to the app (not the zip)
132149
echo "Stapling ticket to app..."
133150
xcrun stapler staple "$ARTIFACT_PATH"
134151
echo "App stapling complete."
135152

136-
# Clean up zip
137153
rm -f "$ZIP_PATH"
138154
}
139155

140156
# Function to notarize and staple the .dmg
141157
notarize_dmg() {
142158
echo "Notarizing DMG at: $ARTIFACT_PATH"
143159

144-
# Sign the DMG first (required before notarization)
160+
# Re-verify keychain state
161+
echo "Verifying keychain state before DMG signing..."
162+
security unlock-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN_NAME"
163+
security find-identity -v -p codesigning "$KEYCHAIN_NAME"
164+
165+
# Sign the DMG
145166
echo "Signing DMG..."
146-
codesign --force --verify --verbose --sign "$SIGNING_IDENTITY" --timestamp "$ARTIFACT_PATH"
167+
codesign --force --verbose --sign "$SIGNING_IDENTITY" "$ARTIFACT_PATH"
168+
if [[ $? -ne 0 ]]; then
169+
echo "Error: Failed to sign DMG. Checking keychain state..."
170+
security find-identity -v -p codesigning "$KEYCHAIN_NAME"
171+
exit 1
172+
fi
147173
echo "DMG signing complete."
148174

149-
# Temporary file to store the command's output
175+
# Verify the signature
176+
echo "Verifying DMG signature..."
177+
codesign --verify --verbose "$ARTIFACT_PATH"
178+
179+
# Notarize the DMG
150180
local notary_output_file
151181
notary_output_file=$(mktemp)
152182

153-
# Submit for notarization and check the exit code directly.
154-
# The --wait flag makes the command exit with 0 on success and non-zero on failure.
155-
# We redirect all output to a temp file so we can show it and parse it later.
183+
echo "Notarizing DMG..."
156184
if ! xcrun notarytool submit "$ARTIFACT_PATH" \
157185
--apple-id "$MACOS_APPLE_ID" \
158186
--password "$MACOS_NOTARIZATION_PASSWORD" \
159187
--team-id "$MACOS_TEAM_ID" \
160188
--wait > "$notary_output_file" 2>&1; then
161189

162190
echo "Error: Notarization failed."
163-
# Print the full output from the failed command for debugging
164191
cat "$notary_output_file"
165-
166-
# Attempt to get logs if we can find a UUID.
167-
# Use 'head -n 1' to ensure we only get the first matching line.
168192
REQUEST_UUID=$(grep "id:" "$notary_output_file" | head -n 1 | awk '{print $2}')
169193
if [[ -n "$REQUEST_UUID" ]]; then
170194
echo "Fetching notarization logs for UUID: $REQUEST_UUID"
@@ -177,7 +201,6 @@ notarize_dmg() {
177201
exit 1
178202
fi
179203

180-
# If we reach here, the command succeeded.
181204
echo "Notarization successful. Full log:"
182205
cat "$notary_output_file"
183206
rm "$notary_output_file"
@@ -188,12 +211,13 @@ notarize_dmg() {
188211
}
189212

190213
# --- CLEANUP ---
191-
cleanup() {
192-
echo "Cleaning up..."
193-
security delete-keychain "$KEYCHAIN_NAME" || true
194-
rm -f "$CERTIFICATE_P12_PATH"
195-
}
196-
trap cleanup EXIT
214+
# Note: Cleanup is handled in CI, not here, since this script is called twice
215+
# cleanup() {
216+
# echo "Cleaning up..."
217+
# security delete-keychain "$KEYCHAIN_NAME" || true
218+
# rm -f "$CERTIFICATE_P12_PATH"
219+
# }
220+
# trap cleanup EXIT
197221

198222
# --- EXECUTION ---
199223
if [[ "$ARTIFACT_PATH" == *.app ]]; then

0 commit comments

Comments
 (0)