Last active
March 19, 2025 02:10
-
-
Save paulz/53f80b8e16ae82a07f432d831b538978 to your computer and use it in GitHub Desktop.
TestFlight deployment using altool GitHub Actions workflow
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
#!/bin/zsh --login --errexit | |
version=$((GITHUB_RUN_NUMBER+version_offset)) | |
ORGANIZER_ARCHIVE=$(find ~/Library/Developer/Xcode/Archives -name MyApp-$version.xcarchive) | |
if [[ $ORGANIZER_ARCHIVE ]] | |
then | |
echo "::notice::Uploading: $ORGANIZER_ARCHIVE" | |
else | |
echo "::error::Archive MyApp-$version.xcarchive not found" | |
find -s ~/Library/Developer/Xcode/Archives -name \*.xcarchive | |
exit 1 | |
fi | |
rm export-options.plist || true | |
/usr/libexec/PlistBuddy -c 'Add :method string app-store' export-options.plist | |
/usr/libexec/PlistBuddy -c 'Add :destination string export' export-options.plist | |
# Add default toolchain to the path to fix error: otool-classic not found | |
PATH=$(xcode-select -p)/Toolchains/XcodeDefault.xctoolchain/usr/bin:$PATH | |
# Unlock keychain to workaround: https://developer.apple.com/forums/thread/123959 | |
security unlock-keychain -p $KEYCHAIN_PASSWORD ~/Library/Keychains/login.keychain-db | |
security show-keychain-info login.keychain | |
xcodebuild -exportArchive -verbose \ | |
-sdk iphoneos \ | |
-archivePath $ORGANIZER_ARCHIVE \ | |
-exportOptionsPlist export-options.plist \ | |
-authenticationKeyIssuerID $AUTH_KEY_ISSUER_ID \ | |
-authenticationKeyID $AUTH_KEY_ID \ | |
-authenticationKeyPath ~/.appstoreconnect/private_keys/AuthKey_$AUTH_KEY_ID.p8 \ | |
-allowProvisioningUpdates \ | |
-exportPath exported | |
xcrun altool --verbose --upload-app --file ./exported/MyApp.ipa --type iOS --apiIssuer $AUTH_KEY_ISSUER_ID --apiKey $AUTH_KEY_ID |
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: TestFlight | |
on: | |
workflow_dispatch: | |
inputs: | |
changelog: | |
type: string | |
description: What to test | |
required: true | |
push: | |
branches: | |
- experiment/test-flight/** | |
defaults: | |
run: | |
shell: zsh --login --errexit --pipefail {0} | |
env: | |
NSUnbufferedIO: YES # display xcodebuild output in the correct order for github action log | |
version_offset: 1 # Offset build version number from Github run number | |
concurrency: | |
group: one-test-flight-${{ github.ref }} | |
cancel-in-progress: true | |
jobs: | |
xcode-archive: | |
name: Build iOS Release | |
timeout-minutes: 30 | |
runs-on: self-hosted | |
steps: | |
- name: Show what to test | |
run: echo "::notice::What to test - ${{ github.event.inputs.changelog }}" | |
- name: Checkout | |
uses: actions/checkout@v3 | |
- name: Set version number | |
run: | | |
next_version=$((GITHUB_RUN_NUMBER+version_offset)) | |
agvtool new-version $next_version | |
echo "::notice::$(agvtool what-version | tr -d '\n')" | |
marketing_version=$(xcodebuild -showBuildSettings | grep MARKETING_VERSION | tr -d 'MARKETING_VERSION =') | |
echo "TAG_NAME=$marketing_version-$next_version" >> $GITHUB_ENV | |
echo "ARCHIVE=MyApp-$next_version.xcarchive" >> $GITHUB_ENV | |
- name: Clean Build Folder | |
run: rm -rf build || true | |
- name: Unlock Keychain | |
run: | | |
security unlock-keychain -p ${{ secrets.KEYCHAIN_PASSWORD }} login.keychain | |
security show-keychain-info login.keychain | |
- name: Build and Archive | |
run: > | |
xcodebuild | |
-scheme MyApp | |
-sdk iphoneos | |
-archivePath ${{ env.ARCHIVE }} | |
-onlyUsePackageVersionsFromResolvedFile | |
-derivedDataPath build/derivedData | |
-destination generic/platform=iOS | |
archive | xcbeautify | |
env: | |
COMPILER_INDEX_STORE_ENABLE: NO | |
- name: Save Archive to Xcode Organizer | |
run: | | |
open $ARCHIVE | |
find -s ~/Library/Developer/Xcode/Archives/ -name \*.xcarchive | |
- name: Compress Xcode Archive # due to: https://github.com/actions/upload-artifact/issues/326 | |
if: always() | |
run: > | |
tar --use-compress-program pbzip2 | |
--check-links --verbose | |
--create --file $ARCHIVE.tar.bz2 $ARCHIVE || true | |
- name: Upload Xcode archive to Artifacts | |
if: always() | |
uses: actions/upload-artifact@v3 | |
with: | |
path: ${{ env.ARCHIVE }}.tar.bz2 | |
name: ${{ env.ARCHIVE }} | |
- name: GitHub Tag | |
uses: mathieudutour/[email protected] | |
with: | |
custom_tag: ${{ env.TAG_NAME }} | |
github_token: ${{ secrets.GITHUB_TOKEN }} | |
export-archive: | |
name: Upload to TestFlight | |
needs: xcode-archive | |
timeout-minutes: 30 | |
runs-on: self-hosted | |
steps: | |
- name: Export Xcode archive | |
run: scripts/export-xcode-archive.zsh | |
env: | |
AUTH_KEY_ISSUER_ID: ${{ secrets.AUTH_KEY_ISSUER_ID }} | |
AUTH_KEY_ID: ${{ secrets.AUTH_KEY_ID }} | |
KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment