020a85f029
bundleUpdate.sh and denisPublish.sh each called `date +%s`, so a single dual-write
gave the same bytes two different bundle versions -- observed 1785102575 (denis)
and 1785102614 (ota1), 39 seconds apart, for commit b662cd43b.
That is not cosmetic. The bundle version is a path segment in every asset URL the
manifest hands the client:
https://updates.bsky.app/file/1.130.0/<bundle-version>/bundles/<hash>
Both origins mint those URLs against updates.bsky.app, which resolves to whichever
origin Bunny currently points at. So each origin was serving a manifest whose
assets only IT has. A manifest fetched from one origin and assets fetched from the
other 404s -- which is exactly what a rollback of the Bunny origin does if it lands
between a client's manifest fetch and its asset fetch. The dual-write existed to
make rollback safe and was quietly making it unsafe.
Pin the version once in the job and let both scripts inherit it. Both fall back to
`date +%s` when BUNDLE_VERSION is unset, so the single-publisher callers are
unchanged: pull-request-commit.yml (denis only) and `pnpm make-deploy-bundle`.
The fallback uses `:-` rather than `-`, so an empty value also falls back --
`denis publish` rejects a non-numeric bundle version, so an empty one must never
propagate.
This does not make the two manifests byte-identical. createdAt still differs
(21:49:35Z vs 21:50:18Z for the commit above) because ota1's legacy uploader
stamps it server-side on receipt; the client posts a tarball, not a timestamp, so
nothing here can align it. That residual is inert in a way the bundle version was
not: the manifest id is content-addressed on metadata.json and is identical across
origins, so manifestHandler's `currentUpdateID == entry.Manifest.ID` check makes a
client that switches origins see the same update rather than a newer one. It goes
away with the dual-write in Phase 5.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
55 lines
2.1 KiB
Bash
Executable File
55 lines
2.1 KiB
Bash
Executable File
#!/bin/bash
|
|
set -o errexit
|
|
set -o pipefail
|
|
set -o nounset
|
|
|
|
# Publishes the just-exported Expo bundle to the denis OTA service (S3) via the
|
|
# `denis publish` CLI. Mirrors bundleUpdate.sh's inputs (runtime version, bundle
|
|
# version, build numbers) but targets denis instead of the legacy ota1 upload.
|
|
# Expects: the `denis` binary on PATH (setup-denis action), ambient AWS creds
|
|
# (configure-aws-credentials OIDC), and BSKY_IOS_BUILD_NUMBER /
|
|
# BSKY_ANDROID_VERSION_CODE from the use-build-number wrapper.
|
|
|
|
rm -rf bundleTempDir
|
|
|
|
echo "Assembling bundle directory..."
|
|
node scripts/bundleUpdate.js
|
|
|
|
if [ -z "$RUNTIME_VERSION" ]; then
|
|
RUNTIME_VERSION=$(cat package.json | jq '.version' -r)
|
|
fi
|
|
|
|
# Accept a caller-supplied bundle version so that a dual-write publishes the SAME
|
|
# version to every origin. When this script and bundleUpdate.sh each called
|
|
# `date +%s` independently they produced versions seconds apart for identical
|
|
# bytes -- observed 1785102575 (denis) vs 1785102614 (ota1) for one commit. Since
|
|
# the version is part of the asset URL path, the two origins then served
|
|
# manifests pointing at paths only one of them had, so the manifest and its
|
|
# assets had to come from the same origin or the fetch 404s. Falling back to
|
|
# `date +%s` keeps standalone callers (PR previews, `pnpm make-deploy-bundle`)
|
|
# working unchanged.
|
|
BUNDLE_VERSION="${BUNDLE_VERSION:-$(date +%s)}"
|
|
DENIS_CDN_DOMAIN="${DENIS_CDN_DOMAIN:-updates.bsky.app}"
|
|
DENIS_S3_BUCKET="${DENIS_S3_BUCKET:-bsky-denis-ota-prod}"
|
|
|
|
echo "Publishing to denis..."
|
|
echo " runtime-version: $RUNTIME_VERSION"
|
|
echo " bundle-version: $BUNDLE_VERSION"
|
|
echo " channel: $CHANNEL_NAME"
|
|
echo " ios-build-number: $BSKY_IOS_BUILD_NUMBER"
|
|
echo " android-build-number: $BSKY_ANDROID_VERSION_CODE"
|
|
echo " cdn-domain: $DENIS_CDN_DOMAIN"
|
|
echo " s3-bucket: $DENIS_S3_BUCKET"
|
|
|
|
denis publish \
|
|
--bundle-dir bundleTempDir \
|
|
--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" \
|
|
--cdn-domain "$DENIS_CDN_DOMAIN" \
|
|
--s3-bucket "$DENIS_S3_BUCKET"
|
|
|
|
rm -rf bundleTempDir
|