-
Notifications
You must be signed in to change notification settings - Fork 1.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add OTA updates support for testflight
channel
#3291
Conversation
The Pull Request introduced fingerprint changes against the base commit: 02b2ab4 Fingerprint diff[
{
"type": "file",
"filePath": ".gitignore",
"reasons": [
"bareGitIgnore"
],
"hash": "34d7809b467aae19b90d91248c1967f54b5613e3"
},
{
"type": "file",
"filePath": "eas.json",
"reasons": [
"easBuild"
],
"hash": "991e1f84ddcc82b0fb25e2f46b6bdfcf088690d7"
},
{
"type": "file",
"filePath": "package.json",
"reasons": [
"expoConfigPlugins"
],
"hash": "2868ff27167ee7ac22c4a5df4bd251302ea9b7f8"
},
{
"type": "dir",
"filePath": "node_modules/expo-updates/ios",
"reasons": [
"expoAutolinkingIos"
],
"hash": "d46bff4299ab6eed3a7e3a2488215fad8eaa164d"
},
{
"type": "dir",
"filePath": "patches",
"reasons": [
"patchPackage"
],
"hash": "e62e799b66ac996950d154bba61d4df5f2171b46"
},
{
"type": "contents",
"id": "expoConfig",
"contents": "{\"android\":{\"adaptiveIcon\":{\"backgroundColor\":\"#1185FE\",\"backgroundImage\":\"./assets/icon-android-background.png\",\"foregroundImage\":\"./assets/icon-android-foreground.png\",\"monochromeImage\":\"./assets/icon-android-foreground.png\"},\"googleServicesFile\":\"./google-services.json\",\"icon\":\"./assets/icon.png\",\"intentFilters\":[{\"action\":\"VIEW\",\"autoVerify\":true,\"category\":[\"BROWSABLE\",\"DEFAULT\"],\"data\":[false,{\"host\":\"bsky.app\",\"scheme\":\"https\"}]}],\"package\":\"xyz.blueskyweb.app\",\"splash\":{\"backgroundColor\":\"#0c7cff\",\"dark\":{\"backgroundColor\":\"#0f141b\",\"image\":\"./assets/splash-dark.png\",\"resizeMode\":\"cover\"},\"image\":\"./assets/splash.png\",\"resizeMode\":\"cover\"}},\"androidStatusBar\":{\"backgroundColor\":\"#00000000\",\"barStyle\":\"light-content\"},\"assetBundlePatterns\":[\"**/*\"],\"extra\":{\"eas\":{\"build\":{\"experimental\":{\"ios\":{\"appExtensions\":[{\"bundleIdentifier\":\"xyz.blueskyweb.app.Share-with-Bluesky\",\"entitlements\":{\"com.apple.security.application-groups\":[\"group.app.bsky\"]},\"targetName\":\"Share-with-Bluesky\"}]}}},\"projectId\":\"55bd077a-d905-4184-9c7f-94789ba0f302\"}},\"hooks\":{\"postPublish\":[{\"config\":{\"dist\":\"undefined.1.76.0.undefined\",\"organization\":\"blueskyweb\",\"project\":\"react-native\",\"release\":\"1.76.0\"},\"file\":\"sentry-expo/upload-sourcemaps\"}]},\"icon\":\"./assets/icon.png\",\"ios\":{\"associatedDomains\":[\"applinks:bsky.app\",\"applinks:staging.bsky.app\"],\"bundleIdentifier\":\"xyz.blueskyweb.app\",\"config\":{\"usesNonExemptEncryption\":false},\"entitlements\":{\"com.apple.security.application-groups\":\"group.app.bsky\"},\"infoPlist\":{\"NSCameraUsageDescription\":\"Used for profile pictures, posts, and other kinds of content.\",\"NSMicrophoneUsageDescription\":\"Used for posts and other kinds of content.\",\"NSPhotoLibraryAddUsageDescription\":\"Used to save images to your library.\",\"NSPhotoLibraryUsageDescription\":\"Used for profile pictures, posts, and other kinds of content\",\"UIBackgroundModes\":[\"remote-notification\"]},\"splash\":{\"backgroundColor\":\"#ffffff\",\"dark\":{\"backgroundColor\":\"#001429\",\"image\":\"./assets/splash-dark.png\",\"resizeMode\":\"cover\"},\"image\":\"./assets/splash.png\",\"resizeMode\":\"cover\"},\"supportsTablet\":false},\"name\":\"Bluesky\",\"orientation\":\"portrait\",\"owner\":\"blueskysocial\",\"platforms\":[\"android\",\"ios\",\"web\"],\"plugins\":[\"./plugins/shareExtension/withShareExtensions.js\",\"./plugins/withAndroidManifestFCMIconPlugin.js\",\"./plugins/withAndroidManifestPlugin.js\",\"./plugins/withAndroidSplashScreenStatusBarTranslucentPlugin.js\",\"./plugins/withAndroidStylesWindowBackgroundPlugin.js\",\"expo-localization\",[\"expo-build-properties\",{\"android\":{\"buildToolsVersion\":\"34.0.0\",\"compileSdkVersion\":34,\"kotlinVersion\":\"1.8.0\",\"newArchEnabled\":false,\"targetSdkVersion\":34},\"ios\":{\"deploymentTarget\":\"13.4\",\"newArchEnabled\":false}}],[\"expo-notifications\",{\"color\":\"#1185fe\",\"icon\":\"./assets/icon-android-notification.png\"}]],\"scheme\":\"bluesky\",\"sdkVersion\":\"50.0.0\",\"slug\":\"bluesky\",\"splash\":{\"backgroundColor\":\"#ffffff\",\"image\":\"./assets/splash.png\",\"resizeMode\":\"cover\"},\"updates\":{\"channel\":\"production\",\"checkAutomatically\":\"NEVER\",\"codeSigningCertificate\":\"./code-signing/certificate.pem\",\"codeSigningMetadata\":{\"alg\":\"rsa-v1_5-sha256\",\"keyid\":\"main\"},\"enabled\":false,\"fallbackToCacheTimeout\":30000,\"url\":\"https://updates.bsky.app/manifest\"},\"userInterfaceStyle\":\"automatic\",\"version\":\"1.76.0\",\"web\":{\"favicon\":\"./assets/favicon.png\"}}",
"reasons": [
"expoConfig"
],
"hash": "ec8665883ccf4478a9d5b3dd09e452af616f67ad"
},
{
"type": "contents",
"id": "packageJson:scripts",
"contents": "{\"prepare\":\"is-ci || husky install\",\"postinstall\":\"patch-package && yarn intl:compile\",\"prebuild\":\"expo prebuild --clean\",\"android\":\"expo run:android\",\"ios\":\"expo run:ios\",\"web\":\"expo start --web\",\"use-build-number\":\"./scripts/useBuildNumberEnv.sh\",\"use-build-number-with-bump\":\"./scripts/useBuildNumberEnvWithBump.sh\",\"build-web\":\"expo export:web && node ./scripts/post-web-build.js && cp -v ./web-build/static/js/*.* ./bskyweb/static/js/\",\"build-all\":\"yarn intl:build && yarn use-build-number-with-bump eas build --platform all\",\"build-ios\":\"yarn use-build-number-with-bump eas build -p ios\",\"build-android\":\"yarn use-build-number-with-bump eas build -p android\",\"build\":\"yarn use-build-number-with-bump eas build\",\"start\":\"expo start --dev-client\",\"start:prod\":\"expo start --dev-client --no-dev --minify\",\"clean-cache\":\"rm -rf node_modules/.cache/babel-loader/*\",\"test\":\"NODE_ENV=test jest --forceExit --testTimeout=20000 --bail\",\"test-watch\":\"NODE_ENV=test jest --watchAll\",\"test-ci\":\"NODE_ENV=test jest --ci --forceExit --reporters=default --reporters=jest-junit\",\"test-coverage\":\"NODE_ENV=test jest --coverage\",\"lint\":\"eslint --cache --ext .js,.jsx,.ts,.tsx src\",\"typecheck\":\"tsc --project ./tsconfig.check.json\",\"e2e:mock-server\":\"./jest/dev-infra/with-test-redis-and-db.sh ts-node --project tsconfig.e2e.json __e2e__/mock-server.ts\",\"e2e:metro\":\"NODE_ENV=test RN_SRC_EXT=e2e.ts,e2e.tsx expo run:ios\",\"e2e:build\":\"NODE_ENV=test detox build -c ios.sim.debug\",\"e2e:run\":\"NODE_ENV=test detox test --configuration ios.sim.debug --take-screenshots all\",\"perf:test\":\"NODE_ENV=test maestro test\",\"perf:test:run\":\"NODE_ENV=test maestro test __e2e__/maestro/scroll.yaml\",\"perf:test:measure\":\"NODE_ENV=test flashlight test --bundleId xyz.blueskyweb.app --testCommand 'yarn perf:test' --duration 150000 --resultsFilePath .perf/results.json\",\"perf:test:results\":\"NODE_ENV=test flashlight report .perf/results.json\",\"perf:measure\":\"NODE_ENV=test flashlight measure\",\"intl:build\":\"yarn intl:extract && yarn intl:compile\",\"intl:check\":\"yarn intl:extract && git diff-index -G'(^[^\\\\*# /])|(^#\\\\w)|(^\\\\s+[^\\\\*#/])' HEAD || (echo '\\n⚠️ i18n detected un-extracted translations\\n' && exit 1)\",\"intl:extract\":\"lingui extract\",\"intl:compile\":\"lingui compile\",\"nuke\":\"rm -rf ./node_modules && rm -rf ./ios && rm -rf ./android\",\"update-extensions\":\"bash scripts/updateExtensions.sh\",\"export\":\"npx expo export\"}",
"reasons": [
"packageJson:scripts"
],
"hash": "4247ebb9a76cda7a18bb1e346a43d96908ffde6a"
}
] Generated by PR labeler 🤖 |
another adjustment, testing another adjustment, testing fix again fix again set default runtime version fix test this script test this script test this script add build numbers to the deployment url clean give script access to build number add `useBuildNumberEnv` without a bump new line fix missing async add channel name to deployment url add updates check on launch for testflight users ver bump init updates on launch for native add `testflight` as default in build submit add is_testflight check
a2c0019
to
f1cdc4e
Compare
This reverts commit 44c5113.
version bump adjust fixes test
134adb3
to
2b5056a
Compare
drop check down to every 15 minutes adjustments change to 15 mins use jq to get version if necessary rm test on push figured it out remove nightly testflight releases test again again again again again AGAIN ONCE MORE test again again again again again AGAIN test again again again again again AGAIN test again again again again again test again again again again test again again again test again again test again test test test run deploy if necessary run deploy if necessary run deploy if necessary run deploy if necessary run deploy if necessary remove test message fix environment oops cleanup merge in changes
0772a63
to
e3065c8
Compare
testflight
vs production
channels for expo-updates
testflight
channel
0d67811
to
e011399
Compare
@@ -69,7 +68,7 @@ jobs: | |||
echo "${{ secrets.GOOGLE_SERVICES_TOKEN }}" > google-services.json | |||
|
|||
- name: 🏗️ EAS Build | |||
run: yarn use-build-number eas build -p ios --profile production --local --output build.ipa --non-interactive | |||
run: yarn use-build-number eas build -p ios --profile ${{ inputs.profile || 'testflight' }} --local --output build.ipa --non-interactive |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the --profile
flag here determines what EXPO_PUBLIC_ENV
gets set to.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM! So pumped for this 🔥
As you mentioned in Slack, let's do another quick look at Android too
"preview": { | ||
"extends": "base", | ||
"distribution": "internal", | ||
"channel": "preview", | ||
"channel": "production", | ||
"ios": { | ||
"resourceClass": "large" | ||
}, | ||
"env": { | ||
"EXPO_PUBLIC_ENV": "production" | ||
} | ||
}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this preview
profile was only added for APK builds (happens bc of distribution: 'internal'
). Could maybe remove if we can build APKs with the testflight
profile.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah interesting. I think what I'll do for now then is set this one to use testflight
channel, since we'll still need to do Android builds locally until we figure out the Google Play alpha builds stuff.
@@ -0,0 +1,7 @@ | |||
# Expo-Updates Patch |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Super appreciate this md 🙏
update git ignore rm test stuff from the bundle action remove test message test message fix test message test message few android fixes few android fixes fix jq add a test message fix slack webhook create android deployments test 2 create android deployments add `testflight-android` profile to eas.json more cleanup some more cleanup simplify some logic remove unnecessary channel rename to `useOTAUpdates`
f60bdae
to
4e581b7
Compare
Why
This PR adds OTA update functionality to the app. Updates will use the
updates.bsky.app
service, which is based on the Expo Updates protocol. https://github.com/expo/custom-expo-updates-serverThere are two channels for updates:
production
andtestflight
. In this PR, we are only enabling thetestflight
channel. Users that are using the production app will not receive OTA updates, and the production client will not make any requests to the server at this time.After some time of testing the internal channel, we can enable the
production
channel to start getting a sense of how many requests are going to the server and to see if there are any changes we need to make there. The good news is that even if the server goes down or starts returning errors, the client will simply ignore the requests/errors and continue to operate normally.We should also update the workflow at a later point to support automatic deployments to the staging server, as well as manual workflow for releasing to web.
Workflow
How Channels Work
There is an environemtn variable inside of
.env
calledEXPO_PUBLIC_ENV
that can be either set toproduction
ortestflight
depending on how we run the release. Usingeas build --profile testflight
for example will automatically setEXPO_PUBLIC_ENV
totestflight
. This will set the app to download updates from thetestflight
channel. Likewise, usingeas build --profile production
will set the app to download updates from theproduction
channel.There should not be any changes to our current workflow when submitting new releases to the app store. The GitHub action is configured to either use the
testflight
orproduction
channel now. @pfrazee notably it might be worth taking a moment to properly add the credentials for Google Play to make Android releases easier, but the workflow that you are using for submitting Android builds right now will also continue to be supported.How Updates Work
New builds (i.e. a build that we are submitting to the App Store) will not immediately have any OTA updates available for it. In that case, the JS bundle included in the .ipa/.aab will be used by the client. Whenever an OTA update is released however, the .ipa/.aab's JS bundle will not be used in favor of the JS bundle downloaded from our updates server.
In the event that the downloaded JS bundle causes any issues, the client will fall back to using the .ipa/.aab's JS bundle.
We use
expo-fingerprint
in the GitHub action as well to prevent any accidental deployments that are not compatible with the current runtime version. I.e., if we updated a package that uses native code such asreact-navigation
, there's a chance that the JS code used byreact-navigation
would not be compatible with the native code the library uses. Therefore, we will cancel and fail these deployments.