diff --git a/.github/workflows/bundle-deploy-eas-update.yml b/.github/workflows/bundle-deploy-eas-update.yml index e5bec8cc77..28308e5073 100644 --- a/.github/workflows/bundle-deploy-eas-update.yml +++ b/.github/workflows/bundle-deploy-eas-update.yml @@ -204,20 +204,19 @@ jobs: SENTRY_DIST=${{ steps.env.outputs.bundle-identifier }} pnpm export - - name: 📦 Package Bundle and 🚀 Deploy - if: ${{ !steps.fingerprint.outputs.includes-changes && - !steps.version.outputs.version-changed }} - run: pnpm use-build-number bash scripts/bundleUpdate.sh - env: - DENIS_API_KEY: ${{ secrets.DENIS_API_KEY }} - RUNTIME_VERSION: ${{ inputs.runtimeVersion }} - CHANNEL_NAME: ${{ inputs.channel || 'testflight' }} - - # The three steps below dual-write the same exported bundle to the new - # denis/S3 service alongside the legacy ota1 upload above. This is a - # deliberate temporary dual-write during the ota1 -> denis migration: - # both paths run and both must succeed. The legacy step above and this - # block are removed together once denis is the sole origin (Phase 5). + # denis on EKS has been the sole origin for updates.bsky.app since + # 2026-07-26, so it publishes FIRST: it is the path that actually serves + # clients. The legacy ota1 upload runs after it, and exists only so that + # rolling the Bunny origin back to ota1 would find current bundles there. + # + # The ordering is load-bearing, not cosmetic. While the legacy step ran + # first, its failure skipped these steps and nothing reached EITHER origin + # -- the dual-write took down the working path with it. Both steps are + # still required to pass, so a stale ota1 remains a loud failure, but the + # publish that serves users has already landed before the legacy one can + # fail. + # + # Both halves are removed together when ota1 is decommissioned (Phase 5). - name: ☁️ Configure AWS credentials (denis) if: ${{ !steps.fingerprint.outputs.includes-changes && !steps.version.outputs.version-changed }} @@ -243,6 +242,15 @@ jobs: RUNTIME_VERSION: ${{ inputs.runtimeVersion }} CHANNEL_NAME: ${{ inputs.channel || 'testflight' }} + - name: 📦 Package Bundle and 🚀 Deploy (legacy ota1) + if: ${{ !steps.fingerprint.outputs.includes-changes && + !steps.version.outputs.version-changed }} + run: pnpm use-build-number bash scripts/bundleUpdate.sh + env: + DENIS_API_KEY: ${{ secrets.DENIS_API_KEY }} + RUNTIME_VERSION: ${{ inputs.runtimeVersion }} + CHANNEL_NAME: ${{ inputs.channel || 'testflight' }} + buildIfNecessaryIOS: name: Build and Submit iOS needs: [bundleDeploy] diff --git a/scripts/bundleUpdate.sh b/scripts/bundleUpdate.sh index 08b9f12d50..0685ecd108 100644 --- a/scripts/bundleUpdate.sh +++ b/scripts/bundleUpdate.sh @@ -15,7 +15,21 @@ fi cd bundleTempDir || exit BUNDLE_VERSION=$(date +%s) -DEPLOYMENT_URL="https://updates.bsky.app/v1/upload?runtime-version=$RUNTIME_VERSION&bundle-version=$BUNDLE_VERSION&channel=$CHANNEL_NAME&ios-build-number=$BSKY_IOS_BUILD_NUMBER&android-build-number=$BSKY_ANDROID_VERSION_CODE" + +# This MUST address ota1's own origin hostname, never updates.bsky.app. +# +# Since the 2026-07-26 cutover updates.bsky.app resolves to denis on EKS, which +# deliberately has no /v1/upload route -- publishing there is out-of-band via +# `denis publish` (see denisPublish.sh). Posting to the CDN hostname therefore +# returns 404, which is what broke this step the first time it ran after the +# flip. The dual-write was never independent of the cutover precisely because it +# addressed the hostname being cut over. +# +# This upload exists only to keep ota1 carrying current bundles so a rollback of +# the Bunny origin remains useful. It goes away with this whole script when ota1 +# is decommissioned (Phase 5). +OTA1_ORIGIN="${OTA1_ORIGIN:-https://ota1.us-east.updates.bsky.network}" +DEPLOYMENT_URL="$OTA1_ORIGIN/v1/upload?runtime-version=$RUNTIME_VERSION&bundle-version=$BUNDLE_VERSION&channel=$CHANNEL_NAME&ios-build-number=$BSKY_IOS_BUILD_NUMBER&android-build-number=$BSKY_ANDROID_VERSION_CODE" tar czvf bundle.tar.gz ./*