run altool with --verbose #334
Workflow file for this run
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: CI | |
on: | |
pull_request: | |
branches: | |
- main | |
- alpha | |
push: | |
permissions: | |
contents: write | |
jobs: | |
build: | |
runs-on: macos-13 | |
outputs: | |
bundle_version: ${{ steps.configure_versions.outputs.bundle_version }} | |
next_bundle_version: ${{ steps.configure_versions.outputs.next_bundle_version }} | |
bundle_short_version: ${{ steps.configure_versions.outputs.bundle_short_version }} | |
strategy: | |
matrix: | |
spec: | |
- { scheme: 'ZitiPacketTunnel', config: 'Release', sdk: 'macosx', destination: 'generic/platform=macOS' } | |
- { scheme: 'ZitiMobilePacketTunnel', config: 'Release', sdk: 'iphoneos', destination: 'generic/platform=iOS' } | |
steps: | |
- uses: actions/checkout@v4 | |
- uses: maxim-lobanov/setup-xcode@v1 | |
with: | |
xcode-version: '15.2' | |
- name: Store XCConfig | |
id: store_xcconfig | |
run: | | |
xcconfig_fn="./Configs/workspace-settings-overrides.xcconfig" | |
echo ${{ secrets.XCCONFIG }} | base64 --decode > ${xcconfig_fn} | |
id_var=$([[ ${{ matrix.spec.sdk }} == 'macosx' ]] && echo "MAC_APP_IDENTIFIER" || echo "IOS_APP_IDENTIFIER") | |
line=$(cat ${xcconfig_fn} | grep ${id_var}) && app_identifier=$(echo ${line##* }) | |
echo "id_var: ${id_var}; app_identiier: ${app_identifier}" | |
echo "app_identifier=${app_identifier}" >> $GITHUB_OUTPUT | |
- name: Setup Keychain | |
run: | | |
echo "${{ secrets.APPLE_DEVELOPMENT_P12 }}" | base64 --decode > ./development.p12 | |
echo "${{ secrets.APPLE_DEVELOPMENT_P12_PASSWORD }}" > ./development.pass | |
PASS=$(cat ./development.pass | base64 --decode) | |
security create-keychain -p paswsword build.keychain | |
security default-keychain -s build.keychain | |
security unlock-keychain -p paswsword build.keychain | |
security import ./development.p12 -k build.keychain -P ${PASS} -A -t cert -f pkcs12 | |
security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k paswsword build.keychain | |
- run: mkdir ./archives | |
- name: Store API Key | |
id: store_api_key | |
env: | |
AUTH_KEY: ${{ secrets.APPLE_DEVELOPER_KEY }} | |
AUTH_KEY_ID: ${{ secrets.APPLE_DEVELOPER_KEY_ID }} | |
run: | | |
key_dir="${HOME}/.appstoreconnect/private_keys" | |
mkdir -p ${key_dir} | |
key_fn="${key_dir}/AuthKey_${AUTH_KEY_ID}.p8" | |
echo "Storing ${key_fn}" | |
echo ${AUTH_KEY} | base64 --decode > ${key_fn} | |
echo "api_key_fn=${key_fn}" >> $GITHUB_OUTPUT | |
- name: Create App Store Connect Token | |
id: create_acs_token | |
env: | |
AUTH_KEY_ID: ${{ secrets.APPLE_DEVELOPER_KEY_ID }} | |
AUTH_KEY_ISSUER_ID: ${{ secrets.APPLE_DEVELOPER_KEY_ISSUER_ID }} | |
api_key_fn: ${{ steps.store_api_key.outputs.api_key_fn }} | |
run: | | |
gem install jwt | |
cat > jwt.rb <<EOF | |
require "base64" | |
require "jwt" | |
puts JWT.encode({ iss: ARGV[0], exp: Time.now.to_i + 20 * 60, aud: "appstoreconnect-v1" }, | |
OpenSSL::PKey.read(File.read(ARGV[2])), "ES256", header_fields={ kid: ARGV[1] }) | |
EOF | |
bearer=$(ruby jwt.rb ${AUTH_KEY_ISSUER_ID} ${AUTH_KEY_ID} ${api_key_fn}) | |
echo "bearer=${bearer}" >> $GITHUB_OUTPUT | |
- name: Get App Info | |
id: get_app_info | |
env: | |
AUTH_KEY_ID: ${{ secrets.APPLE_DEVELOPER_KEY_ID }} | |
AUTH_KEY_ISSUER_ID: ${{ secrets.APPLE_DEVELOPER_KEY_ISSUER_ID }} | |
run: | | |
all_app_info=$(xcrun altool --verbose --list-apps --apiKey ${AUTH_KEY_ID} --apiIssuer ${AUTH_KEY_ISSUER_ID} --output-format json) | |
app_id="${{ steps.store_xcconfig.outputs.app_identifier }}" | |
app_info=$(echo ${all_app_info} | jq -r --arg APPID ${app_id} '.applications[] | select(.ReservedBundleIdentifier | contains($APPID))') | |
version_number=$(echo ${app_info} | jq '."Version Number"') | |
short_version=$(echo ${app_info} | jq '.ShortVersion') | |
application=$(echo ${app_info} | jq '.Application') | |
apple_id=$(echo ${app_info} | jq '.AppleID') | |
team_id=$(echo ${app_info} | jq '.WWDRIdentifier') | |
echo "version_number=${version_number}" >> $GITHUB_OUTPUT | |
echo "short_version=${short_version}" >> $GITHUB_OUTPUT | |
echo "application=${application}" >> $GITHUB_OUTPUT | |
echo "apple_id=${apple_id}" >> $GITHUB_OUTPUT | |
echo "team_id=${team_id}" >> $GITHUB_OUTPUT | |
- name: Configure Versions | |
id: configure_versions | |
env: | |
bearer: "${{ steps.create_acs_token.outputs.bearer }}" | |
run: | | |
mvers=$(agvtool mvers -terse1) | |
app="${{ steps.get_app_info.outputs.apple_id }}" | |
url="https://api.appstoreconnect.apple.com/v1/builds?filter[app]=${app}&fields[builds]=version&limit=1" | |
acs_vers=$(curl -g -s -H "Authorization: Bearer ${bearer}" "${url}" | jq '.data[].attributes.version|tonumber') | |
echo "ACS Vers: ${acs_vers}" | |
curr=$([[ -z "${acs_vers}" ]] && echo ${steps.get_app_info.outputs.version_number} || echo ${acs_vers}) | |
echo "Curr: ${curr}" | |
next=$((${curr}+1)) | |
echo "Bumping version from ${curr} to ${next}" | |
agvtool new-version -all ${next} | |
echo "bundle_version=${curr}" >> $GITHUB_OUTPUT | |
echo "next_bundle_version=${next}" >> $GITHUB_OUTPUT | |
echo "bundle_short_version=${mvers}" >> $GITHUB_OUTPUT | |
- name: Get Public ID | |
id: get_public_id | |
env: | |
AUTH_KEY_ID: ${{ secrets.APPLE_DEVELOPER_KEY_ID }} | |
AUTH_KEY_ISSUER_ID: ${{ secrets.APPLE_DEVELOPER_KEY_ISSUER_ID }} | |
run: | | |
all_provider_info=$(xcrun altool --list-providers --apiKey ${AUTH_KEY_ID} --apiIssuer ${AUTH_KEY_ISSUER_ID} --output-format json) | |
team_id="${{ steps.get_app_info.outputs.team_id }}" | |
public_id=$(echo ${all_provider_info} | jq -r --arg TEAMID ${team_id} '.providers[] | select(.WWDRTeamID | contains($TEAMID)).PublicID') | |
echo "public_id=${public_id}" >> $GITHUB_OUTPUT | |
- name: Archive | |
env: | |
SCHEME: ${{ matrix.spec.scheme }} | |
CONFIG: ${{ matrix.spec.config }} | |
SDK: ${{ matrix.spec.sdk }} | |
DESTINATION: ${{ matrix.spec.destination }} | |
AUTH_KEY_ID: ${{ secrets.APPLE_DEVELOPER_KEY_ID }} | |
AUTH_KEY_ISSUER_ID: ${{ secrets.APPLE_DEVELOPER_KEY_ISSUER_ID }} | |
run: | | |
xcodebuild archive -allowProvisioningUpdates \ | |
-authenticationKeyPath ${{ steps.store_api_key.outputs.api_key_fn }} \ | |
-authenticationKeyID ${AUTH_KEY_ID} -authenticationKeyIssuerID ${AUTH_KEY_ISSUER_ID} \ | |
-configuration ${CONFIG} -scheme ${SCHEME} -sdk ${SDK} -destination ${DESTINATION} \ | |
-archivePath ./archives/${SCHEME} | |
- name: Export | |
env: | |
SCHEME: ${{ matrix.spec.scheme }} | |
AUTH_KEY_ID: ${{ secrets.APPLE_DEVELOPER_KEY_ID }} | |
AUTH_KEY_ISSUER_ID: ${{ secrets.APPLE_DEVELOPER_KEY_ISSUER_ID }} | |
run: | | |
xcodebuild -allowProvisioningUpdates \ | |
-authenticationKeyPath ${{ steps.store_api_key.outputs.api_key_fn }} \ | |
-authenticationKeyID ${AUTH_KEY_ID} -authenticationKeyIssuerID ${AUTH_KEY_ISSUER_ID} \ | |
-exportArchive -exportPath ./archives/${SCHEME} \ | |
-exportOptionsPlist ./etc/exportOptionsRelease.plist \ | |
-archivePath ./archives/${SCHEME}.xcarchive | |
- name: Validate | |
id: validate_app | |
continue-on-error: true | |
env: | |
SCHEME: ${{ matrix.spec.scheme }} | |
AUTH_KEY_ID: ${{ secrets.APPLE_DEVELOPER_KEY_ID }} | |
AUTH_KEY_ISSUER_ID: ${{ secrets.APPLE_DEVELOPER_KEY_ISSUER_ID }} | |
run: | | |
type=$([[ ${{ matrix.spec.sdk }} == 'macosx' ]] && echo "macos" || echo "ios") | |
ext=$([[ ${{ matrix.spec.sdk }} == 'macosx' ]] && echo "pkg" || echo "ipa") | |
app=${{ steps.get_app_info.outputs.application }} | |
fn="./archives/${SCHEME}/${app}.${ext}" | |
xcrun altool --validate-app --file "${fn}" --type ${type} --apiKey ${AUTH_KEY_ID} --apiIssuer ${AUTH_KEY_ISSUER_ID} | |
echo "package_path=${fn}" >> $GITHUB_OUTPUT | |
- name: Upload | |
if: github.event_name == 'pull_request' | |
env: | |
AUTH_KEY_ID: ${{ secrets.APPLE_DEVELOPER_KEY_ID }} | |
AUTH_KEY_ISSUER_ID: ${{ secrets.APPLE_DEVELOPER_KEY_ISSUER_ID }} | |
run: | | |
type=$([[ ${{ matrix.spec.sdk }} == 'macosx' ]] && echo "macos" || echo "ios") | |
file_path="${{ steps.validate_app.outputs.package_path }}" | |
public_id=${{ steps.get_public_id.outputs.public_id }} | |
apple_id=${{ steps.get_app_info.outputs.apple_id }} | |
bundle_version=${{ steps.configure_versions.outputs.next_bundle_version }} | |
bundle_short_version=${{ steps.configure_versions.outputs.bundle_short_version }} | |
bundle_id=${{ steps.store_xcconfig.outputs.app_identifier }} | |
xcrun altool --upload-package "${file_path}" \ | |
--asc-public-id ${public_id} \ | |
--apple-id ${apple_id} \ | |
--bundle-version ${bundle_version} \ | |
--bundle-short-version-string ${bundle_short_version} \ | |
--bundle-id ${bundle_id} \ | |
--type ${type} --apiKey ${AUTH_KEY_ID} --apiIssuer ${AUTH_KEY_ISSUER_ID} | |
- name: Wait For Build Processing | |
if: github.event_name == 'pull_request' | |
env: | |
bearer: "${{ steps.create_acs_token.outputs.bearer }}" | |
uploaded_build: "${{ steps.configure_versions.outputs.next_bundle_version }}" | |
run: | | |
mvers=$(agvtool mvers -terse1) | |
app="${{ steps.get_app_info.outputs.apple_id }}" | |
url="https://api.appstoreconnect.apple.com/v1/builds?filter[app]=${app}&fields[builds]=version&filter[preReleaseVersion.version]=${mvers}&limit=1" | |
while [ 1 ] ; do | |
echo "Waiting for build processing to complete for ${mvers}.${uploaded_build}..." | |
latest_build=$(curl -g -s -H "Authorization: Bearer ${bearer}" "${url}" | jq '.data[].attributes.version|tonumber') | |
if [ "$latest_build" = "$uploaded_build" ] ; then echo "Build processing complete"; break; fi | |
sleep 30 | |
done | |
- name: Cleanup Keychain | |
if: always() | |
run: | | |
rm -f ${{ steps.store_api_key.outputs.api_key_fn }} | |
rm -f ./development.p12 | |
rm -f ./development.pass | |
security default-keychain -s "login.keychain" | |
security delete-keychain build.keychain | |
draft-release: | |
runs-on: ubuntu-latest | |
needs: [ build ] | |
if: github.event_name == 'push' && (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/alpha') | |
steps: | |
- name: Checkout Project | |
uses: actions/checkout@v4 | |
with: | |
fetch-depth: 0 | |
- name: Draft Release | |
id: release_drafter | |
uses: release-drafter/release-drafter@v5 | |
env: | |
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
with: | |
tag: "${{ needs.build.outputs.bundle_short_version }}.${{ needs.build.outputs.bundle_version }}" | |
name: "v${{ needs.build.outputs.bundle_short_version }}.${{ needs.build.outputs.bundle_version }}" | |
version: "${{ needs.build.outputs.bundle_short_version }}.${{ needs.build.outputs.bundle_version }}" | |
prerelease: "${{ github.ref != 'refs/heads/main' }}" |