-
Notifications
You must be signed in to change notification settings - Fork 85
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[eas-cli] add
--with-eas-environment-variables-set
flag to `eas upd…
…ate` command (#2628) <!-- If this PR requires a changelog entry, add it by commenting the PR with the command `/changelog-entry [breaking-change|new-feature|bug-fix|chore] [message]`. --> <!-- You can skip the changelog check by labeling the PR with "no changelog". --> # Why https://exponent-internal.slack.com/archives/C013ZK4SA12/p1725644220583309 We are planning to introduce enhancements to our env vars system soon. Currently, we only allow people to keep secrets on EAS servers. Secrets are not readable outside of EAS servers so of course EAS Update doesn't work with them. In a new system, people can also store readable env vars on our servers, which opens new possibilities about how EAS Update can interact with env vars! In this PR I'm adding support for the `--with-eas-environment-variables-set production|preview|development` flag. If used, we use the flag's value to fetch readable env vars from our servers and use it in the `expo export` command to produce an update bundle based on these env vars. If the flag is used I'm using the `EXPO_NO_DOTENV` flag to disable Expo CLI from loading env vars from `.env` files and potentially unwillingly overwriting env vars fetched from our servers for a given environment. Users seem to face big issues with using env vars with EAS Build & Update at the moment, originating from the fact that these 2 handle different, non-compatible ways of using env vars. Env vars in the build profile and server-side secrets vs local env vars + `.env`. With this flag it will be easy to avoid envs mismatch by doing `eas update ----with-eas-environment-variables-set environment` and `eas build` with `{ ..., environment: environment, ...} in the build profile! # How Add a new hidden (for now) flag `--with-eas-environment-variables-set` that indicates which environment to use. If used fetch env vars from server. Merge and overwrite `process.env` with newly fetched env vars. Use them to resolve the expo config. Don't use `.env` env var loading from Expo CLI if server-side env vars are used. # Test Plan Test manually. Run `eas update` with and without a new flag. Check that the expo config is resolved correctly.
- Loading branch information
1 parent
a212662
commit d0f01cb
Showing
24 changed files
with
337 additions
and
38 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
42 changes: 42 additions & 0 deletions
42
packages/eas-cli/src/commandUtils/context/ServerSideEnvironmentVariablesContextField.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
import ContextField, { ContextOptions } from './ContextField'; | ||
import { createGraphqlClient } from './contextUtils/createGraphqlClient'; | ||
import { findProjectDirAndVerifyProjectSetupAsync } from './contextUtils/findProjectDirAndVerifyProjectSetupAsync'; | ||
import { getProjectIdAsync } from './contextUtils/getProjectIdAsync'; | ||
import { loadServerSideEnvironmentVariablesAsync } from './contextUtils/loadServerSideEnvironmentVariablesAsync'; | ||
import { getPublicExpoConfig } from '../../project/expoConfig'; | ||
|
||
type GetServerSideEnvironmentVariablesFn = ( | ||
maybeEnv?: Record<string, string> | ||
) => Promise<Record<string, string>>; | ||
|
||
export class ServerSideEnvironmentVariablesContextField extends ContextField<GetServerSideEnvironmentVariablesFn> { | ||
async getValueAsync({ | ||
nonInteractive, | ||
sessionManager, | ||
withServerSideEnvironment, | ||
}: ContextOptions): Promise<GetServerSideEnvironmentVariablesFn> { | ||
const projectDir = await findProjectDirAndVerifyProjectSetupAsync(); | ||
return async (maybeEnv?: Record<string, string>) => { | ||
if (!withServerSideEnvironment) { | ||
throw new Error( | ||
'withServerSideEnvironment parameter is required to evaluate ServerSideEnvironmentVariablesContextField' | ||
); | ||
} | ||
const exp = getPublicExpoConfig(projectDir, { env: maybeEnv }); | ||
const projectId = await getProjectIdAsync(sessionManager, exp, { | ||
nonInteractive, | ||
env: maybeEnv, | ||
}); | ||
const { authenticationInfo } = await sessionManager.ensureLoggedInAsync({ | ||
nonInteractive, | ||
}); | ||
const graphqlClient = createGraphqlClient(authenticationInfo); | ||
const serverSideEnvironmentVariables = await loadServerSideEnvironmentVariablesAsync({ | ||
environment: withServerSideEnvironment, | ||
projectId, | ||
graphqlClient, | ||
}); | ||
return serverSideEnvironmentVariables; | ||
}; | ||
} | ||
} |
68 changes: 68 additions & 0 deletions
68
.../eas-cli/src/commandUtils/context/contextUtils/loadServerSideEnvironmentVariablesAsync.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
import { ExpoGraphqlClient } from './createGraphqlClient'; | ||
import { EnvironmentVariableEnvironment } from '../../../graphql/generated'; | ||
import { EnvironmentVariablesQuery } from '../../../graphql/queries/EnvironmentVariablesQuery'; | ||
import Log from '../../../log'; | ||
|
||
const cachedServerSideEnvironmentVariables: Record< | ||
EnvironmentVariableEnvironment, | ||
Record<string, string> | null | ||
> = { | ||
[EnvironmentVariableEnvironment.Development]: null, | ||
[EnvironmentVariableEnvironment.Preview]: null, | ||
[EnvironmentVariableEnvironment.Production]: null, | ||
}; | ||
|
||
export async function loadServerSideEnvironmentVariablesAsync({ | ||
environment, | ||
projectId, | ||
graphqlClient, | ||
}: { | ||
environment: EnvironmentVariableEnvironment; | ||
projectId: string; | ||
graphqlClient: ExpoGraphqlClient; | ||
}): Promise<Record<string, string>> { | ||
// don't load environment variables if they were already loaded while executing a command | ||
const cachedEnvVarsForEnvironment = cachedServerSideEnvironmentVariables[environment]; | ||
if (cachedEnvVarsForEnvironment) { | ||
return cachedEnvVarsForEnvironment; | ||
} | ||
|
||
const environmentVariables = await EnvironmentVariablesQuery.byAppIdWithSensitiveAsync( | ||
graphqlClient, | ||
{ | ||
appId: projectId, | ||
environment, | ||
} | ||
); | ||
const serverEnvVars = Object.fromEntries( | ||
environmentVariables | ||
.filter(({ name, value }) => name && value) | ||
.map(({ name, value }) => [name, value]) | ||
) as Record<string, string>; | ||
|
||
if (Object.keys(serverEnvVars).length > 0) { | ||
Log.log( | ||
`Environment variables loaded from the "${environment.toLowerCase()}" environment on EAS servers: ${Object.keys( | ||
serverEnvVars | ||
).join(', ')}.` | ||
); | ||
} else { | ||
Log.log( | ||
`No environment variables found for the "${environment.toLowerCase()}" environment on EAS servers.` | ||
); | ||
} | ||
|
||
const encryptedEnvVars = environmentVariables.filter(({ name, value }) => name && !value); | ||
if (encryptedEnvVars.length > 0) { | ||
Log.warn( | ||
`Some environment variables defined in the "${environment.toLowerCase()}" environment on EAS servers are of "encrypted" type and cannot be read outside of the EAS servers (including EAS CLI): ${encryptedEnvVars | ||
.map(({ name }) => name) | ||
.join(', ')}. ` | ||
); | ||
} | ||
Log.newLine(); | ||
|
||
cachedServerSideEnvironmentVariables[environment] = serverEnvVars; | ||
|
||
return serverEnvVars; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.