fix: deep-sign embedded controller binary before outer app signing #44
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: release | |
| on: | |
| workflow_dispatch: | |
| push: | |
| branches: | |
| - "main" | |
| tags: | |
| - "v*" | |
| paths: | |
| - "VERSION" | |
| - "README.md" | |
| - "CHANGELOG.md" | |
| - "project.yml" | |
| - ".github/workflows/release.yml" | |
| - "Scripts/build-app.sh" | |
| - "Scripts/build-dmg.sh" | |
| - "Scripts/build-xcode-app.sh" | |
| - "Scripts/release-preflight.sh" | |
| - "Scripts/sign-and-notarize-dmg.sh" | |
| - "Scripts/verify-distribution.sh" | |
| - "Scripts/verify-installed-app.sh" | |
| - "Scripts/verify-privacy.sh" | |
| - "Scripts/bump-version.py" | |
| jobs: | |
| build-release: | |
| runs-on: macos-14 | |
| permissions: | |
| contents: write | |
| steps: | |
| - name: Check out repository | |
| uses: actions/checkout@v5 | |
| with: | |
| fetch-depth: 0 | |
| - name: Resolve release target | |
| id: release_meta | |
| env: | |
| BEFORE_SHA: ${{ github.event.before }} | |
| REF_TYPE: ${{ github.ref_type }} | |
| run: | | |
| VERSION="$(tr -d '[:space:]' < VERSION)" | |
| TAG="v$VERSION" | |
| SHOULD_RELEASE="true" | |
| REASON="manual dispatch or tag push" | |
| if [ "${GITHUB_EVENT_NAME}" = "push" ] && [ "${REF_TYPE}" != "tag" ]; then | |
| REASON="VERSION changed on main" | |
| if [ -n "${BEFORE_SHA:-}" ] && [ "${BEFORE_SHA}" != "0000000000000000000000000000000000000000" ] && git diff --quiet "$BEFORE_SHA" "$GITHUB_SHA" -- VERSION; then | |
| SHOULD_RELEASE="false" | |
| REASON="VERSION unchanged on branch push" | |
| fi | |
| fi | |
| echo "version=$VERSION" >> "$GITHUB_OUTPUT" | |
| echo "tag=$TAG" >> "$GITHUB_OUTPUT" | |
| echo "should_release=$SHOULD_RELEASE" >> "$GITHUB_OUTPUT" | |
| echo "reason=$REASON" >> "$GITHUB_OUTPUT" | |
| echo "Release decision: $SHOULD_RELEASE ($REASON)" | |
| - name: Select latest Xcode | |
| if: steps.release_meta.outputs.should_release == 'true' | |
| run: | | |
| latest_xcode="$(ls -d /Applications/Xcode*.app | sort -V | tail -n 1)" | |
| sudo xcode-select -s "$latest_xcode/Contents/Developer" | |
| xcodebuild -version | |
| - name: Install xcodegen | |
| if: steps.release_meta.outputs.should_release == 'true' | |
| run: brew install xcodegen | |
| - name: Run release preflight | |
| if: steps.release_meta.outputs.should_release == 'true' | |
| env: | |
| MSW_PREFLIGHT_SKIP_BUILDS: "1" | |
| run: | | |
| chmod +x Scripts/*.sh | |
| ./Scripts/release-preflight.sh | |
| - name: Prepare temporary keychain | |
| if: steps.release_meta.outputs.should_release == 'true' | |
| env: | |
| APPLE_CERTIFICATE_P12_BASE64: ${{ secrets.APPLE_CERTIFICATE_P12_BASE64 }} | |
| APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }} | |
| run: | | |
| if [ -z "${APPLE_CERTIFICATE_P12_BASE64}" ] || [ -z "${APPLE_CERTIFICATE_PASSWORD}" ]; then | |
| echo "missing signing certificate secrets" >&2 | |
| exit 1 | |
| fi | |
| KEYCHAIN_PASSWORD="$(openssl rand -base64 24)" | |
| echo "KEYCHAIN_PASSWORD=$KEYCHAIN_PASSWORD" >> "$GITHUB_ENV" | |
| echo "KEYCHAIN_PATH=$RUNNER_TEMP/modelswitchboard.keychain-db" >> "$GITHUB_ENV" | |
| security create-keychain -p "$KEYCHAIN_PASSWORD" "$RUNNER_TEMP/modelswitchboard.keychain-db" | |
| security set-keychain-settings -lut 21600 "$RUNNER_TEMP/modelswitchboard.keychain-db" | |
| security unlock-keychain -p "$KEYCHAIN_PASSWORD" "$RUNNER_TEMP/modelswitchboard.keychain-db" | |
| echo "$APPLE_CERTIFICATE_P12_BASE64" | base64 --decode > "$RUNNER_TEMP/developer-id.p12" | |
| security import "$RUNNER_TEMP/developer-id.p12" \ | |
| -k "$RUNNER_TEMP/modelswitchboard.keychain-db" \ | |
| -P "$APPLE_CERTIFICATE_PASSWORD" \ | |
| -T /usr/bin/codesign \ | |
| -T /usr/bin/security | |
| security list-keychains -d user -s "$RUNNER_TEMP/modelswitchboard.keychain-db" login.keychain-db | |
| security set-key-partition-list -S apple-tool:,apple: -k "$KEYCHAIN_PASSWORD" "$RUNNER_TEMP/modelswitchboard.keychain-db" | |
| - name: Write App Store Connect API key | |
| if: steps.release_meta.outputs.should_release == 'true' | |
| env: | |
| APPLE_NOTARY_API_KEY_P8_BASE64: ${{ secrets.APPLE_NOTARY_API_KEY_P8_BASE64 }} | |
| run: | | |
| if [ -z "${APPLE_NOTARY_API_KEY_P8_BASE64}" ]; then | |
| echo "missing notary API key secret" >&2 | |
| exit 1 | |
| fi | |
| API_KEY_PATH="$RUNNER_TEMP/AuthKey.p8" | |
| echo "$APPLE_NOTARY_API_KEY_P8_BASE64" | base64 --decode > "$API_KEY_PATH" | |
| echo "APPLE_NOTARY_API_KEY_PATH=$API_KEY_PATH" >> "$GITHUB_ENV" | |
| - name: Build, sign, and notarize DMGs | |
| if: steps.release_meta.outputs.should_release == 'true' | |
| env: | |
| APPLE_DEVELOPER_IDENTITY: ${{ secrets.APPLE_DEVELOPER_IDENTITY }} | |
| APPLE_NOTARY_API_KEY_PATH: ${{ env.APPLE_NOTARY_API_KEY_PATH }} | |
| APPLE_NOTARY_API_KEY_ID: ${{ secrets.APPLE_NOTARY_API_KEY_ID }} | |
| APPLE_NOTARY_API_ISSUER_ID: ${{ secrets.APPLE_NOTARY_API_ISSUER_ID }} | |
| run: | | |
| chmod +x Scripts/*.sh | |
| for variant in base plus; do | |
| APP_VARIANT="$variant" ./Scripts/sign-and-notarize-dmg.sh | |
| APP_VARIANT="$variant" ./Scripts/verify-distribution.sh | |
| done | |
| shasum -a 256 "dist/Model-Switchboard-$(tr -d '[:space:]' < VERSION).dmg" > "dist/Model-Switchboard-$(tr -d '[:space:]' < VERSION).dmg.sha256" | |
| shasum -a 256 "dist/Model-Switchboard-Plus-$(tr -d '[:space:]' < VERSION).dmg" > "dist/Model-Switchboard-Plus-$(tr -d '[:space:]' < VERSION).dmg.sha256" | |
| - name: Upload release assets | |
| if: steps.release_meta.outputs.should_release == 'true' | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| RELEASE_TAG: ${{ steps.release_meta.outputs.tag }} | |
| RELEASE_VERSION: ${{ steps.release_meta.outputs.version }} | |
| REF_TYPE: ${{ github.ref_type }} | |
| run: | | |
| VERSION="$RELEASE_VERSION" | |
| TAG="$RELEASE_TAG" | |
| FILES=( | |
| "dist/Model-Switchboard-$VERSION.dmg" | |
| "dist/Model-Switchboard-Plus-$VERSION.dmg" | |
| "dist/Model-Switchboard-$VERSION.dmg.sha256" | |
| "dist/Model-Switchboard-Plus-$VERSION.dmg.sha256" | |
| ) | |
| for file in "${FILES[@]}"; do | |
| if [ ! -f "$file" ]; then | |
| echo "missing release artifact: $file" >&2 | |
| exit 1 | |
| fi | |
| done | |
| if gh release view "$TAG" >/dev/null 2>&1; then | |
| gh release upload "$TAG" "${FILES[@]}" --clobber | |
| else | |
| CREATE_ARGS=("$TAG" "${FILES[@]}" --title "$TAG" --generate-notes) | |
| if [ "$REF_TYPE" != "tag" ]; then | |
| CREATE_ARGS+=(--target "$GITHUB_SHA") | |
| fi | |
| gh release create "${CREATE_ARGS[@]}" | |
| fi |