Compare commits

...

38 Commits

Author SHA1 Message Date
Eric Bailey 56b3b357f1 Add debug screen 2025-07-28 17:50:42 -05:00
Eric Bailey 4c35228764 Remove TF check for BUNDLE_DATE 2025-07-28 17:50:21 -05:00
Eric Bailey 7ada116ef0 Just fallback to package version for Render deploys 2025-07-28 17:45:45 -05:00
Eric Bailey 0afd105346 Update webpack to use same SENTRY_RELEASE var 2025-07-28 17:06:59 -05:00
Eric Bailey b9d44eb31b Add new env setup to missed OTA spot 2025-07-28 17:04:49 -05:00
Eric Bailey f173cc32c0 Align on RELEASE_VERSION 2025-07-28 17:02:02 -05:00
Eric Bailey 6fe61b9b78 Pass in sentry CLI env vars, align matching values 2025-07-28 17:00:59 -05:00
Eric Bailey 5beaabe01d Fix missing space in ios workflow 2025-07-28 14:15:17 -05:00
Eric Bailey c24df11c7d Slice full hash for display in app 2025-07-28 14:15:17 -05:00
Eric Bailey 9d0da258a1 Just use long commit hash 2025-07-28 14:15:17 -05:00
Eric Bailey 275dccb25b Remove unnecessary testflight check 2025-07-28 14:15:17 -05:00
Eric Bailey 3e2f91b8b1 Remove invalid syntax 2025-07-28 14:15:17 -05:00
Eric Bailey e916516abd Fix render substitution syntax 2025-07-28 14:15:17 -05:00
Eric Bailey 59a5dbb992 Add PACKAGE_VERSION and replace in statsig to fix conflict 2025-07-28 14:15:17 -05:00
Eric Bailey b4c0631c75 Update webpack Sentry dist value based on prev commits 2025-07-28 14:15:17 -05:00
Eric Bailey fdcbdec873 Revert Sentry patch as a result of prev commit 2025-07-28 14:15:17 -05:00
Eric Bailey 3361902f8b Clarify build process env vars and ensure they are explicitly passed in 2025-07-28 14:15:17 -05:00
Eric Bailey 78647ca44d Trim RENDER_GIT_COMMIT to first 7 to match --short sha 2025-07-28 14:15:17 -05:00
Eric Bailey bfc8bb9d44 Update BUNDLE_DATE format comment 2025-07-28 14:15:17 -05:00
Eric Bailey 09dcc384f4 [APP-1331] Migrate app-info to new env (#8703)
* Move env files into directory with platform specific files

* Migrate usages of app-info to new env

* Fix bad import
2025-07-28 14:15:17 -05:00
Eric Bailey 4979cbb991 Slice bundle hash to match other platforms, needed for render.com deployments 2025-07-28 14:15:17 -05:00
Eric Bailey 8bd98cc223 Update IS_TESTFLIGHT to include testflight-android 2025-07-28 14:15:17 -05:00
Eric Bailey eff64d4c0c Make sure EXPO_PUBLIC_ENV is set for web container builds 2025-07-28 14:15:17 -05:00
Eric Bailey b06c18e0de Echo variables to .env in Dockerfile instead of passing to shell script 2025-07-28 14:15:17 -05:00
Eric Bailey c33ab5cb81 Properly patch Sentry package 2025-07-28 14:15:17 -05:00
Eric Bailey 5894f41fe8 Self review 2025-07-28 14:15:17 -05:00
Eric Bailey 24c1fdb717 Replace NODE_ENV in places where its safe 2025-07-28 14:15:17 -05:00
Eric Bailey ce81f8ac91 Remove debugging field 2025-07-28 14:15:17 -05:00
Eric Bailey 78c22a37cd Prefix SENTRY_DSN with EXPO_PUBLIC to match others 2025-07-28 14:15:17 -05:00
Eric Bailey f40530e968 Deprecate SENTRY_DIST in favor of EXPO_PUBLIC_BUNDLE_IDENTIFIER 2025-07-28 14:15:17 -05:00
Eric Bailey 53624a22bc Fix missing bundle identifier for Render deploys 2025-07-28 14:15:17 -05:00
Eric Bailey 2f5a4e4ff3 Use existing EXPO_PUBLIC_BUNDLE_IDENTIFIER short commit has as Sentry dist value 2025-07-28 14:15:17 -05:00
Eric Bailey 37deba7653 Deprecate SENTRY_RELEASE since we use package.json now 2025-07-28 14:15:17 -05:00
Eric Bailey 281bf6cd25 Prefix Bitdrift key with EXPO_PUBLIC 2025-07-28 14:15:17 -05:00
Eric Bailey 3e9ba0dcf5 Use new env in chat proxy header 2025-07-28 14:15:17 -05:00
Eric Bailey c1462fca7c Use new env in Bitdrift setup file 2025-07-28 14:15:17 -05:00
Eric Bailey bb86265cd0 Use new env in Sentry setup file 2025-07-28 14:15:17 -05:00
Eric Bailey 0d74630b5d Clean up env files 2025-07-28 14:15:17 -05:00
27 changed files with 314 additions and 167 deletions
+29 -5
View File
@@ -1,8 +1,32 @@
# Copy this to `.env` and `.env.test` files
# The env the app is running in e.g. development, testflight, production
EXPO_PUBLIC_ENV=development
BITDRIFT_API_KEY=
SENTRY_AUTH_TOKEN=
EXPO_PUBLIC_LOG_LEVEL=debug
EXPO_PUBLIC_LOG_DEBUG=
# This is the semver release version of the app, pulled from package.json
EXPO_PUBLIC_RELEASE_VERSION=
# This is the commit hash that the current bundle was made from.
EXPO_PUBLIC_BUNDLE_IDENTIFIER=
# Should be formatted YYMMDDHH so that it increases for each build.
EXPO_PUBLIC_BUNDLE_DATE=0
# The log level for the app's logger transports
EXPO_PUBLIC_LOG_LEVEL=debug
# Enable debug logs for specific logger instances
EXPO_PUBLIC_LOG_DEBUG=session
# Chat service DID
EXPO_PUBLIC_CHAT_PROXY_DID=
#
#
# Bluesky specific values
#
#
# Sentry DSN for telemetry
EXPO_PUBLIC_SENTRY_DSN=
# Bitdrift API key. If undefined, Bitdrift will be disabled.
EXPO_PUBLIC_BITDRIFT_API_KEY=
@@ -43,12 +43,11 @@ jobs:
tags: |
type=sha,enable=true,priority=100,prefix=,suffix=,format=long
- name: Set outputs
id: vars
- name: Setup env
id: env
run: |
echo "sha_short=$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT
echo "SENTRY_DIST=$(git rev-parse HEAD)" >> $GITHUB_OUTPUT
echo "SENTRY_RELEASE=$(jq -r '.version' package.json)" >> $GITHUB_OUTPUT
echo "EXPO_PUBLIC_RELEASE_VERSION=$(jq -r '.version' package.json)" >> $GITHUB_OUTPUT
echo "EXPO_PUBLIC_BUNDLE_IDENTIFIER=$(git rev-parse HEAD)" >> $GITHUB_OUTPUT
- name: Build and push Docker image
id: build-and-push
@@ -62,8 +61,8 @@ jobs:
cache-from: type=gha
cache-to: type=gha,mode=max
build-args: |
EXPO_PUBLIC_BUNDLE_IDENTIFIER=${{ steps.vars.outputs.sha_short }}
SENTRY_DIST=${{ steps.vars.outputs.SENTRY_DIST }}
SENTRY_RELEASE=${{ steps.vars.outputs.SENTRY_RELEASE }}
EXPO_PUBLIC_ENV=production
EXPO_PUBLIC_RELEASE_VERSION=${{ steps.env.outputs.EXPO_PUBLIC_RELEASE_VERSION }}
EXPO_PUBLIC_BUNDLE_IDENTIFIER=${{ steps.env.outputs.EXPO_PUBLIC_BUNDLE_IDENTIFIER }}
EXPO_PUBLIC_SENTRY_DSN=${{ secrets.SENTRY_DSN }}
SENTRY_AUTH_TOKEN=${{ secrets.SENTRY_AUTH_TOKEN }}
SENTRY_DSN=${{ secrets.SENTRY_DSN }}
+25 -11
View File
@@ -62,23 +62,30 @@ jobs:
- name: Check for i18n compilation errors
run: if grep -q "invalid syntax" "i18n.log"; then echo "\n\nFound compilation errors!\n\n" && exit 1; else echo "\n\nNo compilation errors!\n\n"; fi
- name: ✏️ Write environment variables
# EXPO_PUBLIC_ENV is handled in eas.json
- name: Env
id: env
run: |
export json='${{ secrets.GOOGLE_SERVICES_TOKEN }}'
echo "${{ secrets.ENV_TOKEN }}" > .env
echo "EXPO_PUBLIC_BUNDLE_IDENTIFIER=$(git rev-parse --short HEAD)" >> .env
echo "EXPO_PUBLIC_RELEASE_VERSION=$(jq -r '.version' package.json)" >> .env
echo "EXPO_PUBLIC_RELEASE_VERSION=$(jq -r '.version' package.json)" >> $GITHUB_OUTPUT
echo "EXPO_PUBLIC_BUNDLE_IDENTIFIER=$(git rev-parse HEAD)" >> .env
echo "EXPO_PUBLIC_BUNDLE_IDENTIFIER=$(git rev-parse HEAD)" >> $GITHUB_OUTPUT
echo "EXPO_PUBLIC_BUNDLE_DATE=$(date -u +"%y%m%d%H")" >> .env
echo "BITDRIFT_API_KEY=${{ secrets.BITDRIFT_API_KEY }}" >> .env
echo "EXPO_PUBLIC_SENTRY_DSN=${{ secrets.SENTRY_DSN }}" >> .env
echo "EXPO_PUBLIC_BITDRIFT_API_KEY=${{ secrets.BITDRIFT_API_KEY }}" >> .env
echo "$json" > google-services.json
- name: Setup Sentry vars for build-time injection
id: sentry
run: |
echo "SENTRY_DIST=$(git rev-parse HEAD)" >> $GITHUB_OUTPUT
echo "SENTRY_RELEASE=$(jq -r '.version' package.json)" >> $GITHUB_OUTPUT
- name: 🏗️ EAS Build
run: SENTRY_DIST=${{ steps.sentry.outputs.SENTRY_DIST }} SENTRY_RELEASE=${{ steps.sentry.outputs.SENTRY_RELEASE }} SENTRY_AUTH_TOKEN=${{ secrets.SENTRY_AUTH_TOKEN }} SENTRY_DSN=${{ secrets.SENTRY_DSN }} yarn use-build-number-with-bump eas build -p android --profile ${{ inputs.profile || 'testflight-android' }} --local --output build.aab --non-interactive
run: >
SENTRY_AUTH_TOKEN=${{ secrets.SENTRY_AUTH_TOKEN }}
SENTRY_RELEASE=${{ steps.env.outputs.EXPO_PUBLIC_RELEASE_VERSION }}
SENTRY_DIST=${{ steps.env.outputs.EXPO_PUBLIC_BUNDLE_IDENTIFIER }}
yarn use-build-number-with-bump
eas build -p android
--profile ${{ inputs.profile || 'testflight-android' }}
--local --output build.aab --non-interactive
- name: ✍️ Rename Testflight bundle
if: ${{ inputs.profile != 'production' }}
@@ -140,7 +147,14 @@ jobs:
- name: 🏗️ Build Production APK
if: ${{ inputs.profile == 'production' }}
run: SENTRY_DIST=${{ steps.sentry.outputs.SENTRY_DIST }} SENTRY_RELEASE=${{ steps.sentry.outputs.SENTRY_RELEASE }} SENTRY_AUTH_TOKEN=${{ secrets.SENTRY_AUTH_TOKEN }} SENTRY_DSN=${{ secrets.SENTRY_DSN }} yarn use-build-number-with-bump eas build -p android --profile production-apk --local --output build.apk --non-interactive
run: >
SENTRY_AUTH_TOKEN=${{ secrets.SENTRY_AUTH_TOKEN }}
SENTRY_RELEASE=${{ steps.env.outputs.EXPO_PUBLIC_RELEASE_VERSION }}
SENTRY_DIST=${{ steps.env.outputs.EXPO_PUBLIC_BUNDLE_IDENTIFIER }}
yarn use-build-number-with-bump
eas build -p android
--profile production-apk
--local --output build.apk --non-interactive
- name: 🚀 Upload Production APK Artifact
id: upload-artifact-production-apk
+16 -9
View File
@@ -75,22 +75,29 @@ jobs:
- name: Check for i18n compilation errors
run: if grep -q "invalid syntax" "i18n.log"; then echo "\n\nFound compilation errors!\n\n" && exit 1; else echo "\n\nNo compilation errors!\n\n"; fi
# EXPO_PUBLIC_ENV is handled in eas.json
- name: ✏️ Write environment variables
id: env
run: |
echo "${{ secrets.ENV_TOKEN }}" > .env
echo "EXPO_PUBLIC_BUNDLE_IDENTIFIER=$(git rev-parse --short HEAD)" >> .env
echo "EXPO_PUBLIC_RELEASE_VERSION=$(jq -r '.version' package.json)" >> .env
echo "EXPO_PUBLIC_RELEASE_VERSION=$(jq -r '.version' package.json)" >> $GITHUB_OUTPUT
echo "EXPO_PUBLIC_BUNDLE_IDENTIFIER=$(git rev-parse HEAD)" >> .env
echo "EXPO_PUBLIC_BUNDLE_IDENTIFIER=$(git rev-parse HEAD)" >> $GITHUB_OUTPUT
echo "EXPO_PUBLIC_BUNDLE_DATE=$(date -u +"%y%m%d%H")" >> .env
echo "BITDRIFT_API_KEY=${{ secrets.BITDRIFT_API_KEY }}" >> .env
echo "EXPO_PUBLIC_SENTRY_DSN=${{ secrets.SENTRY_DSN }}" >> .env
echo "EXPO_PUBLIC_BITDRIFT_API_KEY=${{ secrets.BITDRIFT_API_KEY }}" >> .env
echo "${{ secrets.GOOGLE_SERVICES_TOKEN }}" > google-services.json
- name: Setup Sentry vars for build-time injection
id: sentry
run: |
echo "SENTRY_DIST=$(git rev-parse HEAD)" >> $GITHUB_OUTPUT
echo "SENTRY_RELEASE=$(jq -r '.version' package.json)" >> $GITHUB_OUTPUT
- name: 🏗️ EAS Build
run: SENTRY_DIST=${{ steps.sentry.outputs.SENTRY_DIST }} SENTRY_RELEASE=${{ steps.sentry.outputs.SENTRY_RELEASE }} SENTRY_AUTH_TOKEN=${{ secrets.SENTRY_AUTH_TOKEN }} SENTRY_DSN=${{ secrets.SENTRY_DSN }} yarn use-build-number-with-bump eas build -p ios --profile ${{ inputs.profile || 'testflight' }} --local --output build.ipa --non-interactive
run: >
SENTRY_AUTH_TOKEN=${{ secrets.SENTRY_AUTH_TOKEN }}
SENTRY_RELEASE=${{ steps.env.outputs.EXPO_PUBLIC_RELEASE_VERSION }}
SENTRY_DIST=${{ steps.env.outputs.EXPO_PUBLIC_BUNDLE_IDENTIFIER }}
yarn use-build-number-with-bump
eas build -p ios
--profile ${{ inputs.profile || 'testflight' }}
--local --output build.ipa --non-interactive
- name: 🚀 Deploy
run: eas submit -p ios --non-interactive --path build.ipa
+47 -18
View File
@@ -101,25 +101,30 @@ jobs:
if: ${{ !steps.fingerprint.outputs.includes-changes }}
uses: dcarbone/install-jq-action@v2
- name: ✏️ Write environment variables
# EXPO_PUBLIC_ENV is handled in eas.json
- name: Env
id: env
if: ${{ !steps.fingerprint.outputs.includes-changes }}
run: |
export json='${{ secrets.GOOGLE_SERVICES_TOKEN }}'
echo "${{ secrets.ENV_TOKEN }}" > .env
echo "EXPO_PUBLIC_BUNDLE_IDENTIFIER=$(git rev-parse --short HEAD)" >> .env
echo "EXPO_PUBLIC_RELEASE_VERSION=$(jq -r '.version' package.json)" >> .env
echo "EXPO_PUBLIC_RELEASE_VERSION=$(jq -r '.version' package.json)" >> $GITHUB_OUTPUT
echo "EXPO_PUBLIC_BUNDLE_IDENTIFIER=$(git rev-parse HEAD)" >> .env
echo "EXPO_PUBLIC_BUNDLE_IDENTIFIER=$(git rev-parse HEAD)" >> $GITHUB_OUTPUT
echo "EXPO_PUBLIC_BUNDLE_DATE=$(date -u +"%y%m%d%H")" >> .env
echo "BITDRIFT_API_KEY=${{ secrets.BITDRIFT_API_KEY }}" >> .env
echo "EXPO_PUBLIC_SENTRY_DSN=${{ secrets.SENTRY_DSN }}" >> .env
echo "EXPO_PUBLIC_BITDRIFT_API_KEY=${{ secrets.BITDRIFT_API_KEY }}" >> .env
echo "$json" > google-services.json
- name: Setup Sentry vars for build-time injection
id: sentry
run: |
echo "SENTRY_DIST=$(git rev-parse HEAD)" >> $GITHUB_OUTPUT
echo "SENTRY_RELEASE=$(jq -r '.version' package.json)" >> $GITHUB_OUTPUT
# TODO do we need EXPO_PUBLIC_ENV here?
- name: 🏗️ Create Bundle
if: ${{ !steps.fingerprint.outputs.includes-changes }}
run: SENTRY_DIST=${{ steps.sentry.outputs.SENTRY_DIST }} SENTRY_RELEASE=${{ steps.sentry.outputs.SENTRY_RELEASE }} SENTRY_AUTH_TOKEN=${{ secrets.SENTRY_AUTH_TOKEN }} SENTRY_DSN=${{ secrets.SENTRY_DSN }} EXPO_PUBLIC_ENV="${{ inputs.channel || 'testflight' }}" yarn export
run: >
SENTRY_AUTH_TOKEN=${{ secrets.SENTRY_AUTH_TOKEN }}
SENTRY_RELEASE=${{ steps.env.outputs.EXPO_PUBLIC_RELEASE_VERSION }}
SENTRY_DIST=${{ steps.env.outputs.EXPO_PUBLIC_BUNDLE_IDENTIFIER }}
yarn export
- name: 📦 Package Bundle and 🚀 Deploy
if: ${{ !steps.fingerprint.outputs.includes-changes }}
@@ -205,16 +210,28 @@ jobs:
- name: 🔤 Compile translations
run: yarn intl:build
- name: ✏️ Write environment variables
- name: Env
id: env
run: |
echo "${{ secrets.ENV_TOKEN }}" > .env
echo "EXPO_PUBLIC_BUNDLE_IDENTIFIER=$(git rev-parse --short HEAD)" >> .env
echo "EXPO_PUBLIC_RELEASE_VERSION=$(jq -r '.version' package.json)" >> .env
echo "EXPO_PUBLIC_RELEASE_VERSION=$(jq -r '.version' package.json)" >> $GITHUB_OUTPUT
echo "EXPO_PUBLIC_BUNDLE_IDENTIFIER=$(git rev-parse HEAD)" >> .env
echo "EXPO_PUBLIC_BUNDLE_IDENTIFIER=$(git rev-parse HEAD)" >> $GITHUB_OUTPUT
echo "EXPO_PUBLIC_BUNDLE_DATE=$(date -u +"%y%m%d%H")" >> .env
echo "BITDRIFT_API_KEY=${{ secrets.BITDRIFT_API_KEY }}" >> .env
echo "EXPO_PUBLIC_SENTRY_DSN=${{ secrets.SENTRY_DSN }}" >> .env
echo "EXPO_PUBLIC_BITDRIFT_API_KEY=${{ secrets.BITDRIFT_API_KEY }}" >> .env
echo "${{ secrets.GOOGLE_SERVICES_TOKEN }}" > google-services.json
- name: 🏗️ EAS Build
run: yarn use-build-number-with-bump eas build -p ios --profile testflight --local --output build.ipa --non-interactive
run: >
SENTRY_AUTH_TOKEN=${{ secrets.SENTRY_AUTH_TOKEN }}
SENTRY_RELEASE=${{ steps.env.outputs.EXPO_PUBLIC_RELEASE_VERSION }}
SENTRY_DIST=${{ steps.env.outputs.EXPO_PUBLIC_BUNDLE_IDENTIFIER }}
yarn use-build-number-with-bump
eas build -p ios
--profile testflight
--local --output build.ipa --non-interactive
- name: 🚀 Deploy
run: eas submit -p ios --non-interactive --path build.ipa
@@ -282,17 +299,29 @@ jobs:
- name: 🔤 Compile translations
run: yarn intl:build
- name: ✏️ Write environment variables
- name: Env
id: env
run: |
export json='${{ secrets.GOOGLE_SERVICES_TOKEN }}'
echo "${{ secrets.ENV_TOKEN }}" > .env
echo "EXPO_PUBLIC_BUNDLE_IDENTIFIER=$(git rev-parse --short HEAD)" >> .env
echo "EXPO_PUBLIC_RELEASE_VERSION=$(jq -r '.version' package.json)" >> .env
echo "EXPO_PUBLIC_RELEASE_VERSION=$(jq -r '.version' package.json)" >> $GITHUB_OUTPUT
echo "EXPO_PUBLIC_BUNDLE_IDENTIFIER=$(git rev-parse HEAD)" >> .env
echo "EXPO_PUBLIC_BUNDLE_IDENTIFIER=$(git rev-parse HEAD)" >> $GITHUB_OUTPUT
echo "EXPO_PUBLIC_BUNDLE_DATE=$(date -u +"%y%m%d%H")" >> .env
echo "BITDRIFT_API_KEY=${{ secrets.BITDRIFT_API_KEY }}" >> .env
echo "EXPO_PUBLIC_SENTRY_DSN=${{ secrets.SENTRY_DSN }}" >> .env
echo "EXPO_PUBLIC_BITDRIFT_API_KEY=${{ secrets.BITDRIFT_API_KEY }}" >> .env
echo "$json" > google-services.json
- name: 🏗️ EAS Build
run: yarn use-build-number-with-bump eas build -p android --profile testflight-android --local --output build.apk --non-interactive
run: >
SENTRY_AUTH_TOKEN=${{ secrets.SENTRY_AUTH_TOKEN }}
SENTRY_RELEASE=${{ steps.env.outputs.EXPO_PUBLIC_RELEASE_VERSION }}
SENTRY_DIST=${{ steps.env.outputs.EXPO_PUBLIC_BUNDLE_IDENTIFIER }}
yarn use-build-number-with-bump
eas build -p android
--profile testflight-android
--local --output build.apk --non-interactive
- name: ⏰ Get a timestamp
id: timestamp
+16 -13
View File
@@ -19,28 +19,28 @@ ENV GOARCH="amd64"
ENV CGO_ENABLED=1
ENV GOEXPERIMENT="loopvar"
# The latest git hash of the preview branch on render.com
# https://render.com/docs/docker-secrets#environment-variables-in-docker-builds
ARG RENDER_GIT_COMMIT
#
# Expo
#
ARG EXPO_PUBLIC_ENV
ENV EXPO_PUBLIC_ENV=${EXPO_PUBLIC_ENV:-development}
ARG EXPO_PUBLIC_RELEASE_VERSION
ENV EXPO_PUBLIC_RELEASE_VERSION=$EXPO_PUBLIC_RELEASE_VERSION
ARG EXPO_PUBLIC_BUNDLE_IDENTIFIER
ENV EXPO_PUBLIC_BUNDLE_IDENTIFIER=${EXPO_PUBLIC_BUNDLE_IDENTIFIER:-dev}
# The latest git hash of the preview branch on render.com
ARG RENDER_GIT_COMMIT
# If not set by GitHub workflows, we're probably in Render
ENV EXPO_PUBLIC_BUNDLE_IDENTIFIER=${EXPO_PUBLIC_BUNDLE_IDENTIFIER:-$RENDER_GIT_COMMIT}
#
# Sentry
#
ARG SENTRY_AUTH_TOKEN
ENV SENTRY_AUTH_TOKEN=${SENTRY_AUTH_TOKEN:-unknown}
# Will fall back to package.json#version, but this is handled elsewhere
ARG SENTRY_RELEASE
ENV SENTRY_RELEASE=$SENTRY_RELEASE
ARG SENTRY_DIST
# Default to RENDER_GIT_COMMIT if not set by GitHub workflows
ENV SENTRY_DIST=${SENTRY_DIST:-$RENDER_GIT_COMMIT}
ARG SENTRY_DSN
ENV SENTRY_DSN=$SENTRY_DSN
ARG EXPO_PUBLIC_SENTRY_DSN
ENV EXPO_PUBLIC_SENTRY_DSN=$EXPO_PUBLIC_SENTRY_DSN
#
# Copy everything into the container
@@ -60,13 +60,16 @@ RUN \. "$NVM_DIR/nvm.sh" && \
nvm install $NODE_VERSION && \
nvm use $NODE_VERSION && \
echo "Using bundle identifier: $EXPO_PUBLIC_BUNDLE_IDENTIFIER" && \
echo "EXPO_PUBLIC_ENV=$EXPO_PUBLIC_ENV" >> .env && \
echo "EXPO_PUBLIC_RELEASE_VERSION=$EXPO_PUBLIC_RELEASE_VERSION" >> .env && \
echo "EXPO_PUBLIC_BUNDLE_IDENTIFIER=$EXPO_PUBLIC_BUNDLE_IDENTIFIER" >> .env && \
echo "EXPO_PUBLIC_BUNDLE_DATE=$(date -u +"%y%m%d%H")" >> .env && \
echo "EXPO_PUBLIC_SENTRY_DSN=$EXPO_PUBLIC_SENTRY_DSN" >> .env && \
npm install --global yarn && \
yarn && \
yarn intl:build 2>&1 | tee i18n.log && \
if grep -q "invalid syntax" "i18n.log"; then echo "\n\nFound compilation errors!\n\n" && exit 1; else echo "\n\nNo compile errors!\n\n"; fi && \
EXPO_PUBLIC_BUNDLE_IDENTIFIER=$EXPO_PUBLIC_BUNDLE_IDENTIFIER EXPO_PUBLIC_BUNDLE_DATE=$() SENTRY_AUTH_TOKEN=$SENTRY_AUTH_TOKEN SENTRY_RELEASE=$SENTRY_RELEASE SENTRY_DIST=$SENTRY_DIST SENTRY_DSN=$SENTRY_DSN yarn build-web
SENTRY_AUTH_TOKEN=$SENTRY_AUTH_TOKEN SENTRY_RELEASE=$EXPO_PUBLIC_RELEASE_VERSION SENTRY_DIST=$EXPO_PUBLIC_BUNDLE_IDENTIFIER yarn build-web
# DEBUG
RUN find ./bskyweb/static && find ./web-build/static
+2 -2
View File
@@ -89,9 +89,9 @@ If you change `SENTRY_AUTH_TOKEN`, you need to do `yarn prebuild` before running
### Adding bitdrift
Adding bitdirft is NOT required. You can keep `BITDRIFT_API_KEY=` in `.env` which will avoid initializing bitdrift during startup.
Adding bitdrift is NOT required. You can keep `EXPO_PUBLIC_BITDRIFT_API_KEY=` in `.env` which will avoid initializing bitdrift during startup.
However, if you're a part of the Bluesky team and want to enable bitdrift, fill in `BITDRIFT_API_KEY` in your `.env` to enable bitdrift.
However, if you're a part of the Bluesky team and want to enable bitdrift, fill in `EXPO_PUBLIC_BITDRIFT_API_KEY` in your `.env` to enable bitdrift.
### Adding and Updating Locales
@@ -2,13 +2,13 @@ import {Pressable} from 'react-native'
import * as Clipboard from 'expo-clipboard'
import {t} from '@lingui/macro'
import {IS_INTERNAL} from '#/lib/app-info'
import {DISCOVER_DEBUG_DIDS} from '#/lib/constants'
import {useGate} from '#/lib/statsig/statsig'
import {useSession} from '#/state/session'
import * as Toast from '#/view/com/util/Toast'
import {atoms as a, useBreakpoints, useTheme} from '#/alf'
import {Text} from '#/components/Typography'
import {IS_INTERNAL} from '#/env'
export function DiscoverDebug({
feedContext,
@@ -17,7 +17,6 @@ import {msg} from '@lingui/macro'
import {useLingui} from '@lingui/react'
import {useNavigation} from '@react-navigation/native'
import {IS_INTERNAL} from '#/lib/app-info'
import {DISCOVER_DEBUG_DIDS} from '#/lib/constants'
import {useOpenLink} from '#/lib/hooks/useOpenLink'
import {getCurrentRoute} from '#/lib/routes/helpers'
@@ -83,6 +82,7 @@ import {
useReportDialogControl,
} from '#/components/moderation/ReportDialog'
import * as Prompt from '#/components/Prompt'
import {IS_INTERNAL} from '#/env'
import * as bsky from '#/types/bsky'
let PostMenuItems = ({
-6
View File
@@ -1,6 +0,0 @@
export const LOG_DEBUG = process.env.EXPO_PUBLIC_LOG_DEBUG || ''
export const LOG_LEVEL = (process.env.EXPO_PUBLIC_LOG_LEVEL || 'info') as
| 'debug'
| 'info'
| 'warn'
| 'error'
+79
View File
@@ -0,0 +1,79 @@
import {type Did} from '@atproto/api'
import packageJson from '#/../package.json'
/**
* The semver version of the app, as defined in `package.json.`
*
* N.B. The fallback is needed for Render.com deployments
*/
export const RELEASE_VERSION: string =
process.env.EXPO_PUBLIC_RELEASE_VERSION || packageJson.version
/**
* The env the app is running in e.g. development, testflight, production
*/
export const ENV: string = process.env.EXPO_PUBLIC_ENV
/**
* Indicates whether the app is running in TestFlight
*/
export const IS_TESTFLIGHT = ENV === 'testflight'
/**
* Indicates whether the app is __DEV__
*/
export const IS_DEV = __DEV__
/**
* Indicates whether the app is __DEV__ or TestFlight
*/
export const IS_INTERNAL = IS_DEV || IS_TESTFLIGHT
/**
* The commit hash that the current bundle was made from. The user can
* see the commit hash in the app's settings along with the other version info.
* Useful for debugging/reporting.
*/
export const BUNDLE_IDENTIFIER: string =
process.env.EXPO_PUBLIC_BUNDLE_IDENTIFIER || 'dev'
/**
* This will always be in the format of YYMMDDHH, so that it always increases
* for each build. This should only be used for StatSig reporting and shouldn't
* be used to identify a specific bundle.
*/
export const BUNDLE_DATE: number = !process.env.EXPO_PUBLIC_BUNDLE_DATE
? 0
: Number(process.env.EXPO_PUBLIC_BUNDLE_DATE)
/**
* The log level for the app.
*/
export const LOG_LEVEL = (process.env.EXPO_PUBLIC_LOG_LEVEL || 'info') as
| 'debug'
| 'info'
| 'warn'
| 'error'
/**
* Enable debug logs for specific logger instances
*/
export const LOG_DEBUG: string = process.env.EXPO_PUBLIC_LOG_DEBUG || ''
/**
* The DID of the chat service to proxy to
*/
export const CHAT_PROXY_DID: Did =
process.env.EXPO_PUBLIC_CHAT_PROXY_DID || 'did:web:api.bsky.chat'
/**
* Sentry DSN for telemetry
*/
export const SENTRY_DSN: string | undefined = process.env.EXPO_PUBLIC_SENTRY_DSN
/**
* Bitdrift API key. If undefined, Bitdrift should be disabled.
*/
export const BITDRIFT_API_KEY: string | undefined =
process.env.EXPO_PUBLIC_BITDRIFT_API_KEY
+19
View File
@@ -0,0 +1,19 @@
import {nativeBuildVersion} from 'expo-application'
import {BUNDLE_IDENTIFIER, IS_TESTFLIGHT, RELEASE_VERSION} from '#/env/common'
export * from '#/env/common'
/**
* The semver version of the app, specified in our `package.json`.file. On
* iOs/Android, the native build version is appended to the semver version, so
* that it can be used to identify a specific build.
*/
export const APP_VERSION = `${RELEASE_VERSION}.${nativeBuildVersion}`
/**
* The short commit hash and environment of the current bundle.
*/
export const APP_METADATA = `${BUNDLE_IDENTIFIER.slice(0, 7)} (${
__DEV__ ? 'dev' : IS_TESTFLIGHT ? 'tf' : 'prod'
})`
+15
View File
@@ -0,0 +1,15 @@
import {BUNDLE_IDENTIFIER, RELEASE_VERSION} from '#/env/common'
export * from '#/env/common'
/**
* The semver version of the app, specified in our `package.json`.file. On
* iOs/Android, the native build version is appended to the semver version, so
* that it can be used to identify a specific build.
*/
export const APP_VERSION = RELEASE_VERSION
/**
* The short commit hash and environment of the current bundle.
*/
export const APP_METADATA = `${BUNDLE_IDENTIFIER.slice(0, 7)} (${__DEV__ ? 'dev' : 'prod'})`
-18
View File
@@ -1,18 +0,0 @@
import {nativeApplicationVersion, nativeBuildVersion} from 'expo-application'
export const IS_TESTFLIGHT = process.env.EXPO_PUBLIC_ENV === 'testflight'
export const IS_INTERNAL = __DEV__ || IS_TESTFLIGHT
// This is the commit hash that the current bundle was made from. The user can see the commit hash in the app's settings
// along with the other version info. Useful for debugging/reporting.
export const BUNDLE_IDENTIFIER = process.env.EXPO_PUBLIC_BUNDLE_IDENTIFIER ?? ''
// This will always be in the format of YYMMDD, so that it always increases for each build. This should only be used
// for Statsig reporting and shouldn't be used to identify a specific bundle.
export const BUNDLE_DATE =
IS_TESTFLIGHT || __DEV__ ? 0 : Number(process.env.EXPO_PUBLIC_BUNDLE_DATE)
export const appVersion = `${nativeApplicationVersion}.${nativeBuildVersion}`
export const bundleInfo = `${BUNDLE_IDENTIFIER} (${
__DEV__ ? 'dev' : IS_TESTFLIGHT ? 'tf' : 'prod'
})`
-18
View File
@@ -1,18 +0,0 @@
import packageDotJson from '../../package.json'
export const IS_TESTFLIGHT = false
export const IS_INTERNAL = __DEV__
// This is the commit hash that the current bundle was made from. The user can see the commit hash in the app's settings
// along with the other version info. Useful for debugging/reporting.
export const BUNDLE_IDENTIFIER =
process.env.EXPO_PUBLIC_BUNDLE_IDENTIFIER ?? 'dev'
// This will always be in the format of YYMMDD, so that it always increases for each build. This should only be used
// for Statsig reporting and shouldn't be used to identify a specific bundle.
export const BUNDLE_DATE = __DEV__
? 0
: Number(process.env.EXPO_PUBLIC_BUNDLE_DATE)
export const appVersion = packageDotJson.version
export const bundleInfo = `${BUNDLE_IDENTIFIER} (${__DEV__ ? 'dev' : 'prod'})`
+1 -1
View File
@@ -10,9 +10,9 @@ import {
useUpdates,
} from 'expo-updates'
import {IS_TESTFLIGHT} from '#/lib/app-info'
import {logger} from '#/logger'
import {isIOS} from '#/platform/detection'
import {IS_TESTFLIGHT} from '#/env'
const MINIMUM_MINIMIZE_TIME = 15 * 60e3
+9 -11
View File
@@ -3,12 +3,11 @@ import {Platform} from 'react-native'
import {AppState, type AppStateStatus} from 'react-native'
import {Statsig, StatsigProvider} from 'statsig-react-native-expo'
import {BUNDLE_DATE, BUNDLE_IDENTIFIER, IS_TESTFLIGHT} from '#/lib/app-info'
import {logger} from '#/logger'
import {type MetricEvents} from '#/logger/metrics'
import {isWeb} from '#/platform/detection'
import * as persisted from '#/state/persisted'
import packageDotJson from '../../../package.json'
import * as env from '#/env'
import {useSession} from '../../state/session'
import {timeout} from '../async/timeout'
import {useNonReactiveCallback} from '../hooks/useNonReactiveCallback'
@@ -49,12 +48,11 @@ export type {MetricEvents as LogEvents}
function createStatsigOptions(prefetchUsers: StatsigUser[]) {
return {
environment: {
tier:
process.env.NODE_ENV === 'development'
? 'development'
: IS_TESTFLIGHT
? 'staging'
: 'production',
tier: env.IS_DEV
? 'development'
: env.IS_TESTFLIGHT
? 'staging'
: 'production',
},
// Don't block on waiting for network. The fetched config will kick in on next load.
// This ensures the UI is always consistent and doesn't update mid-session.
@@ -212,9 +210,9 @@ function toStatsigUser(did: string | undefined): StatsigUser {
refSrc,
refUrl,
platform: Platform.OS as 'ios' | 'android' | 'web',
appVersion: packageDotJson.version,
bundleIdentifier: BUNDLE_IDENTIFIER,
bundleDate: BUNDLE_DATE,
appVersion: env.RELEASE_VERSION,
bundleIdentifier: env.BUNDLE_IDENTIFIER,
bundleDate: env.BUNDLE_DATE,
appLanguage: languagePrefs.appLanguage,
contentLanguages: languagePrefs.contentLanguages,
},
+1 -2
View File
@@ -2,8 +2,7 @@ import {init, SessionStrategy} from '@bitdrift/react-native'
import {Statsig} from 'statsig-react-native-expo'
import {initPromise} from '#/lib/statsig/statsig'
const BITDRIFT_API_KEY = process.env.BITDRIFT_API_KEY
import {BITDRIFT_API_KEY} from '#/env'
initPromise.then(() => {
let isEnabled = false
+2 -1
View File
@@ -14,9 +14,10 @@ import {
} from '#/logger/types'
import {enabledLogLevels} from '#/logger/util'
import {isNative} from '#/platform/detection'
import {ENV} from '#/env'
const TRANSPORTS: Transport[] = (function configureTransports() {
switch (process.env.NODE_ENV) {
switch (ENV) {
case 'production': {
return [sentryTransport, isNative && bitdriftTransport].filter(
Boolean,
+6 -22
View File
@@ -1,32 +1,16 @@
/**
* Importing these separately from `platform/detection` and `lib/app-info` to
* avoid future conflicts and/or circular deps
*/
import {init} from '@sentry/react-native'
import pkgJson from '#/../package.json'
/**
* Examples:
* - `dev`
* - `1.99.0`
*/
const release = process.env.SENTRY_RELEASE || pkgJson.version
/**
* The latest deployed commit hash
*/
const dist = process.env.SENTRY_DIST || 'dev'
import * as env from '#/env'
init({
enabled: !__DEV__ && !!process.env.SENTRY_DSN,
enabled: !env.IS_DEV && !!env.SENTRY_DSN,
autoSessionTracking: false,
dsn: process.env.SENTRY_DSN,
dsn: env.SENTRY_DSN,
debug: false, // If `true`, Sentry will try to print out useful debugging information if something goes wrong with sending the event. Set it to `false` in production
environment: process.env.NODE_ENV,
dist,
release,
environment: env.ENV,
dist: env.BUNDLE_IDENTIFIER,
release: pkgJson.version,
ignoreErrors: [
/*
* Unknown internals errors
+22 -6
View File
@@ -1,5 +1,5 @@
import {useMemo} from 'react'
import {Platform} from 'react-native'
import {Platform, View} from 'react-native'
import {setStringAsync} from 'expo-clipboard'
import * as FileSystem from 'expo-file-system'
import {Image} from 'expo-image'
@@ -9,12 +9,12 @@ import {type NativeStackScreenProps} from '@react-navigation/native-stack'
import {useMutation} from '@tanstack/react-query'
import {Statsig} from 'statsig-react-native-expo'
import {appVersion, BUNDLE_DATE, bundleInfo} from '#/lib/app-info'
import {STATUS_PAGE_URL} from '#/lib/constants'
import {type CommonNavigatorParams} from '#/lib/routes/types'
import {isAndroid, isIOS, isNative} from '#/platform/detection'
import * as Toast from '#/view/com/util/Toast'
import * as SettingsList from '#/screens/Settings/components/SettingsList'
import {atoms as a} from '#/alf'
import {Atom_Stroke2_Corner0_Rounded as AtomIcon} from '#/components/icons/Atom'
import {BroomSparkle_Stroke2_Corner2_Rounded as BroomSparkleIcon} from '#/components/icons/BroomSparkle'
import {CodeLines_Stroke2_Corner2_Rounded as CodeLinesIcon} from '#/components/icons/CodeLines'
@@ -23,6 +23,8 @@ import {Newspaper_Stroke2_Corner2_Rounded as NewspaperIcon} from '#/components/i
import {Wrench_Stroke2_Corner2_Rounded as WrenchIcon} from '#/components/icons/Wrench'
import * as Layout from '#/components/Layout'
import {Loader} from '#/components/Loader'
import {Text} from '#/components/Typography'
import * as env from '#/env'
import {useDemoMode} from '#/storage/hooks/demo-mode'
import {useDevMode} from '#/storage/hooks/dev-mode'
import {OTAInfo} from './components/OTAInfo'
@@ -123,7 +125,7 @@ export function AboutSettingsScreen({}: Props) {
</SettingsList.PressableItem>
)}
<SettingsList.PressableItem
label={_(msg`Version ${appVersion}`)}
label={_(msg`Version ${env.APP_VERSION}`)}
accessibilityHint={_(msg`Copies build version to clipboard`)}
onLongPress={() => {
const newDevModeEnabled = !devModeEnabled
@@ -146,15 +148,15 @@ export function AboutSettingsScreen({}: Props) {
}}
onPress={() => {
setStringAsync(
`Build version: ${appVersion}; Bundle info: ${bundleInfo}; Bundle date: ${BUNDLE_DATE}; Platform: ${Platform.OS}; Platform version: ${Platform.Version}; Anonymous ID: ${stableID}`,
`Build version: ${env.APP_VERSION}; Bundle info: ${env.APP_METADATA}; Bundle date: ${env.BUNDLE_DATE}; Platform: ${Platform.OS}; Platform version: ${Platform.Version}; Anonymous ID: ${stableID}`,
)
Toast.show(_(msg`Copied build version to clipboard`))
}}>
<SettingsList.ItemIcon icon={WrenchIcon} />
<SettingsList.ItemText>
<Trans>Version {appVersion}</Trans>
<Trans>Version {env.APP_VERSION}</Trans>
</SettingsList.ItemText>
<SettingsList.BadgeText>{bundleInfo}</SettingsList.BadgeText>
<SettingsList.BadgeText>{env.APP_METADATA}</SettingsList.BadgeText>
</SettingsList.PressableItem>
{devModeEnabled && (
<>
@@ -179,6 +181,20 @@ export function AboutSettingsScreen({}: Props) {
</SettingsList.ItemText>
</SettingsList.PressableItem>
)}
<View style={[a.gap_sm]}>
<Text>ENV: {env.ENV}</Text>
<Text>IS_TESTFLIGHT: {String(env.IS_TESTFLIGHT)}</Text>
<Text>IS_DEV: {String(env.IS_DEV)}</Text>
<Text>IS_INTERNAL: {String(env.IS_INTERNAL)}</Text>
<Text>BUNDLE_IDENTIFIER: {env.BUNDLE_IDENTIFIER}</Text>
<Text>BUNDLE_DATE: {env.BUNDLE_DATE}</Text>
<Text>LOG_LEVEL: {env.LOG_LEVEL}</Text>
<Text>CHAT_PROXY_DID: {env.CHAT_PROXY_DID}</Text>
<Text>SENTRY_DSN: {env.SENTRY_DSN}</Text>
<Text>APP_VERSION: {env.APP_VERSION}</Text>
<Text>APP_METADATA: {env.APP_METADATA}</Text>
</View>
</>
)}
</SettingsList.Container>
@@ -3,20 +3,20 @@ import {Alert, View} from 'react-native'
import {msg, Trans} from '@lingui/macro'
import {useLingui} from '@lingui/react'
import * as DynamicAppIcon from '@mozzius/expo-dynamic-app-icon'
import {NativeStackScreenProps} from '@react-navigation/native-stack'
import {type NativeStackScreenProps} from '@react-navigation/native-stack'
import {IS_INTERNAL} from '#/lib/app-info'
import {PressableScale} from '#/lib/custom-animations/PressableScale'
import {CommonNavigatorParams} from '#/lib/routes/types'
import {type CommonNavigatorParams} from '#/lib/routes/types'
import {useGate} from '#/lib/statsig/statsig'
import {isAndroid} from '#/platform/detection'
import {AppIconImage} from '#/screens/Settings/AppIconSettings/AppIconImage'
import {AppIconSet} from '#/screens/Settings/AppIconSettings/types'
import {type AppIconSet} from '#/screens/Settings/AppIconSettings/types'
import {useAppIconSets} from '#/screens/Settings/AppIconSettings/useAppIconSets'
import {atoms as a, useTheme} from '#/alf'
import * as Toggle from '#/components/forms/Toggle'
import * as Layout from '#/components/Layout'
import {Text} from '#/components/Typography'
import {IS_INTERNAL} from '#/env'
type Props = NativeStackScreenProps<CommonNavigatorParams, 'AppIconSettings'>
export function AppIconSettingsScreen({}: Props) {
+1 -1
View File
@@ -8,7 +8,6 @@ import Animated, {
import {msg, Trans} from '@lingui/macro'
import {useLingui} from '@lingui/react'
import {IS_INTERNAL} from '#/lib/app-info'
import {
type CommonNavigatorParams,
type NativeStackScreenProps,
@@ -26,6 +25,7 @@ import {TextSize_Stroke2_Corner0_Rounded as TextSize} from '#/components/icons/T
import {TitleCase_Stroke2_Corner0_Rounded as Aa} from '#/components/icons/TitleCase'
import * as Layout from '#/components/Layout'
import {Text} from '#/components/Typography'
import {IS_INTERNAL} from '#/env'
import * as SettingsList from './components/SettingsList'
type Props = NativeStackScreenProps<CommonNavigatorParams, 'AppearanceSettings'>
+1 -1
View File
@@ -9,7 +9,6 @@ import {useNavigation} from '@react-navigation/native'
import {type NativeStackScreenProps} from '@react-navigation/native-stack'
import {useActorStatus} from '#/lib/actor-status'
import {IS_INTERNAL} from '#/lib/app-info'
import {HELP_DESK_URL} from '#/lib/constants'
import {useAccountSwitcher} from '#/lib/hooks/useAccountSwitcher'
import {useApplyPullRequestOTAUpdate} from '#/lib/hooks/useOTAUpdates'
@@ -66,6 +65,7 @@ import {
shouldShowVerificationCheckButton,
VerificationCheckButton,
} from '#/components/verification/VerificationCheckButton'
import {IS_INTERNAL} from '#/env'
import {useActivitySubscriptionsNudged} from '#/storage/hooks/activity-subscriptions-nudged'
type Props = NativeStackScreenProps<CommonNavigatorParams, 'Settings'>
+3 -1
View File
@@ -1,3 +1,5 @@
import {CHAT_PROXY_DID} from '#/env'
export const DM_SERVICE_HEADERS = {
'atproto-proxy': 'did:web:api.bsky.chat#bsky_chat',
'atproto-proxy': `${CHAT_PROXY_DID}#bsky_chat`,
}
+5 -5
View File
@@ -1,11 +1,11 @@
import {AtpSessionData, AtpSessionEvent} from '@atproto/api'
import {type AtpSessionData, type AtpSessionEvent} from '@atproto/api'
import {sha256} from 'js-sha256'
import {Statsig} from 'statsig-react-native-expo'
import {IS_INTERNAL} from '#/lib/app-info'
import {Schema} from '../persisted'
import {Action, State} from './reducer'
import {SessionAccount} from './types'
import {IS_INTERNAL} from '#/env'
import {type Schema} from '../persisted'
import {type Action, type State} from './reducer'
import {type SessionAccount} from './types'
type Reducer = (state: State, action: Action) => State
+1 -1
View File
@@ -53,7 +53,7 @@ module.exports = async function (env, argv) {
project: 'app',
authToken: process.env.SENTRY_AUTH_TOKEN,
release: {
// env is undefined for Render.com builds, fall back
// fallback needed for Render.com deployments
name: process.env.SENTRY_RELEASE || version,
dist: process.env.SENTRY_DIST,
},