Build app #538
This file contains 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: Build app | |
on: | |
push: | |
branches: [ main ] | |
pull_request: | |
branches: [ main ] | |
workflow_dispatch: | |
inputs: | |
appStorePublishVersion: | |
description: 'App store version: "MARKETING:FULL"' | |
required: false | |
type: string | |
jobs: | |
build: | |
strategy: | |
matrix: | |
target: [app-store] | |
runs-on: macos-latest | |
steps: | |
- uses: actions/checkout@v2 | |
- name: Set up Python | |
uses: actions/setup-python@v2 | |
with: | |
python-version: "3.10" | |
- name: Check actions to perform | |
run: | | |
set -x | |
if [ -n '${{ secrets.APPLE_ID}}' ] && [ '${{ matrix.target }}' == release ]; then | |
echo "should_notarize_app=yes" >> "$GITHUB_ENV" | |
fi | |
if [[ "${{ github.event_name }}" == 'workflow_dispatch' || "${{ github.ref }}" == 'refs/heads/main' ]]; then | |
echo "should_upload_app=yes" >> "$GITHUB_ENV" | |
fi | |
if [ '${{ matrix.target }}' == release ]; then | |
echo "NAME_QUALIFIER=" >> "$GITHUB_ENV" | |
else | |
echo "NAME_QUALIFIER=-${{ matrix.target }}" >> "$GITHUB_ENV" | |
fi | |
- name: Will notarize | |
if: env.should_notarize_app | |
run: echo "Will notarize app" | |
- name: Will upload | |
if: env.should_upload_app | |
run: echo "Will upload app" | |
- name: Pip install | |
run: | | |
python -m pip install --upgrade pip | |
python -m pip install --upgrade dmgbuild | |
- name: Create temporary keychain | |
run: | | |
set -eu -o pipefail | |
## Create and populate a temporary keychain with our cert. | |
# We need the "Apple Development" one for building, and then "Developer ID" one for notarizing | |
keychain_path="$RUNNER_TEMP/app-signing.keychain-db" | |
keychain_password="$(uuidgen)" | |
security create-keychain -p "$keychain_password" "$keychain_path" | |
security set-keychain-settings -lut 21600 "$keychain_path" | |
security unlock-keychain -p "$keychain_password" "$keychain_path" | |
echo "KEYCHAIN_PATH=$keychain_path" >> "$GITHUB_ENV" | |
- name: Confirm keychain | |
run: | | |
set -eu -o pipefail | |
set -x | |
security list-keychain -d user -s "$KEYCHAIN_PATH" | |
security list-keychain | |
- name: Import build cert | |
run: | | |
set -eu o pipefail | |
certificate_path="$RUNNER_TEMP/build_certificate.p12" | |
echo -n "$BUILD_P12_BASE64" | base64 --decode > "$certificate_path" | |
security import "$certificate_path" -P "$BUILD_P12_PASSPHRASE" -A -t cert -f pkcs12 -k "$KEYCHAIN_PATH" | |
env: | |
BUILD_P12_BASE64: ${{ secrets.BUILD_P12_BASE64 }} # the "Apple Development" one, though "Mac Developer ID" also seems to work (that's what I'm using now) | |
BUILD_P12_PASSPHRASE: ${{ secrets.BUILD_P12_PASSPHRASE }} | |
- name: Import notarization cert | |
run: | | |
set -eu -o pipefail | |
dev_id_certificate_path="$RUNNER_TEMP/build_dev_id.cer" | |
echo -n "$DEV_ID_CERTIFICATE_BASE64" | base64 --decode > "$dev_id_certificate_path" | |
security import "$dev_id_certificate_path" -k "$KEYCHAIN_PATH" | |
env: | |
DEV_ID_CERTIFICATE_BASE64: ${{ secrets.DEV_ID_CERTIFICATE_BASE64 }} # the "Developer ID Application" one | |
- name: Build | |
run: | | |
xcodebuild -scheme "whatdid-${{ matrix.target }}" build archive -archivePath build/whatdid | |
- name: Archive | |
if: env.should_upload_app | |
run: | | |
set -eu -o pipefail | |
/usr/bin/plutil -insert teamID -string "${APPLE_TEAM_ID}" buildscripts/archive-export.plist | |
/usr/bin/plutil -insert signingCertificate -string "${APPLE_SIGNING_CERT_NAME}" buildscripts/archive-export.plist | |
xcodebuild -exportArchive -archivePath build/whatdid.xcarchive -exportPath build -exportOptionsPlist buildscripts/archive-export.plist | |
env: | |
APPLE_SIGNING_CERT_NAME: ${{ secrets.APPLE_SIGNING_CERT_NAME }} | |
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }} | |
- name: Notarize | |
if: env.should_upload_app && env.should_notarize_app | |
run: | | |
cd build | |
ditto -c -k --keepParent Whatdid*.app whatdid.zip | |
mkdir logs | |
mv DistributionSummary.plist Packaging.log logs/ | |
xcrun notarytool store-credentials "AC_PASSWORD" --apple-id "$APPLE_ID" --team-id "$APPLE_TEAM_ID" --password "$APPLE_NOTARYTOOL_PASSWORD" | |
# tee /dev/fd/2 just tees out to stderr -- so we can see the response, but also capture it to a variable | |
notary_submission="$(xcrun notarytool submit whatdid.zip --keychain-profile AC_PASSWORD -f json | tee /dev/fd/2)" | |
echo "$notary_submission" | jq . | |
notary_id="$(echo "$notary_submission" | jq -r .id)" | |
notary_result="$(xcrun notarytool wait "$notary_id" --keychain-profile AC_PASSWORD -f json | tee /dev/fd/2)" | |
if [[ "$(echo "$notary_result" | jq -r .status)" != Accepted ]]; then | |
xcrun notarytool log "$notary_id" --keychain-profile AC_PASSWORD | jq . | |
fi | |
pwd | |
xcrun stapler staple Whatdid.app | |
spctl -vvv --assess --type exec ./Whatdid.app | |
env: | |
APPLE_ID: ${{ secrets.APPLE_ID }} | |
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }} | |
APPLE_NOTARYTOOL_PASSWORD: ${{ secrets.APPLE_NOTARYTOOL_PASSWORD }} | |
- name: Create DMG | |
if: env.should_upload_app | |
run: | | |
app_name="$(cd build; echo *.app)" # "whatdid.app" or "whatdid-app-store.app" | |
dmgbuild -s buildscripts/dmgbuild_settings.py -D "app=build/$app_name" "Whatdid" build/Whatdid.dmg | |
- name: Upload app to GH Action Artifact | |
uses: actions/upload-artifact@v2 | |
if: env.should_upload_app | |
with: | |
name: Whatdid${{ env.NAME_QUALIFIER }}.dmg | |
path: build/Whatdid.dmg | |
- name: Upload app to App Store | |
if: ${{ matrix.target == 'app-store' && inputs.appStorePublishVersion != '' }} | |
run: | | |
cd build | |
marketing_version="$(echo "$APP_STORE_VERSION_STR" | cut -d: -f1)" | |
full_version="$(echo "$APP_STORE_VERSION_STR" | cut -d: -f2)" | |
printf 'Using marketing version <%s> and full version <%s>\n' "$marketing_version" "$full_version" | |
xcrun altool --upload-package Whatdid.app -t osx --apple-id CUJYAXXM6G.com.yuvalshavit.whatdid --bundle-id com.yuvalshavit.whatdid --bundle-short-version-string "$marketing_version" --bundle-version "$full_version" -u "$APPLE_ID" -p '@env:APPLE_NOTARYTOOL_PASSWORD' | |
env: | |
APP_STORE_VERSION_STR: ${{ inputs.appStorePublishVersion }} | |
APPLE_RELEASE_KEY_ISSUER: ${{ secrets.APPLE_RELEASE_KEY_ISSUER }} | |
APPLE_RELEASE_KEY_ID: ${{ secrets.APPLE_RELEASE_KEY_ID }} | |
APPLE_ID: ${{ secrets.APPLE_ID }} | |
APPLE_NOTARYTOOL_PASSWORD: ${{ secrets.APPLE_NOTARYTOOL_PASSWORD }} | |
- name: Upload packaging logs | |
uses: actions/upload-artifact@v2 | |
if: env.should_upload_app && env.should_notarize_app | |
with: | |
name: packaging-logs${{ env.NAME_QUALIFIER }} | |
path: build/logs |