|
| 1 | +# macOS Code Signing Fix - v1.6.0 Release |
| 2 | + |
| 3 | +## Problem Summary |
| 4 | + |
| 5 | +The v1.6.0 release workflow failed at the macOS code signing step with the error: |
| 6 | + |
| 7 | +``` |
| 8 | +Developer ID Application: ***: no identity found |
| 9 | +``` |
| 10 | + |
| 11 | +## Root Cause |
| 12 | + |
| 13 | +**Location:** `.github/workflows/release.yml:290` |
| 14 | + |
| 15 | +The workflow was constructing the certificate identity string incorrectly: |
| 16 | + |
| 17 | +```yaml |
| 18 | +codesign --sign "Developer ID Application: ${{ secrets.APPLE_TEAM_ID }}" |
| 19 | +``` |
| 20 | +
|
| 21 | +### What Went Wrong |
| 22 | +
|
| 23 | +- The `APPLE_TEAM_ID` secret contains only the Team ID (format: `ABC123XYZ`) |
| 24 | +- The workflow was prepending "Developer ID Application: " to create `"Developer ID Application: ABC123XYZ"` |
| 25 | +- But the actual certificate name in the keychain is `"Developer ID Application: Your Name (ABC123XYZ)"` |
| 26 | +- Codesign couldn't find a match, resulting in "no identity found" |
| 27 | + |
| 28 | +### Certificate Import Was Successful |
| 29 | + |
| 30 | +The certificate **was successfully imported** into the keychain (verified by logs showing "Imported Private Key"). The problem was purely in how we were referencing it. |
| 31 | + |
| 32 | +## The Fix |
| 33 | + |
| 34 | +Added a new step to automatically discover the certificate's actual name from the keychain: |
| 35 | + |
| 36 | +```yaml |
| 37 | +- name: Find certificate identity |
| 38 | + run: | |
| 39 | + echo "=== Listing available signing identities ===" |
| 40 | + security find-identity -v -p codesigning signing_temp.keychain |
| 41 | +
|
| 42 | + # Extract the full certificate name (between quotes) |
| 43 | + IDENTITY=$(security find-identity -v -p codesigning signing_temp.keychain | grep "Developer ID Application" | head -1 | awk -F'"' '{print $2}') |
| 44 | +
|
| 45 | + if [ -z "$IDENTITY" ]; then |
| 46 | + echo "ERROR: No Developer ID Application certificate found!" |
| 47 | + exit 1 |
| 48 | + fi |
| 49 | +
|
| 50 | + echo "Found identity: $IDENTITY" |
| 51 | + echo "CERT_IDENTITY=$IDENTITY" >> $GITHUB_ENV |
| 52 | +``` |
| 53 | + |
| 54 | +Then updated all `codesign` commands to use the discovered identity: |
| 55 | + |
| 56 | +```yaml |
| 57 | +codesign --sign "$CERT_IDENTITY" \ |
| 58 | +``` |
| 59 | + |
| 60 | +## Changes Made |
| 61 | + |
| 62 | +### Files Modified |
| 63 | +- `.github/workflows/release.yml` |
| 64 | + |
| 65 | +### Steps Updated |
| 66 | +1. **New step:** "Find certificate identity" - Discovers the actual certificate name |
| 67 | +2. **Updated:** "Sign the binary" - Uses `$CERT_IDENTITY` instead of hardcoded string |
| 68 | +3. **Updated:** "Sign ONNX Runtime library" - Uses `$CERT_IDENTITY` |
| 69 | +4. **Updated:** "Sign DMG" - Uses `$CERT_IDENTITY` |
| 70 | + |
| 71 | +### Not Changed |
| 72 | +- `notarytool` commands still use `--team-id "${{ secrets.APPLE_TEAM_ID }}"` - This is correct! |
| 73 | +- The notarytool command expects the raw Team ID, not the certificate name. |
| 74 | + |
| 75 | +## GitHub Secrets Configuration |
| 76 | + |
| 77 | +The following secrets are required and appear to be correctly configured: |
| 78 | + |
| 79 | +| Secret Name | Purpose | Format | |
| 80 | +|-------------|---------|--------| |
| 81 | +| `APPLE_CERTIFICATE_BASE64` | Base64-encoded .p12 certificate file | Base64 string | |
| 82 | +| `APPLE_CERTIFICATE_PASSWORD` | Password for the .p12 certificate | Plain text | |
| 83 | +| `APPLE_TEAM_ID` | Apple Developer Team ID | 10-character alphanumeric (e.g., `ABC123XYZ`) | |
| 84 | +| `APPLE_ID` | Apple ID email for notarization | Email address | |
| 85 | +| `APPLE_APP_SPECIFIC_PASSWORD` | App-specific password for notarization | Generated password | |
| 86 | + |
| 87 | +### How to Get These Values |
| 88 | + |
| 89 | +1. **APPLE_CERTIFICATE_BASE64**: |
| 90 | + ```bash |
| 91 | + base64 -i YourCertificate.p12 -o certificate.txt |
| 92 | + ``` |
| 93 | + |
| 94 | +2. **APPLE_CERTIFICATE_PASSWORD**: The password you set when exporting the certificate from Keychain Access |
| 95 | + |
| 96 | +3. **APPLE_TEAM_ID**: Found in Apple Developer Account → Membership details |
| 97 | + |
| 98 | +4. **APPLE_ID**: Your Apple ID email (must be in the Developer team) |
| 99 | + |
| 100 | +5. **APPLE_APP_SPECIFIC_PASSWORD**: Generated at https://appleid.apple.com/account/manage → App-Specific Passwords |
| 101 | + |
| 102 | +## Testing the Fix |
| 103 | + |
| 104 | +### Option 1: Re-run the Failed Workflow |
| 105 | + |
| 106 | +The easiest way to test: |
| 107 | + |
| 108 | +```bash |
| 109 | +gh run rerun 22037479561 --failed |
| 110 | +``` |
| 111 | + |
| 112 | +This will re-run only the failed "Sign & Notarize macOS" job. |
| 113 | + |
| 114 | +### Option 2: Create a New Test Tag |
| 115 | + |
| 116 | +Create a test release to verify the entire workflow: |
| 117 | + |
| 118 | +```bash |
| 119 | +git tag -a v1.6.0-test -m "Test macOS signing fix" |
| 120 | +git push origin v1.6.0-test |
| 121 | +gh run watch |
| 122 | +``` |
| 123 | + |
| 124 | +Then delete the test tag and release when confirmed working: |
| 125 | + |
| 126 | +```bash |
| 127 | +gh release delete v1.6.0-test --yes |
| 128 | +git tag -d v1.6.0-test |
| 129 | +git push origin :refs/tags/v1.6.0-test |
| 130 | +``` |
| 131 | + |
| 132 | +### Option 3: Trigger Manual Workflow Run |
| 133 | + |
| 134 | +If the workflow has `workflow_dispatch` enabled, you can trigger it manually. |
| 135 | + |
| 136 | +## Expected Workflow Output |
| 137 | + |
| 138 | +After the fix, you should see: |
| 139 | + |
| 140 | +``` |
| 141 | +=== Listing available signing identities === |
| 142 | + 1) ABC123... "Developer ID Application: Your Name (ABC123XYZ)" (CSSMERR_TP_CERT_REVOKED) |
| 143 | +Found identity: Developer ID Application: Your Name (ABC123XYZ) |
| 144 | +=== Signing binary === |
| 145 | +Using identity: Developer ID Application: Your Name (ABC123XYZ) |
| 146 | +unsigned/birda: signed bundle with Mach-O thin (arm64) [com.example.birda] |
| 147 | +``` |
| 148 | + |
| 149 | +## Next Steps |
| 150 | + |
| 151 | +1. **Commit and push the fix:** |
| 152 | + ```bash |
| 153 | + git add .github/workflows/release.yml |
| 154 | + git commit -m "fix: correct macOS code signing identity detection" |
| 155 | + git push origin main |
| 156 | + ``` |
| 157 | + |
| 158 | +2. **Re-run the v1.6.0 release workflow:** |
| 159 | + ```bash |
| 160 | + gh run rerun 22037479561 --failed |
| 161 | + ``` |
| 162 | + |
| 163 | +3. **Monitor the workflow:** |
| 164 | + ```bash |
| 165 | + gh run watch |
| 166 | + ``` |
| 167 | + |
| 168 | +4. **If successful**, the release will be created automatically with all artifacts including the signed macOS DMG. |
| 169 | + |
| 170 | +## Additional Notes |
| 171 | + |
| 172 | +- The fix is backward compatible and won't affect other jobs |
| 173 | +- The discovery method is more robust than hardcoding the identity |
| 174 | +- If multiple Developer ID certificates exist, it uses the first one found |
| 175 | +- The `APPLE_TEAM_ID` secret is still needed for the notarytool commands |
| 176 | + |
| 177 | +## Troubleshooting |
| 178 | + |
| 179 | +If the workflow still fails: |
| 180 | + |
| 181 | +1. **Check certificate validity:** |
| 182 | + ```bash |
| 183 | + # Locally test the certificate |
| 184 | + openssl pkcs12 -info -in YourCertificate.p12 |
| 185 | + ``` |
| 186 | + |
| 187 | +2. **Verify the certificate is a "Developer ID Application" certificate**, not: |
| 188 | + - Developer ID Installer |
| 189 | + - Mac App Distribution |
| 190 | + - Mac Installer Distribution |
| 191 | + |
| 192 | +3. **Check certificate expiration** in Apple Developer Console |
| 193 | + |
| 194 | +4. **Ensure the certificate includes the private key** when exported from Keychain Access |
0 commit comments