3

Today I tried to setup my EAS builds using multiple environments. When following these steps, the app config is not correctly setup due to undefined environment variables and I'm not sure what I'm doing wrong.

  • Workflow: managed
  • 'eas-cli' version: eas-cli/15.0.12 darwin-arm64 node-v22.13.0

Steps I did:

  • Created environment variables on Expo
  • For my local development I've pulled them using the eas env:pull command which created a .env.local with the correct values
  • In my app.config.ts I've made three different app variants based on the APP_VARIANT environment variable, looking like this:
import { ConfigContext, ExpoConfig } from 'expo/config'

const colorGray200 = '#ECEDEE'
const colorGreenDefault = '#003D4F'

type TEnvironment = 'development' | 'preview' | 'production'

interface TAdaptiveIcon {
    foregroundImage?: string
    monochromeImage?: string
    backgroundImage?: string
    backgroundColor?: string
}

interface TSplashScreenConfig {
    backgroundColor: string
    image: string
    dark?: {
        image: string
        backgroundColor: string
    }
}

interface AppEnvironmentConfig {
    name: string
    identifier: string
    icon: string
    adaptiveIcon: TAdaptiveIcon
    splash: TSplashScreenConfig
}

type AppConfig = Record<TEnvironment, AppEnvironmentConfig>

const appConfig: AppConfig = {
    development: {
        name: 'MyApp Dev',
        identifier: 'app.myapp.be.dev',
        icon: './assets/icon.png',
        adaptiveIcon: {
            foregroundImage: './assets/adaptive-icon.png',
            backgroundColor: '#ffffff',
        },
        splash: {
            backgroundColor: colorGray200,
            image: './assets/splash-icon.png',
            dark: {
                image: './assets/splash-icon-dark.png',
                backgroundColor: colorGreenDefault,
            },
        },
    },
    preview: {
        name: 'MyApp Preview',
        identifier: 'app.***.be.preview',
        icon: './assets/icon.png',
        adaptiveIcon: {
            foregroundImage: './assets/adaptive-icon.png',
            backgroundColor: '#ffffff',
        },
        splash: {
            backgroundColor: colorGray200,
            image: './assets/splash-icon.png',
            dark: {
                image: './assets/splash-icon-dark.png',
                backgroundColor: colorGreenDefault,
            },
        },
    },
    production: {
        name: 'MyApp',
        identifier: 'app.***.be',
        icon: './assets/icon.png',
        adaptiveIcon: {
            foregroundImage: './assets/adaptive-icon.png',
            backgroundColor: '#ffffff',
        },
        splash: {
            backgroundColor: colorGray200,
            image: './assets/splash-icon.png',
            dark: {
                image: './assets/splash-icon-dark.png',
                backgroundColor: colorGreenDefault,
            },
        },
    },
}

export default ({ config }: ConfigContext): ExpoConfig => {
    const appVariant: TEnvironment = process.env.APP_VARIANT
    if (!appVariant) {
        throw new Error(`APP_VARIANT environment variable not defined`)
    }
    const currentAppConfig = appConfig[appVariant]
    return {
        ...config,
        name: currentAppConfig.name,
        slug: '****',
        owner: '****',
        version: '1.0.0',
        scheme: currentAppConfig.identifier,
        orientation: 'portrait',
        icon: currentAppConfig.icon,
        userInterfaceStyle: 'light',
        newArchEnabled: true,
        ios: {
            icon: {
                dark: './assets/images/ios-dark.png',
                light: './assets/images/ios-light.png',
                tinted: './assets/images/ios-tinted.png',
            },
            bundleIdentifier: currentAppConfig.identifier,
            infoPlist: {
                ITSAppUsesNonExemptEncryption: false,
            },
        },
        android: {
            adaptiveIcon: currentAppConfig.adaptiveIcon,
        },
        web: {
            favicon: './assets/favicon.png',
        },
        plugins: [
            'expo-router',
            'expo-secure-store',
            [
                'expo-splash-screen',
                {
                    ...currentAppConfig.splash,
                    imageWidth: 200,
                },
            ],
        ],
        extra: {
            router: {
                origin: false,
            },
            eas: {
                projectId: '0ffea***-****-****-****-**********8d',
            },
        },
    }
}

  • My eas.json looks like this
{
    "build": {
        "development": {
            "env": {
                "APP_VARIANT": "development"
            },
            "environment": "development",
            "developmentClient": true,
            "distribution": "internal"
        },
        "preview": {
            "env": {
                "APP_VARIANT": "preview"
            },
            "distribution": "internal",
            "environment": "preview"
        },
        "production": {
            "env": {
                "APP_VARIANT": "production"
            },
            "environment": "production"
        }
    },
    "cli": {
        "appVersionSource": "remote"
    }
}
  • So now, every EAS command (build, env:pull, ..) I run, results into:
Failed to read the app config from the project using "npx expo config" command: npx expo config --json exited with non-zero code: 1.
Falling back to the version of "@expo/config" shipped with the EAS CLI.
  • But running npx expo config myself, results in the printing of the development config.

What am I missing?

I also thought that adding the env APP_VARIANT in the eas.json is redundant due to the environments being available on EAS build servers.

1
  • did you find a solution? Commented Sep 18 at 2:45

3 Answers 3

0

adding the appvariant in your eas.json is not redundant, your env is bundled at build time which your app.config.js does not exactly have access to, so at least put the appvariant env inside of your eas.json and any other variable your reference in your app.config.js

you can also manually run source your envs before you try building

set -o allexport; source .env.local; set+o allexport;
Sign up to request clarification or add additional context in comments.

1 Comment

Did you find the solution?
0

I had a similar issue when running eas credentials which doesn't have access to eas dashboard env variables (like eas build does) and doesn't load .env file env variables (like npx expo run does). The fix was to run it like this: eas env:exec production "eas credentials" which allowed me to inject the eas dashboard production env variables into the credentials command so that my app.config.ts had access to the necessary env variables.

Comments

0

In my case, I had all my variables stored in .env.local file. I renamed .env.local to .env and it worked.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.