Create DMG Variant #497
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
on: | |
workflow_dispatch: | |
inputs: | |
atb-variant: | |
description: "ATB variant. Used for measuring attribution and retention." | |
required: false | |
type: string | |
origin-variant: | |
description: "Origin variant. Used for measuring attribution only." | |
required: false | |
type: string | |
workflow_call: | |
inputs: | |
atb-variant: | |
description: "ATB variant. Used for measuring attribution and retention. Passed by the caller workflow." | |
required: false | |
type: string | |
origin-variant: | |
description: "Origin variant. Used for measuring attribution only. Passed by the caller workflow." | |
required: false | |
type: string | |
secrets: | |
APPLE_API_KEY_BASE64: | |
required: true | |
APPLE_API_KEY_ID: | |
required: true | |
APPLE_API_KEY_ISSUER: | |
required: true | |
AWS_ACCESS_KEY_ID_RELEASE_S3: | |
required: true | |
AWS_SECRET_ACCESS_KEY_RELEASE_S3: | |
required: true | |
MATCH_PASSWORD: | |
required: true | |
SSH_PRIVATE_KEY_FASTLANE_MATCH: | |
required: true | |
jobs: | |
create-dmg-variant: | |
name: Create DMG Variant | |
env: | |
ATB_VARIANT_NAME: ${{ inputs.atb-variant || github.event.inputs.atb-variant }} | |
ORIGIN_VARIANT_NAME: ${{ inputs.origin-variant || github.event.inputs.origin-variant }} | |
runs-on: macos-14 | |
timeout-minutes: 15 | |
steps: | |
- name: Register SSH key for certificates repository access | |
uses: webfactory/[email protected] | |
with: | |
ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY_FASTLANE_MATCH }} | |
- name: Check out the code | |
uses: actions/checkout@v4 | |
with: | |
sparse-checkout: | | |
.github | |
Gemfile | |
Gemfile.lock | |
fastlane | |
scripts | |
- name: Set up fastlane | |
run: bundle install | |
- name: Sync code signing assets | |
env: | |
APPLE_API_KEY_BASE64: ${{ secrets.APPLE_API_KEY_BASE64 }} | |
APPLE_API_KEY_ID: ${{ secrets.APPLE_API_KEY_ID }} | |
APPLE_API_KEY_ISSUER: ${{ secrets.APPLE_API_KEY_ISSUER }} | |
MATCH_PASSWORD: ${{ secrets.MATCH_PASSWORD }} | |
SSH_PRIVATE_KEY_FASTLANE_MATCH: ${{ secrets.SSH_PRIVATE_KEY_FASTLANE_MATCH }} | |
run: bundle exec fastlane sync_signing_dmg_release | |
- name: Download DMG artifact | |
id: download-dmg-artifact | |
continue-on-error: true | |
uses: actions/download-artifact@v4 | |
with: | |
name: duckduckgo-dmg | |
path: ${{ github.workspace }} | |
- name: Download release app | |
# Download the release app only if download-dmg-artifact fails | |
if: ${{ steps.download-dmg-artifact.outcome == 'failure' }} | |
run: | | |
curl -fLSs "${{ vars.RELEASE_DMG_URL }}" --output duckduckgo.dmg | |
- name: Extract App from DMG | |
id: extract-app-from-dmg | |
run: | | |
hdiutil attach duckduckgo.dmg -mountpoint vanilla | |
mkdir -p dmg | |
cp -R vanilla/DuckDuckGo.app dmg/DuckDuckGo.app | |
hdiutil detach vanilla | |
rm -f duckduckgo.dmg | |
- name: Install create-dmg | |
run: brew install create-dmg | |
- name: Set up variant | |
working-directory: ${{ github.workspace }}/dmg | |
run: | | |
codesign -d --entitlements :- DuckDuckGo.app > entitlements.plist | |
echo "${{ env.ATB_VARIANT_NAME }}" > "DuckDuckGo.app/Contents/Resources/variant.txt" | |
echo "${{ env.ORIGIN_VARIANT_NAME }}" > "DuckDuckGo.app/Contents/Resources/Origin.txt" | |
sign_identity="$(security find-certificate -a -c "Developer ID Application" -Z | grep ^SHA-1 | cut -d " " -f3 | uniq)" | |
/usr/bin/codesign \ | |
--force \ | |
--sign ${sign_identity} \ | |
--options runtime \ | |
--entitlements entitlements.plist \ | |
--generate-entitlement-der "DuckDuckGo.app" | |
rm -f entitlements.plist | |
- name: Notarize the app | |
env: | |
APPLE_API_KEY_BASE64: ${{ secrets.APPLE_API_KEY_BASE64 }} | |
APPLE_API_KEY_ID: ${{ secrets.APPLE_API_KEY_ID }} | |
APPLE_API_KEY_ISSUER: ${{ secrets.APPLE_API_KEY_ISSUER }} | |
working-directory: ${{ github.workspace }}/dmg | |
run: | | |
# import API Key from secrets | |
export APPLE_API_KEY_PATH="$RUNNER_TEMP/apple_api_key.pem" | |
echo -n "$APPLE_API_KEY_BASE64" | base64 --decode -o $APPLE_API_KEY_PATH | |
notarization_zip_path="DuckDuckGo-for-notarization.zip" | |
ditto -c -k --keepParent "DuckDuckGo.app" "${notarization_zip_path}" | |
xcrun notarytool submit \ | |
--key "${APPLE_API_KEY_PATH}" \ | |
--key-id "${{ env.APPLE_API_KEY_ID }}" \ | |
--issuer "${{ env.APPLE_API_KEY_ISSUER }}" \ | |
--wait \ | |
"${notarization_zip_path}" | |
xcrun stapler staple "DuckDuckGo.app" | |
rm -rf "${notarization_zip_path}" | |
- name: Create variant DMG | |
env: | |
GH_TOKEN: ${{ github.token }} | |
run: | | |
retries=3 | |
while [[ $retries -gt 0 ]]; do | |
# Using APFS filesystem as per https://github.com/actions/runner-images/issues/7522#issuecomment-2299918092 | |
if create-dmg --volname "DuckDuckGo" \ | |
--filesystem APFS \ | |
--icon "DuckDuckGo.app" 140 160 \ | |
--background "scripts/assets/dmg-background.png" \ | |
--window-size 600 400 \ | |
--icon-size 120 \ | |
--app-drop-link 430 160 "duckduckgo.dmg" \ | |
"dmg" | |
then | |
break | |
fi | |
retries=$((retries-1)) | |
done | |
- name: Set variant name | |
id: set-variant-name | |
run: | | |
if [ -z "$ORIGIN_VARIANT_NAME" ] && [ -n "$ATB_VARIANT_NAME" ]; then | |
name=$ATB_VARIANT_NAME | |
elif [ -n "$ORIGIN_VARIANT_NAME" ] && [ -z "$ATB_VARIANT_NAME" ]; then | |
name=$ORIGIN_VARIANT_NAME | |
elif [ -n "$ORIGIN_VARIANT_NAME" ] && [ -n "$ATB_VARIANT_NAME" ]; then | |
name="${ORIGIN_VARIANT_NAME}-${ATB_VARIANT_NAME}" | |
else | |
echo "Neither ATB_VARIANT_NAME nor ORIGIN_VARIANT_NAME is set" | |
exit 1 | |
fi | |
echo "variant-name=${name}" >> "$GITHUB_OUTPUT" | |
- name: Upload variant DMG | |
env: | |
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID_RELEASE_S3 }} | |
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY_RELEASE_S3 }} | |
AWS_DEFAULT_REGION: ${{ vars.AWS_DEFAULT_REGION }} | |
run: | | |
aws s3 cp duckduckgo.dmg \ | |
s3://${{ vars.RELEASE_BUCKET_NAME }}/${{ vars.RELEASE_BUCKET_PREFIX }}/${{ steps.set-variant-name.outputs.variant-name }}/duckduckgo.dmg \ | |
--acl public-read |