Skip to content

Commit

Permalink
Evaluate dynamicProjectConfig with EnvVars
Browse files Browse the repository at this point in the history
  • Loading branch information
khamilowicz committed Aug 22, 2024
1 parent 97f267b commit e17b83a
Show file tree
Hide file tree
Showing 16 changed files with 187 additions and 119 deletions.
2 changes: 1 addition & 1 deletion packages/eas-cli/src/build/android/build.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ export async function prepareAndroidBuildAsync(
? false
: ctx.buildProfile.autoIncrement,
vcsClient: ctx.vcsClient,
env: ctx.buildProfile.env,
env: ctx.env,
});
},
prepareJobAsync: async (
Expand Down
2 changes: 1 addition & 1 deletion packages/eas-cli/src/build/build.ts
Original file line number Diff line number Diff line change
Expand Up @@ -676,7 +676,7 @@ async function createAndMaybeUploadFingerprintAsync<T extends Platform>(
platform: ctx.platform,
workflow: ctx.workflow,
projectDir: ctx.projectDir,
env: ctx.buildProfile.env,
env: ctx.env,
cwd: ctx.projectDir,
});

Expand Down
4 changes: 2 additions & 2 deletions packages/eas-cli/src/build/createContext.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ export async function createBuildContextAsync<T extends Platform>({
env: Record<string, string>;
}): Promise<BuildContext<T>> {
const { exp, projectId } = await getDynamicPrivateProjectConfigAsync({
env: { ...env, ...buildProfile.env },
env,
});
const projectName = exp.slug;
const account = await getOwnerAccountForProjectIdAsync(graphqlClient, projectId);
Expand All @@ -91,7 +91,7 @@ export async function createBuildContextAsync<T extends Platform>({
user: actor,
graphqlClient,
analytics,
env: buildProfile.env,
env,
easJsonCliConfig,
vcsClient,
freezeCredentials,
Expand Down
86 changes: 86 additions & 0 deletions packages/eas-cli/src/build/evaluateConfigWithEnvVarsAsync.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import { Env } from '@expo/eas-build-job';
import { BuildProfile } from '@expo/eas-json';

import { ExpoGraphqlClient } from '../commandUtils/context/contextUtils/createGraphqlClient';
import { EnvironmentVariableEnvironment } from '../graphql/generated';
import { EnvironmentVariablesQuery } from '../graphql/queries/EnvironmentVariablesQuery';
import Log from '../log';

function isEnvironment(env: string): env is EnvironmentVariableEnvironment {
if (
Object.values(EnvironmentVariableEnvironment).includes(
env.toUpperCase() as EnvironmentVariableEnvironment
)
) {
return true;
}
return false;
}

export async function evaluateConfigWithEnvVarsAsync<Config extends { projectId: string }, Opts>({
flags,
buildProfile,
graphqlClient,
getProjectConfig,
opts,
}: {
flags: { environment?: string };
buildProfile: BuildProfile;
graphqlClient: ExpoGraphqlClient | null;
opts: Opts;
getProjectConfig(opts: Opts): Promise<Config>;
}): Promise<Config & { env: Env }> {
if (!graphqlClient) {
Log.warn('An Expo user account is required to fetch environment variables.');
const config = await getProjectConfig(opts);
return { env: buildProfile.env ?? {}, ...config };
}
const { projectId } = await getProjectConfig({ env: buildProfile.env, ...opts });
const env = await resolveEnvVarsAsync({ flags, buildProfile, graphqlClient, projectId });
const config = await getProjectConfig({ ...opts, env });

return { env, ...config };
}

async function resolveEnvVarsAsync({
flags,
buildProfile,
graphqlClient,
projectId,
}: {
flags: { environment?: string };
buildProfile: BuildProfile;
graphqlClient: ExpoGraphqlClient;
projectId: string;
}): Promise<Env> {
const environment =
flags.environment ?? buildProfile.environment ?? process.env.EAS_CURRENT_ENVIRONMENT;

if (!environment || !isEnvironment(environment)) {
return { ...buildProfile.env };
}

try {
const environmentVariables = await EnvironmentVariablesQuery.byAppIdWithSensitiveAsync(
graphqlClient,
{
appId: projectId,
environment,
}
);
const envVars = Object.fromEntries(
environmentVariables
.filter(({ name, value }) => name && value)
.map(({ name, value }) => [name, value])
) as Record<string, string>;

return { ...envVars, ...buildProfile.env };
} catch (e) {
Log.error('Failed to pull env variables for environment ${environment} from EAS servers');
Log.error(e);
Log.error(
'This can possibly be a bug in EAS/EAS CLI. Report it here: https://github.com/expo/eas-cli/issues'
);
return { ...buildProfile.env };
}
}
6 changes: 3 additions & 3 deletions packages/eas-cli/src/build/ios/build.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import {
export async function createIosContextAsync(
ctx: CommonContext<Platform.IOS>
): Promise<IosBuildContext> {
const { buildProfile } = ctx;
const { buildProfile, env } = ctx;

if (ctx.workflow === Workflow.MANAGED) {
await ensureBundleIdentifierIsDefinedForManagedProjectAsync(ctx);
Expand All @@ -47,7 +47,7 @@ export async function createIosContextAsync(
projectDir: ctx.projectDir,
exp: ctx.exp,
xcodeBuildContext,
env: buildProfile.env,
env,
vcsClient: ctx.vcsClient,
});
const applicationTarget = findApplicationTarget(targets);
Expand Down Expand Up @@ -89,7 +89,7 @@ export async function prepareIosBuildAsync(
? false
: ctx.buildProfile.autoIncrement,
vcsClient: ctx.vcsClient,
env: ctx.buildProfile.env,
env: ctx.env,
});
},
prepareJobAsync: async (
Expand Down
80 changes: 9 additions & 71 deletions packages/eas-cli/src/build/runBuildAndSubmit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { ExpoConfig } from '@expo/config-types';
import { Env, Platform, Workflow } from '@expo/eas-build-job';
import {
AppVersionSource,
BuildProfile,
EasJson,
EasJsonAccessor,
EasJsonUtils,
Expand All @@ -19,6 +18,7 @@ import { BuildRequestSender, MaybeBuildFragment, waitForBuildEndAsync } from './
import { ensureProjectConfiguredAsync } from './configure';
import { BuildContext } from './context';
import { createBuildContextAsync } from './createContext';
import { evaluateConfigWithEnvVarsAsync } from './evaluateConfigWithEnvVarsAsync';
import { prepareIosBuildAsync } from './ios/build';
import { LocalBuildMode, LocalBuildOptions } from './local';
import { ensureExpoDevClientInstalledForDevClientBuildsAsync } from './utils/devClient';
Expand All @@ -37,7 +37,6 @@ import {
SubmissionFragment,
} from '../graphql/generated';
import { BuildQuery } from '../graphql/queries/BuildQuery';
import { EnvironmentVariablesQuery } from '../graphql/queries/EnvironmentVariablesQuery';
import { toAppPlatform, toPlatform } from '../graphql/types/AppPlatform';
import Log, { learnMore } from '../log';
import {
Expand Down Expand Up @@ -188,23 +187,18 @@ export async function runBuildAndSubmitAsync(

for (const buildProfile of buildProfiles) {
const platform = toAppPlatform(buildProfile.platform);
const { projectId } = await getDynamicPrivateProjectConfigAsync({
env: buildProfile.profile.env,
});
const env = await resolveEnvVarsAsync({

const { env } = await evaluateConfigWithEnvVarsAsync({
flags,
buildProfile,
buildProfile: buildProfile.profile,
graphqlClient,
projectId,
getProjectConfig: getDynamicPrivateProjectConfigAsync,
opts: { env: buildProfile.profile.env },
});

const buildVariables = { ...env, ...buildProfile.profile.env };

Log.log(
`Loaded "env" configuration for the "${buildProfile.profileName}" profile: ${
buildVariables
? Object.keys(buildVariables).join(', ')
: 'no environment variables specified'
env ? Object.keys(env).join(', ') : 'no environment variables specified'
}. ${learnMore('https://docs.expo.dev/build-reference/variables/')}`
);

Expand Down Expand Up @@ -268,7 +262,6 @@ export async function runBuildAndSubmitAsync(
buildCtx: nullthrows(buildCtxByPlatform[startedBuild.build.platform]),
moreBuilds: startedBuilds.length > 1,
projectDir,
buildProfile: startedBuild.buildProfile.profile,
submitProfile,
nonInteractive: flags.nonInteractive,
selectedSubmitProfileName: flags.submitProfile,
Expand Down Expand Up @@ -370,7 +363,7 @@ async function prepareAndStartBuildAsync({
vcsClient: Client;
getDynamicPrivateProjectConfigAsync: DynamicConfigContextFn;
customBuildConfigMetadata?: CustomBuildConfigMetadata;
env: Record<string, string>;
env: Env;
}): Promise<{ build: BuildFragment | undefined; buildCtx: BuildContext<Platform> }> {
const buildCtx = await createBuildContextAsync({
buildProfileName: buildProfile.profileName,
Expand Down Expand Up @@ -468,7 +461,6 @@ async function prepareAndStartSubmissionAsync({
buildCtx,
moreBuilds,
projectDir,
buildProfile,
submitProfile,
selectedSubmitProfileName,
nonInteractive,
Expand All @@ -477,7 +469,6 @@ async function prepareAndStartSubmissionAsync({
buildCtx: BuildContext<Platform>;
moreBuilds: boolean;
projectDir: string;
buildProfile: BuildProfile;
submitProfile: SubmitProfile;
selectedSubmitProfileName?: string;
nonInteractive: boolean;
Expand All @@ -489,7 +480,7 @@ async function prepareAndStartSubmissionAsync({
profile: submitProfile,
archiveFlags: { id: build.id },
nonInteractive,
env: buildProfile.env,
env: buildCtx.env,
credentialsCtx: buildCtx.credentialsCtx,
applicationIdentifier: buildCtx.android?.applicationId ?? buildCtx.ios?.bundleIdentifier,
actor: buildCtx.user,
Expand Down Expand Up @@ -607,56 +598,3 @@ async function validateExpoUpdatesInstalledAsProjectDependencyAsync({
}
}
}

function isEnvironment(env: string): env is EnvironmentVariableEnvironment {
if (
Object.values(EnvironmentVariableEnvironment).includes(env as EnvironmentVariableEnvironment)
) {
return true;
}
return false;
}

async function resolveEnvVarsAsync({
flags,
buildProfile,
graphqlClient,
projectId,
}: {
flags: BuildFlags;
buildProfile: ProfileData<'build'>;
graphqlClient: ExpoGraphqlClient;
projectId: string;
}): Promise<Record<string, string>> {
const environment =
flags.environment ?? buildProfile.profile.environment ?? process.env.EAS_CURRENT_ENVIRONMENT;

if (!environment || !isEnvironment(environment)) {
return {};
}

try {
const environmentVariables = await EnvironmentVariablesQuery.byAppIdWithSensitiveAsync(
graphqlClient,
{
appId: projectId,
environment,
}
);
const envVars = Object.fromEntries(
environmentVariables
.filter(({ name, value }) => name && value)
.map(({ name, value }) => [name, value])
) as Record<string, string>;

return envVars;
} catch (e) {
Log.error('Failed to pull env variables for environment ${environment} from EAS servers');
Log.error(e);
Log.error(
'This can possibly be a bug in EAS/EAS CLI. Report it here: https://github.com/expo/eas-cli/issues'
);
}

return {};
}
4 changes: 2 additions & 2 deletions packages/eas-cli/src/build/validate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ import Log, { learnMore } from '../log';
import { isPNGAsync } from '../utils/image';

export function checkNodeEnvVariable(ctx: CommonContext<Platform>): void {
if (ctx.buildProfile.env?.NODE_ENV === 'production') {
if (ctx.env?.NODE_ENV === 'production') {
Log.warn(
'You set NODE_ENV=production in the build profile. Remember that it will be available during the entire build process. In particular, it will make yarn/npm install only production packages.'
'You set NODE_ENV=production in the build profile or environment variables. Remember that it will be available during the entire build process. In particular, it will make yarn/npm install only production packages.'
);
Log.newLine();
}
Expand Down
Loading

0 comments on commit e17b83a

Please sign in to comment.