Fix silently-frozen OTA fingerprint baseline with artifacts (#11231)
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -170,22 +170,6 @@ jobs:
|
|||||||
payload: |
|
payload: |
|
||||||
{"text": "Android ${{ inputs.profile || 'testflight-android' }} build submitted to Google Play!\n```Version Number: ${{ needs.build.outputs.package-version }}\nBuild Number: ${{ needs.build.outputs.version-code }}```"}
|
{"text": "Android ${{ inputs.profile || 'testflight-android' }} build submitted to Google Play!\n```Version Number: ${{ needs.build.outputs.package-version }}\nBuild Number: ${{ needs.build.outputs.version-code }}```"}
|
||||||
|
|
||||||
# Record the commit only after a successful submit, so a failed submit doesn't
|
|
||||||
# advance the "most recent testflight" marker.
|
|
||||||
- name: ⬇️ Restore Cache
|
|
||||||
id: get-base-commit
|
|
||||||
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
|
|
||||||
if: ${{ inputs.profile == 'testflight-android' }}
|
|
||||||
with:
|
|
||||||
path: most-recent-testflight-commit.txt
|
|
||||||
key: most-recent-testflight-commit
|
|
||||||
|
|
||||||
- name: ✏️ Write commit hash to cache
|
|
||||||
if: ${{ inputs.profile == 'testflight-android' }}
|
|
||||||
env:
|
|
||||||
GITHUB_SHA: ${{ github.sha }}
|
|
||||||
run: echo $GITHUB_SHA > most-recent-testflight-commit.txt
|
|
||||||
|
|
||||||
# Runs in parallel with submit: the QA APK shouldn't be blocked by a Play submission failure.
|
# Runs in parallel with submit: the QA APK shouldn't be blocked by a Play submission failure.
|
||||||
universalApk:
|
universalApk:
|
||||||
name: Build universal APK
|
name: Build universal APK
|
||||||
|
|||||||
@@ -254,22 +254,6 @@ jobs:
|
|||||||
payload: |
|
payload: |
|
||||||
{"text": "iOS production build for App Store submission is ready!\n```Artifact: Check TestFlight to know when it is available\nVersion Number: ${{ needs.build.outputs.package-version }}\nBuild Number: ${{ needs.build.outputs.build-number }}```"}
|
{"text": "iOS production build for App Store submission is ready!\n```Artifact: Check TestFlight to know when it is available\nVersion Number: ${{ needs.build.outputs.package-version }}\nBuild Number: ${{ needs.build.outputs.build-number }}```"}
|
||||||
|
|
||||||
# Record the commit only after a successful submit, so a failed submit doesn't advance
|
|
||||||
# the baseline used for the next testflight build's changelog.
|
|
||||||
- name: ⬇️ Restore Cache
|
|
||||||
id: get-base-commit
|
|
||||||
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
|
|
||||||
if: ${{ inputs.profile == 'testflight' }}
|
|
||||||
with:
|
|
||||||
path: most-recent-testflight-commit.txt
|
|
||||||
key: most-recent-testflight-commit
|
|
||||||
|
|
||||||
- name: ✏️ Write commit hash to cache
|
|
||||||
env:
|
|
||||||
GITHUB_SHA: ${{ github.sha }}
|
|
||||||
if: ${{ inputs.profile == 'testflight' }}
|
|
||||||
run: echo $GITHUB_SHA > most-recent-testflight-commit.txt
|
|
||||||
|
|
||||||
distribute:
|
distribute:
|
||||||
name: Assign build to TestFlight group
|
name: Assign build to TestFlight group
|
||||||
# fastlane and jq ship preinstalled on the macOS runner image, and this step mostly idles
|
# fastlane and jq ship preinstalled on the macOS runner image, and this step mostly idles
|
||||||
|
|||||||
@@ -33,9 +33,11 @@ jobs:
|
|||||||
name: Bundle and Deploy EAS Update
|
name: Bundle and Deploy EAS Update
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
# id-token: write lets this job mint an OIDC token to assume the denis
|
# id-token: write lets this job mint an OIDC token to assume the denis
|
||||||
# publish role; contents: read is still needed for the checkout.
|
# publish role; actions: read loads the fingerprint baseline artifact;
|
||||||
|
# contents: read is still needed for the checkout.
|
||||||
permissions:
|
permissions:
|
||||||
id-token: write
|
id-token: write
|
||||||
|
actions: read
|
||||||
contents: read
|
contents: read
|
||||||
concurrency:
|
concurrency:
|
||||||
group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.ref }}-deploy
|
group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.ref }}-deploy
|
||||||
@@ -101,12 +103,58 @@ jobs:
|
|||||||
node-version-file: package.json
|
node-version-file: package.json
|
||||||
cache: pnpm
|
cache: pnpm
|
||||||
|
|
||||||
|
- name: ⬇️ Load fingerprint baseline
|
||||||
|
id: baseline
|
||||||
|
if: ${{ (inputs.channel || 'testflight') == 'testflight' }}
|
||||||
|
env:
|
||||||
|
GH_TOKEN: ${{ github.token }}
|
||||||
|
REPOSITORY_ID: ${{ github.repository_id }}
|
||||||
|
run: |
|
||||||
|
url=$(gh api \
|
||||||
|
"repos/${GITHUB_REPOSITORY}/actions/artifacts?name=testflight-native-fingerprint&per_page=100" \
|
||||||
|
--jq "[.artifacts[] | select(
|
||||||
|
.expired == false and
|
||||||
|
.workflow_run.head_branch == \"main\" and
|
||||||
|
.workflow_run.head_repository_id == (\$ENV.REPOSITORY_ID | tonumber)
|
||||||
|
)] | max_by(.created_at) | .archive_download_url" \
|
||||||
|
2>/dev/null || true)
|
||||||
|
|
||||||
|
if [ -n "$url" ] && [ "$url" != "null" ]; then
|
||||||
|
mkdir baseline-artifact
|
||||||
|
if curl -sSL -H "Authorization: Bearer $GH_TOKEN" -o baseline.zip "$url" \
|
||||||
|
&& unzip -q baseline.zip -d baseline-artifact; then
|
||||||
|
if jq -e '.sources | type == "array"' \
|
||||||
|
baseline-artifact/native-fingerprint.json >/dev/null; then
|
||||||
|
echo "path=baseline-artifact/native-fingerprint.json" >> "$GITHUB_OUTPUT"
|
||||||
|
else
|
||||||
|
echo "::warning::Ignoring invalid fingerprint baseline artifact."
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "::warning::Could not download fingerprint baseline artifact."
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
- name: 📷 Check fingerprint and install dependencies
|
- name: 📷 Check fingerprint and install dependencies
|
||||||
id: fingerprint
|
id: fingerprint
|
||||||
uses: bluesky-social/github-actions/fingerprint-native@b5556913e4aef3964cfd5936d0add3fc0d809bdb # v0.2.0
|
uses: bluesky-social/github-actions/fingerprint-native@abc6a46eb4badf243f55bfd7d6cec42722456300 # v0.3.0
|
||||||
with:
|
with:
|
||||||
profile: ${{ inputs.channel || 'testflight' }}
|
profile: ${{ inputs.channel || 'testflight' }}
|
||||||
previous-commit-tag: ${{ inputs.runtimeVersion }}
|
previous-commit-tag: ${{ inputs.runtimeVersion }}
|
||||||
|
# The recordBaseline job uploads this marker after a successful deploy;
|
||||||
|
# on the native path, that requires both builds to succeed. A missing
|
||||||
|
# marker forces native builds so they can seed the baseline safely.
|
||||||
|
baseline-fingerprint-path: ${{ steps.baseline.outputs.path }}
|
||||||
|
|
||||||
|
# Hand the full fingerprint to recordBaseline through a short-lived
|
||||||
|
# artifact. It is uploaded unconditionally but promoted to the persistent
|
||||||
|
# baseline only after both native builds succeed.
|
||||||
|
- name: 🚀 Upload native fingerprint
|
||||||
|
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
||||||
|
with:
|
||||||
|
name: native-fingerprint-${{ github.run_id }}
|
||||||
|
path: ${{ steps.fingerprint.outputs.current-fingerprint-path }}
|
||||||
|
retention-days: 1
|
||||||
|
if-no-files-found: error
|
||||||
|
|
||||||
- name: 🔤 Compile translations
|
- name: 🔤 Compile translations
|
||||||
uses: ./.github/actions/compile-i18n
|
uses: ./.github/actions/compile-i18n
|
||||||
@@ -195,20 +243,6 @@ jobs:
|
|||||||
RUNTIME_VERSION: ${{ inputs.runtimeVersion }}
|
RUNTIME_VERSION: ${{ inputs.runtimeVersion }}
|
||||||
CHANNEL_NAME: ${{ inputs.channel || 'testflight' }}
|
CHANNEL_NAME: ${{ inputs.channel || 'testflight' }}
|
||||||
|
|
||||||
- name: ⬇️ Restore Cache
|
|
||||||
id: get-base-commit
|
|
||||||
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
|
|
||||||
if: ${{ !steps.fingerprint.outputs.includes-changes &&
|
|
||||||
!steps.version.outputs.version-changed }}
|
|
||||||
with:
|
|
||||||
path: most-recent-testflight-commit.txt
|
|
||||||
key: most-recent-testflight-commit
|
|
||||||
|
|
||||||
- name: ✏️ Write commit hash to cache
|
|
||||||
if: ${{ !steps.fingerprint.outputs.includes-changes &&
|
|
||||||
!steps.version.outputs.version-changed }}
|
|
||||||
run: echo $GITHUB_SHA > most-recent-testflight-commit.txt
|
|
||||||
|
|
||||||
buildIfNecessaryIOS:
|
buildIfNecessaryIOS:
|
||||||
name: Build and Submit iOS
|
name: Build and Submit iOS
|
||||||
needs: [bundleDeploy]
|
needs: [bundleDeploy]
|
||||||
@@ -270,3 +304,48 @@ jobs:
|
|||||||
ANDROID_KEYSTORE_PASSWORD: ${{ secrets.ANDROID_KEYSTORE_PASSWORD }}
|
ANDROID_KEYSTORE_PASSWORD: ${{ secrets.ANDROID_KEYSTORE_PASSWORD }}
|
||||||
ANDROID_KEY_ALIAS: ${{ secrets.ANDROID_KEY_ALIAS }}
|
ANDROID_KEY_ALIAS: ${{ secrets.ANDROID_KEY_ALIAS }}
|
||||||
ANDROID_KEY_PASSWORD: ${{ secrets.ANDROID_KEY_PASSWORD }}
|
ANDROID_KEY_PASSWORD: ${{ secrets.ANDROID_KEY_PASSWORD }}
|
||||||
|
|
||||||
|
# Advance the fingerprint baseline only after BOTH native builds have shipped
|
||||||
|
# the new native surface. This replaces the old actions/cache baseline, which
|
||||||
|
# only advanced on cache eviction and so silently froze - freezing meant every
|
||||||
|
# fingerprint looked changed and OTA updates stopped deploying entirely.
|
||||||
|
#
|
||||||
|
# On the native-build path, this runs only after both builds succeed. A
|
||||||
|
# successful OTA deploy also records its fingerprint, refreshing the
|
||||||
|
# persistent marker's retention without changing the native baseline.
|
||||||
|
#
|
||||||
|
# The persistent artifact replaces the old actions/cache marker without
|
||||||
|
# requiring a PAT or mutable repository variable. Each successful deploy adds
|
||||||
|
# an immutable marker; the next run reads the newest non-expired one using the
|
||||||
|
# built-in GITHUB_TOKEN.
|
||||||
|
recordBaseline:
|
||||||
|
name: Record fingerprint baseline
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: [bundleDeploy, buildIfNecessaryIOS, buildIfNecessaryAndroid]
|
||||||
|
if: ${{ always() &&
|
||||||
|
(inputs.channel || 'testflight') == 'testflight' &&
|
||||||
|
needs.bundleDeploy.result == 'success' &&
|
||||||
|
(needs.bundleDeploy.outputs.changes-detected != 'true' ||
|
||||||
|
(needs.buildIfNecessaryIOS.result == 'success' &&
|
||||||
|
needs.buildIfNecessaryAndroid.result == 'success')) &&
|
||||||
|
github.repository == 'bluesky-social/social-app' }}
|
||||||
|
permissions:
|
||||||
|
actions: read
|
||||||
|
steps:
|
||||||
|
- name: ⬇️ Download native fingerprint
|
||||||
|
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
||||||
|
with:
|
||||||
|
name: native-fingerprint-${{ github.run_id }}
|
||||||
|
|
||||||
|
- name: 🧐 Validate native fingerprint
|
||||||
|
run: >
|
||||||
|
jq -e '.sources | type == "array"' native-fingerprint.json >/dev/null ||
|
||||||
|
(echo "::error::native fingerprint artifact was invalid; refusing to record it as the baseline." && exit 1)
|
||||||
|
|
||||||
|
- name: 🚀 Record fingerprint baseline
|
||||||
|
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
||||||
|
with:
|
||||||
|
name: testflight-native-fingerprint
|
||||||
|
path: native-fingerprint.json
|
||||||
|
retention-days: 90
|
||||||
|
if-no-files-found: error
|
||||||
|
|||||||
Reference in New Issue
Block a user