Open andrejpavlovic opened 8 months ago
I just encountered the same issue. Thanks for the workaround for now!
did you create the prebuild? i encoutered same issue, i solved by prebuild creation instead of set NODE_ENV.
did you create the prebuild? i encoutered same issue, i solved by prebuild creation instead of set NODE_ENV.
I don't think prebuild is relevant here, since prebuild is an expo
command, and the question is really about how to access environment variables when using eas update
I was facing a similar issue, so hope I can share some insights.
I am using an expo app with different app variants [staging, production].
This is my eas config****
"staging": {
"distribution": "store",
"env": {
"APP_VARIANT": "staging"
},
"channel": "staging",
"autoIncrement": true
},
"production": {
"channel": "production",
"autoIncrement": true
}
And my app.config.ts is something like this
export default ({ config }: ConfigContext): ExpoConfig => {
const isStaging = process.env.APP_VARIANT === 'staging';
const productionConfig: ExpoConfig = {
...config,
name: 'App',
ios: {
bundleIdentifier: 'com.xxxx.influencer',
},
android: {
package: 'com.xxxx.influencer',
},
extra: {
eas: {
projectId: '8c24d46b-xxxx-45f1-xxxx-xxx571c7xxxx',
},
GQL_URL: 'https://gql.xxxx.com/graphql/',
},
updates: {
url: 'https://u.expo.dev/xxx-xxxx-45f1-9379-dce571cxxx',
},
runtimeVersion: {
policy: 'appVersion',
},
};
if (isStaging) {
return {
...productionConfig,
name: '(Stg)App',
ios: {
...productionConfig.ios,
bundleIdentifier: 'com.xxxx.influencer.staging',
},
android: {
...productionConfig.android,
package: 'com.xxxx.influencer.staging',
},
extra: {
...productionConfig.extra,
GQL_URL: 'https://stg-gql.xxxx.com/graphql/',
},
};
}
return productionConfig;
};
For building the app (for staging) I use these commands
eas build --profile staging --platform android
eas build --profile staging --platform ios
Till this point, everything works fine. The build can properly set all environment variables, as I have specified the profile with env
on my eas.json.
Also, on the app.config.ts, it can pick up the correct env[staging].
I was trying to push an update on my staging variant with the following command
eas update --branch staging --message "Message..."
Although I was sending the update to the staging branch, the new update wasn't able to pick the APP_VARIANT
correctly.
Probably, it was undefined on app.config.ts
, and my staging app was behaving like the production app by using my production GQL_URL: 'https://gql.xxxx.com/graphql/',
endpoint.
Finally, I was able to fix that by setting the APP_VARIANT
with the eas update command like this
APP_VARIANT=staging eas update --branch staging --message "Message..."
On the CI, it will be something like this
APP_VARIANT=staging npx eas-cli update --branch staging --message="`git log -1 --pretty=%B`" --non-interactive
I was facing a similar issue, so hope I can share some insights.
I am using an expo app with different app variants [staging, production].
This is my eas config
"staging": { "distribution": "store", "env": { "APP_VARIANT": "staging" }, "channel": "staging", "autoIncrement": true }, "production": { "channel": "production", "autoIncrement": true }
And my app.config.ts is something like this
export default ({ config }: ConfigContext): ExpoConfig => { const isStaging = process.env.APP_VARIANT === 'staging'; const productionConfig: ExpoConfig = { ...config, name: 'App', ios: { bundleIdentifier: 'com.xxxx.influencer', }, android: { package: 'com.xxxx.influencer', }, extra: { eas: { projectId: '8c24d46b-xxxx-45f1-xxxx-xxx571c7xxxx', }, GQL_URL: 'https://gql.xxxx.com/graphql/', }, updates: { url: 'https://u.expo.dev/xxx-xxxx-45f1-9379-dce571cxxx', }, runtimeVersion: { policy: 'appVersion', }, }; if (isStaging) { return { ...productionConfig, name: '(Stg)App', ios: { ...productionConfig.ios, bundleIdentifier: 'com.xxxx.influencer.staging', }, android: { ...productionConfig.android, package: 'com.xxxx.influencer.staging', }, extra: { ...productionConfig.extra, GQL_URL: 'https://stg-gql.xxxx.com/graphql/', }, }; } return productionConfig; };
For building the app (for staging) I use these commands
eas build --profile staging --platform android eas build --profile staging --platform ios
Till this point, everything works fine. The build can properly set all environment variables, as I have specified the profile with
env
on my eas.json.Also, on the app.config.ts, it can pick up the correct env[staging].
The problem happens with the eas update!
I was trying to push an update on my staging variant with the following command
eas update --branch staging --message "Message..."
Although I was sending the update to the staging branch, the new update wasn't able to pick the
APP_VARIANT
correctly.Probably, it was undefined on
app.config.ts
, and my staging app was behaving like the production app by using my productionGQL_URL: 'https://gql.xxxx.com/graphql/',
endpoint.Finally, I was able to fix that by setting the
APP_VARIANT
with the eas update command like thisAPP_VARIANT=staging eas update --branch staging --message "Message..."
On the CI, it will be something like this
APP_VARIANT=staging npx eas-cli update --branch staging --message="`git log -1 --pretty=%B`" --non-interactive
I am having an issue with the build not the eas update, I am trying to set a new projectId based on configurations but it keeps failing when running the eas build worker, i thought you might have an input here
Thanks for your workaround @andrejpavlovic - however I found an issue which is preventing me from continuing, I load the dotenv config using the ES6 method: import 'dotenv/config';
as described here: https://github.com/motdotla/dotenv?tab=readme-ov-file#how-do-i-use-dotenv-with-import (I'm using dotenv-vault but not sure that is relevant as I can see the vars being loaded in logs)
And for some reason the config is being called 3 times, once with the correct process.env var set and twice more with it undefined:
// app.config.ts
export default ({ config }: ConfigContext): ExpoConfig => {
const url = `https://u.expo.dev/${process.env.EXPO_PROJECT_ID}`;
console.log('URL', url);
...
};
// output
[dotenv@16.4.5][INFO] Loading env from encrypted .env.vault
URL https://u.expo.dev/022xxxxx-eb2e-xxx-b078-24xxxxxfb2d
URL https://u.expo.dev/undefined
URL https://u.expo.dev/undefined
It looks like you are using a dynamic configuration! Learn more: https://docs.expo.dev/workflow/configuration/#dynamic-configuration-with-appconfigjs)
Add the following EAS Update key-values to the project app.config.js:
Learn more: https://expo.fyi/eas-update-config
EAS is only being called once with this command: npx eas-cli@latest update --auto --non-interactive
Interestingly, when using your method of import * as dotenv from 'dotenv';
and calling dotenv.config()
outside the scope of the config function (I don't require the config options with my dotenv-vault) then it seems to call it many more times but it does actually set the env var correctly every time:
// output
[dotenv@16.4.5][INFO] Loading env from encrypted .env.vault
URL https://u.expo.dev/022xxxxx-eb2e-xxx-b078-24xxxxxfb2d
[dotenv@16.4.5][INFO] Loading env from encrypted .env.vault
URL https://u.expo.dev/022xxxxx-eb2e-xxx-b078-24xxxxxfb2d
[dotenv@16.4.5][INFO] Loading env from encrypted .env.vault
URL https://u.expo.dev/022xxxxx-eb2e-xxx-b078-24xxxxxfb2d
[dotenv@16.4.5][INFO] Loading env from encrypted .env.vault
URL https://u.expo.dev/022xxxxx-eb2e-xxx-b078-24xxxxxfb2d
[dotenv@16.4.5][INFO] Loading env from encrypted .env.vault
URL https://u.expo.dev/022xxxxx-eb2e-xxx-b078-24xxxxxfb2d
[dotenv@16.4.5][INFO] Loading env from encrypted .env.vault
URL https://u.expo.dev/022xxxxx-eb2e-xxx-b078-24xxxxxfb2d
- Exporting...
[expo-cli] [dotenv@16.4.5][INFO] Loading env from encrypted .env.vault
- Exporting...
[expo-cli] URL https://u.expo.dev/022xxxxx-eb2e-xxx-b078-24xxxxxfb2d
- Exporting...
[expo-cli] [dotenv@16.4.5][INFO] Loading env from encrypted .env.vault
- Exporting...
[expo-cli] URL https://u.expo.dev/022xxxxx-eb2e-xxx-b078-24xxxxxfb2d
- Exporting...
[expo-cli] [dotenv@16.4.5][INFO] Loading env from encrypted .env.vault
- Exporting...
[expo-cli] URL https://u.expo.dev/022xxxxx-eb2e-xxx-b078-24xxxxxfb2d
[expo-cli] Starting Metro Bundler
It would be nice for this to work as expected by EAS.
I have solved this issue for me anyway by utilising dotenvx
which only injects the variables once and they persist no matter how many times eas
calls the config function - and it keeps the config file cleaner.
This was discovered as dotenv-vault
didn't play nicely with my .env.local
file on development.
Summary:
Don't change your app.config.js/ts
- don't import dotenv
Install dotenvx
(and maybe remove dotenv
) and use it to run eas
:
npx dotenvx run -- npx eas-cli@latest update --auto --non-interactive
// Or simpler when using the (expo-gitub-action)[https://github.com/expo/expo-github-action/tree/v8/]
npx dotenvx run -- eas update --auto --non-interactive
If you need additional env vars passed in then set them before dotenvx:
APP_PROFILE=preview npx dotenvx run -- eas update --auto --non-interactive
// Not like this
npx dotenvx run -- APP_PROFILE=preview eas update --auto --non-interactive
Hope this helps someone until Expo/EAS fix this as it is a bit annoying and 🤯
Using dotenv cli to load the env variables is the only viable solution to this problem. The documentation is really confusing on this topic, especially since "update" is an EAS command, you'd expect it to use variables from eas.json at least, but no - it doesn't load variables from neither eas.json nor env files.
See https://github.com/expo/eas-cli/issues/1265#issuecomment-1499968948
Here's how I've done it (with dotenv-cli as a project dependency):
yarn dotenv -e .env -e .env.<environment> -- npx eas-cli@latest update --channel <channel>
@AdamGerthel if you use npx then you don't need to install it as a project dependency, it will download it and use it on demand. eas.json is not very useful in my opinion as there are no dynamic values in json
Thanks for your workaround @andrejpavlovic - however I found an issue which is preventing me from continuing, I load the dotenv config using the ES6 method:
import 'dotenv/config';
as described here: https://github.com/motdotla/dotenv?tab=readme-ov-file#how-do-i-use-dotenv-with-import (I'm using dotenv-vault but not sure that is relevant as I can see the vars being loaded in logs)And for some reason the config is being called 3 times, once with the correct process.env var set and twice more with it undefined:
// app.config.ts export default ({ config }: ConfigContext): ExpoConfig => { const url = `https://u.expo.dev/${process.env.EXPO_PROJECT_ID}`; console.log('URL', url); ... };
// output [dotenv@16.4.5][INFO] Loading env from encrypted .env.vault URL https://u.expo.dev/022xxxxx-eb2e-xxx-b078-24xxxxxfb2d URL https://u.expo.dev/undefined URL https://u.expo.dev/undefined It looks like you are using a dynamic configuration! Learn more: https://docs.expo.dev/workflow/configuration/#dynamic-configuration-with-appconfigjs) Add the following EAS Update key-values to the project app.config.js: Learn more: https://expo.fyi/eas-update-config
EAS is only being called once with this command:
npx eas-cli@latest update --auto --non-interactive
Interestingly, when using your method of
import * as dotenv from 'dotenv';
and callingdotenv.config()
outside the scope of the config function (I don't require the config options with my dotenv-vault) then it seems to call it many more times but it does actually set the env var correctly every time:// output [dotenv@16.4.5][INFO] Loading env from encrypted .env.vault URL https://u.expo.dev/022xxxxx-eb2e-xxx-b078-24xxxxxfb2d [dotenv@16.4.5][INFO] Loading env from encrypted .env.vault URL https://u.expo.dev/022xxxxx-eb2e-xxx-b078-24xxxxxfb2d [dotenv@16.4.5][INFO] Loading env from encrypted .env.vault URL https://u.expo.dev/022xxxxx-eb2e-xxx-b078-24xxxxxfb2d [dotenv@16.4.5][INFO] Loading env from encrypted .env.vault URL https://u.expo.dev/022xxxxx-eb2e-xxx-b078-24xxxxxfb2d [dotenv@16.4.5][INFO] Loading env from encrypted .env.vault URL https://u.expo.dev/022xxxxx-eb2e-xxx-b078-24xxxxxfb2d [dotenv@16.4.5][INFO] Loading env from encrypted .env.vault URL https://u.expo.dev/022xxxxx-eb2e-xxx-b078-24xxxxxfb2d - Exporting... [expo-cli] [dotenv@16.4.5][INFO] Loading env from encrypted .env.vault - Exporting... [expo-cli] URL https://u.expo.dev/022xxxxx-eb2e-xxx-b078-24xxxxxfb2d - Exporting... [expo-cli] [dotenv@16.4.5][INFO] Loading env from encrypted .env.vault - Exporting... [expo-cli] URL https://u.expo.dev/022xxxxx-eb2e-xxx-b078-24xxxxxfb2d - Exporting... [expo-cli] [dotenv@16.4.5][INFO] Loading env from encrypted .env.vault - Exporting... [expo-cli] URL https://u.expo.dev/022xxxxx-eb2e-xxx-b078-24xxxxxfb2d [expo-cli] Starting Metro Bundler
It would be nice for this to work as expected by EAS.
import * as dotenv from 'dotenv'; dotenv.config();
The above approach solved my issue. the last call was not persisting env variables.
Thank you so much for this workaround😊
@ChromeQ Thanks!!!! That helped me after a lot of frustration!
npx dotenvx run -- eas update --auto --non-interactive
This is the easiest and cleanest solution for me. Thank you so much!
I encountered the same issue. Using a TypeScript app.config file and an env file named .env.local
, I got errors when trying to build or run npx expo-doctor
, saying it couldn't find an env variable. The fix: add import * as dotenv from 'dotenv'; dotenv.config();
to the app.config.ts file. There's a catch though - either rename the file to just .env
, or specify the file path in the config function like this: dotenv.config({ path: '.env.local' });
.
Build/Submit details page URL
No response
Summary
How do I get
eas update
to properly loadapp.config.js
file that references environment variables, if those aren't available wheneas update
is executed?Let's say I have an
.env
file with this environment variable:I use this value in
app.config.js
for something and ensure it is not empty:✔️ Running expo command such as
yarn expo config
works fine, since the environment variable is automatically loaded from.env
file.❌ However when running
eas config
oreas update
, the error above is thrown becauseMY_VALUE
environment value is not available.Now, I understand that eas is not supposed to be reading
.env
values, but the issue here is that it's reading the expo config which uses environment variables.So I thought adding
MY_VALUE
toeas.json
asenv
value would fix the issue, but it only works foreas config
.eas update
doesn't read environment values even fromeas.json
.If
eas update
doesn't read environment values from.env
or fromeas.json
then why is it loadingapp.config.js
which more than likely relies on environment values in order to configure expo plugins, etc.?My workaround for now was to just load
.env
manually inapp.config.js
:Managed or bare?
managed
Environment
expo-env-info 1.2.0 environment info: System: OS: Windows 10 10.0.19045 Binaries: Node: 18.18.0 - C:\Program Files\nodejs\node.EXE Yarn: 1.22.19 - C:\Program Files (x86)\Yarn\bin\yarn.CMD npm: 10.2.5 - C:\Program Files\nodejs\npm.CMD Watchman: 20210110.135312.0 - C:\ProgramData\chocolatey\bin\watchman.EXE IDEs: Android Studio: AI-231.9392.1.2311.11330709 npmPackages: expo: ~50.0.6 => 50.0.6 react: 18.2.0 => 18.2.0 react-dom: ^18.2.0 => 18.2.0 react-native: 0.73.4 => 0.73.4 react-native-web: ~0.19.10 => 0.19.10 Expo Workflow: bare
✔ Check Expo config for common issues ✔ Check package.json for common issues ✔ Check dependencies for packages that should not be installed directly ✔ Check for common project setup issues ✔ Check npm/ yarn versions ✔ Check for issues with metro config ✔ Check Expo config (app.json/ app.config.js) schema ✔ Check that packages match versions required by installed Expo SDK ✔ Check that native modules do not use incompatible support packages ✔ Check for legacy global CLI installed locally ✔ Check that native modules use compatible support package versions for installed Expo SDK
Error output
No response
Reproducible demo or steps to reproduce from a blank project
Description posted above.