Add nightly iOS/Android build workflow (#10940)
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -10,6 +10,32 @@ on:
|
||||
options:
|
||||
- testflight
|
||||
- production
|
||||
assignTestFlightGroup:
|
||||
type: boolean
|
||||
description: Assign the build to the "QA Team" TestFlight group after submitting
|
||||
default: false
|
||||
workflow_call:
|
||||
inputs:
|
||||
profile:
|
||||
type: string
|
||||
description: Build profile to use
|
||||
required: true
|
||||
assignTestFlightGroup:
|
||||
type: boolean
|
||||
description: Assign the build to the "QA Team" TestFlight group after submitting
|
||||
default: false
|
||||
releaseNotes:
|
||||
type: string
|
||||
description: Notes to set as the TestFlight "What to Test" changelog
|
||||
required: false
|
||||
default: ''
|
||||
outputs:
|
||||
package-version:
|
||||
description: Version from package.json
|
||||
value: ${{ jobs.build.outputs.package-version }}
|
||||
build-number:
|
||||
description: iOS build number
|
||||
value: ${{ jobs.build.outputs.build-number }}
|
||||
|
||||
# Deploys happen via EAS using EXPO_TOKEN; the GITHUB_TOKEN only checks out code
|
||||
permissions:
|
||||
@@ -23,6 +49,9 @@ jobs:
|
||||
concurrency:
|
||||
group: ios-build
|
||||
cancel-in-progress: false
|
||||
outputs:
|
||||
package-version: ${{ steps.get-build-info.outputs.PACKAGE_VERSION }}
|
||||
build-number: ${{ steps.ipa-build-number.outputs.build-number }}
|
||||
steps:
|
||||
- name: Check for EXPO_TOKEN
|
||||
run: >
|
||||
@@ -164,6 +193,59 @@ jobs:
|
||||
id: get-build-info
|
||||
run: bash scripts/setGitHubOutput.sh
|
||||
|
||||
# Read the build number straight from the IPA's CFBundleVersion. This is the value
|
||||
# baked in at build time by use-build-number-with-bump (remote counter + 1) and the
|
||||
# number that actually lands in App Store Connect. `eas build:version:get` reads the
|
||||
# remote counter, which a --local build does not advance, so it can be off by one —
|
||||
# using it here would make distribute_only poll for a nonexistent build.
|
||||
- name: 🔢 Read build number from IPA
|
||||
id: ipa-build-number
|
||||
run: |
|
||||
plist_dir="$(mktemp -d)"
|
||||
unzip -o -q "$BUILD_DIR/Bluesky.ipa" 'Payload/*.app/Info.plist' -d "$plist_dir"
|
||||
plist="$(find "$plist_dir" -name Info.plist -print -quit)"
|
||||
build_number="$(/usr/libexec/PlistBuddy -c 'Print CFBundleVersion' "$plist")"
|
||||
rm -rf "$plist_dir"
|
||||
if [ -z "$build_number" ]; then
|
||||
echo "ERROR: could not read CFBundleVersion from IPA"
|
||||
exit 1
|
||||
fi
|
||||
echo "IPA build number: $build_number"
|
||||
echo "build-number=$build_number" >> "$GITHUB_OUTPUT"
|
||||
|
||||
# eas submit only uploads to App Store Connect; it can't assign a build to a
|
||||
# TestFlight group. fastlane's distribute_only mode skips the upload and assigns the
|
||||
# already-submitted build to the group, polling until Apple finishes processing it.
|
||||
# The "What to Test" changelog is supplied by the caller (e.g. the nightly workflow).
|
||||
- name: 🧪 Assign build to TestFlight group
|
||||
if: ${{ inputs.assignTestFlightGroup }}
|
||||
env:
|
||||
ASC_KEY_ID: ${{ secrets.ASC_KEY_ID }}
|
||||
ASC_ISSUER_ID: ${{ secrets.ASC_ISSUER_ID }}
|
||||
ASC_KEY_P8_BASE64: ${{ secrets.ASC_KEY_P8_BASE64 }}
|
||||
APP_VERSION: ${{ steps.get-build-info.outputs.PACKAGE_VERSION }}
|
||||
BUILD_NUMBER: ${{ steps.ipa-build-number.outputs.build-number }}
|
||||
RELEASE_NOTES: ${{ inputs.releaseNotes }}
|
||||
run: |
|
||||
# Ensure the API key material is removed even if fastlane exits non-zero
|
||||
# (the step runs under `bash -e`, which would otherwise abort before cleanup).
|
||||
trap 'rm -f asc_api_key.p8 asc_api_key.json' EXIT
|
||||
echo "$ASC_KEY_P8_BASE64" | base64 --decode > asc_api_key.p8
|
||||
printf '{"key_id":"%s","issuer_id":"%s","key_filepath":"%s","in_house":false}' \
|
||||
"$ASC_KEY_ID" "$ASC_ISSUER_ID" "$PWD/asc_api_key.p8" > asc_api_key.json
|
||||
changelog_args=()
|
||||
if [ -n "$RELEASE_NOTES" ]; then
|
||||
changelog_args=(changelog:"$RELEASE_NOTES")
|
||||
fi
|
||||
fastlane run upload_to_testflight \
|
||||
api_key_path:"$PWD/asc_api_key.json" \
|
||||
distribute_only:true \
|
||||
app_identifier:"xyz.blueskyweb.app" \
|
||||
app_version:"$APP_VERSION" \
|
||||
build_number:"$BUILD_NUMBER" \
|
||||
"${changelog_args[@]}" \
|
||||
groups:"QA Team"
|
||||
|
||||
- name: 🔔 Notify Slack of Production Build
|
||||
if: ${{ inputs.profile == 'production' }}
|
||||
uses: slackapi/slack-github-action@45a88b9581bfab2566dc881e2cd66d334e621e2c # v3.0.3
|
||||
@@ -172,7 +254,7 @@ jobs:
|
||||
webhook-type: incoming-webhook
|
||||
payload-templated: true
|
||||
payload: |
|
||||
{"text": "iOS production build for App Store submission is ready!\n```Artifact: Check TestFlight to know when it is available\nVersion Number: ${{ steps.get-build-info.outputs.PACKAGE_VERSION }}\nBuild Number: ${{ steps.get-build-info.outputs.BSKY_IOS_BUILD_NUMBER }}```"}
|
||||
{"text": "iOS production build for App Store submission is ready!\n```Artifact: Check TestFlight to know when it is available\nVersion Number: ${{ steps.get-build-info.outputs.PACKAGE_VERSION }}\nBuild Number: ${{ steps.ipa-build-number.outputs.build-number }}```"}
|
||||
|
||||
- name: ⬇️ Restore Cache
|
||||
id: get-base-commit
|
||||
|
||||
Reference in New Issue
Block a user