Recommended way for keeping configuration in sync when using EAS build and OTAs

Hello!

I’ve been working with EAS for the first time on my current project and am a little fuzzy on how best to use OTAs with EAS Build.

Relevant context on my project:

  • we have an app.config.js file that reads various values from process.env to populate manifest.extra. Locally, these values are populated from a .env file. In builds, we store values in our Expo account, as secrets.
  • we’ve been testing our work with an internal distribution profile

I may have misunderstood something, but from what I can tell.

  • on creating a build, e.g. running eas build, the app’s configuration comes from our secrets stored in our account
  • on publishing an OTA to our build’s release channel, the app’s configuration comes from whatever configuration is local to the machine on which the publish command was run e.g. whatever happens to be in my .env file at the time.
  • on installing this update, the build e.g. as running on my phone, loses any secrets received from EAS Build, instead using the config in the update from my machine

Assuming some / all of this is correct, I’m concerned about keeping app configuration in sync between EAS Build and OTAs. As in, when I publish to release channel A, I want the published update to be configured the same as if it were released via eas build. It seems really easy to accidentally misconfigure builds based on local configuration.

Do you have any recommendations / strategies for approaching this?

Thanks!

hi there!

secrets should only be used for values that are needed in the build but have nothing to do with your js bundle. for example, your sentry api key (if you use sentry for error tracking) is used at build time to upload your sourcemaps and create a new release on sentrys side, it is not needed for your js bundle. the advice that follows this applies only to environment variables used in your js application code.

i would recommend using a single environment variable to switch between configuration values. you can commit all of these values to source control in pure js files rather than a .env. for example, you could have development.staging.js, staging.config.js, and production.config.js which you commit to git and contain values like export const API_URL = 'https://myserver.com/api'. in your app.config.js, you can then just read a value like APP_ENV and include the necessary configuration. something like:

const APP_ENV = process.env.APP_ENV ?? 'development';
// note: you could alternatively use EAS_BUILD_PROFILE here if you like

const environmentConfig = require(`${APP_ENV}.config.js`);

module.exports = {
  extra: environmentConfig
};

now you only need to switch one environment variable depending on what environment you’re building or publishing to

1 Like

Hello! So sorry for my delayed response, been a busy stretch.

But thanks a ton for that info. I think I was overthinking things a bit. Most of the values I was storing as secrets weren’t actually secrets, so ended up storing them in our build profiles. I’m glad you used the sentry API key as an example, as we’re using Sentry, too. That helped clarify how think about secrets.

Your example clarified how to configure builds different on EAS, but still left me unclear on how to replicate secrets locally when publishing e.g. setting SENTRY_AUTH_TOKEN when running expo publish locally. I ended up replicating that secret in AWS’ Secrets Manager tool (we use AWS for all our infra anyway), then fetching it and storing it in the environment on publish. Seems to be working ok so far!