Skip to content

Create DMG Variant #594

Create DMG Variant

Create DMG Variant #594

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-15
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