EAS project ID with dynamic configuration

Running eas build (eas-cli 2.0.0) yields the following message:

Warning: Your project uses dynamic app configuration, and the EAS project ID can’t automatically be added to it.
Configuration with app.json / app.config.js - Expo Documentation

To complete the setup process, set the extra.eas.projectId in your app.config.js or app.json:

{
“expo”: {
“extra”: {
“eas”: {
“projectId”: “…”
}
}
}
}

However, my dynamic configuration is a function that receives the static configuration as its argument, as described in the linked documentation. It seems to me that the EAS project ID (obviously known by eas-cli) should be merged into that configuration, instead of nagging me to go set it manually. It seems counterproductive for the dynamic configuration to make things less dynamic, and this may just be an oversight in the design of eas-cli.

Thanks!

hello! the project id is replacing the owner / slug as the identifier for expo projects. the reason for this is that it’s a stable identifier that helps us to ensure that the developer is not accidentally doing something under the wrong project before, during, or after project transfers/renames/etc. so, you should add it to your app.json or app.config.js.

My understanding is that the slug is already stable, and it has the advantage of being human readable. It’s hard to imagine how adding a UUID will improve the developer’s ability to target the right EAS project, since they are opaque, and they’re no more unique to Expo than account+slug.

For developers with more than one EAS project - presumably the only ones who could derive any benefit from a project UUID - there must be some way that they are determining locally which project configuration to use, and that determination seems likely to be based on the slug in one way or another. It’s hard for me to see how the UUID provides value to the developer.

Since it is required by the tooling, I will take the manual step to add this to all my configurations, but it seems overdetermined, and makes it easier rather than harder to misconfigure.

Yes… if you never transfer the project. I think the UUID was likely added to make transfers easier. But it’s just my guess.

I wonder if it does actually make transfers easier. In most cases, it seems like the slug would remain the same during a project transfer. In those cases where it didn’t, the developer would know they were changing the slug as part of the transfer. It seems like changing the identity key for every project to an opaque value in order to cover this (edge) case is not weighing developer needs/expectations correctly.

Yes, the slug would remain the same. But the account would of course change.
Apps trying to fetch updates from oldaccount/slug would have to be redirected to newaccount/slug.
Whereas if they are using the UUID instead, then no redirect needs to happen and Expo’s servers don’t have to keep track of what apps were transferred from where to where.

I think that’s the point I was trying to make: this seems to be a convenience for Expo to handle this case, but the impact is felt by all developers using the platform. If the UUID must be used at runtime to resolve EAS updates, there is no reason that Expo cannot resolve the UUID from the current account+slug at build time and include it in the build. Making this a developer concern seems to invite problems rather than solve them.

Since it is required by the tooling, I will take the manual step to add this to all my configurations, but it seems overdetermined, and makes it easier rather than harder to misconfigure.

can you explain what you mean by “all my configurations”? for most developers, they would do this once in their project, it would take several seconds, and they’d be done with it. i’m very interested in learning about your use case where this is problematic

Hi, Brent. We have one codebase that produces several different apps and uses a different Expo project for each app. For some of these apps, we have a separate staging build configured which points to our staging server environment (and is helpfully identified by a distinct app icon), each of which uses a different Expo project. My understanding is that this is one of the purposes of dynamic configuration, along the lines of the ability to “swap out configuration entirely in order to white label an app” as described in the documentation.

For each of these configuration sets, we must now store the EAS project ID. This certainly isn’t difficult, but it seems wrong - because each configuration already identifies itself uniquely by its slug. When I add the UUID for an EAS project, I’m either adding an extraneous specification (if the identifiers match up), or I’m introducing an inconsistent configuration (if they don’t).

I’m facing the same warning, and I believe my user case is close to alpinemedia. We serve multiple apps from the same Expo Codebase, and we’re storing each different client configuration on different folde/repository, before we build we have a little automation that will copy/move every client file to the project and trigger eas for mobile builds and perform necessary actions for web builds/sync.

Is there a way to grab this projectId on the fly? Because most of times we will be creating the project on expo.dev when we trigger eas builds. It will be a new human step to copy a specific id from the site that can introduce new errors.

This is what my app.config.js looks like, we have this appClientConfig.json to every different client that stores expo specific information.

import appClientConfig from './appClientConfig.json';

export default ({ config }) => {

    const injectedClientConfig = {
        ...config,
        name: appClientConfig.name,
        slug: appClientConfig.slug,
        icon: appClientConfig.icon,
        ios: {
            ...config.ios,
            bundleIdentifier: appClientConfig.ios.bundleIdentifier,
        },
        android: {
            ...config.android,
            package: appClientConfig.android.package
        },
        extra: {
            ...config.extra,
            oneSignalAppId: appClientConfig.oneSignalAppId
        }
    }

    return injectedClientConfig
}