Fix the legacy ota1 OTA upload, broken by the denis cutover

The legacy dual-write leg posted to https://updates.bsky.app/v1/upload. That
hostname has resolved to denis on EKS since the 2026-07-26 origin flip, and denis
deliberately has no /v1/upload route -- publishing there is out-of-band via
`denis publish`. The first OTA publish attempted after the flip therefore got a
404 (run 30220289826).

Point it at ota1's own origin instead. The dual-write was never independent of
the cutover: it wrote to ota1 *through the hostname being cut over*, so flipping
the origin necessarily broke it. Addressing ota1 directly is what the step always
meant. Verified reachable: ota1.us-east.updates.bsky.network/v1/upload returns
401 (route present, auth required) where updates.bsky.app returns 404.

Also reorder the two publishes so denis goes first. This is the more serious half
of the bug. The legacy step ran before the denis steps, so when it 404'd the
three denis steps were skipped and the bundle reached NEITHER origin -- a
dual-write that takes down the working path when its deprecated half fails is
worse than no dual-write. denis is the sole origin serving clients, so it
publishes first; the legacy upload follows and is still required to pass, so a
stale ota1 remains a loud failure rather than a silent one.

The upload URL is now overridable via OTA1_ORIGIN, and the comment explains why
it must never be set back to the CDN hostname.

Both halves go away together when ota1 is decommissioned (Phase 5).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Austin McKinley
2026-07-26 14:25:27 -07:00
parent 66ec855efc
commit 952a176c83
2 changed files with 37 additions and 15 deletions
+22 -14
View File
@@ -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]
+15 -1
View File
@@ -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 ./*