Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/build-tools/src/common/projectSources.ts
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,7 @@ async function uploadProjectMetadataAsync(
}
`),
{
buildId: ctx.env.EAS_BUILD_ID,
buildId: nullthrows(ctx.env.EAS_BUILD_ID, 'EAS_BUILD_ID is not set'),
projectMetadataFile: {
type: 'GCS',
bucketKey: uploadSession.bucketKey,
Expand Down
4 changes: 2 additions & 2 deletions packages/build-tools/src/context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ export interface BuildContextOptions {
reportError?: (
msg: string,
err?: Error,
options?: { tags?: Record<string, string>; extras?: Record<string, string> }
options?: { tags?: Record<string, string>; extras?: Record<string, string | undefined> }
) => void;
skipNativeBuild?: boolean;
metadata?: Metadata;
Expand All @@ -80,7 +80,7 @@ export class BuildContext<TJob extends Job = Job> {
public readonly reportError?: (
msg: string,
err?: Error,
options?: { tags?: Record<string, string>; extras?: Record<string, string> }
options?: { tags?: Record<string, string>; extras?: Record<string, string | undefined> }
) => void;
public readonly skipNativeBuild?: boolean;
public readonly expoApiV2BaseUrl?: string;
Expand Down
2 changes: 1 addition & 1 deletion packages/build-tools/src/ios/fastlane.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ export async function runFastlane(
cwd,
}: {
logger?: bunyan;
env?: Record<string, string>;
env?: Env;
cwd?: string;
} = {}
): Promise<SpawnResult> {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { asyncResult } from '@expo/results';
import { BuildFunction, BuildStepInput, BuildStepInputValueTypeName } from '@expo/steps';

import { Sentry } from '../../sentry';
import { retryOnDNSFailure } from '../../utils/retryOnDNSFailure';

export function createSubmissionEntityFunction(): BuildFunction {
Expand Down Expand Up @@ -54,18 +55,42 @@ export function createSubmissionEntityFunction(): BuildFunction {
const robotAccessToken = stepsCtx.global.staticContext.job.secrets?.robotAccessToken;
if (!robotAccessToken) {
stepsCtx.logger.error('Failed to create submission entity: no robot access token found');
Sentry.capture('Failed to create submission entity: missing robot access token');
return;
}

const buildId = inputs.build_id.value;
if (!buildId) {
stepsCtx.logger.error('Failed to create submission entity: no build ID provided');
Sentry.capture('Failed to create submission entity: missing build ID', {
extras: {
buildId,
},
});
return;
}

const workflowJobId = stepsCtx.global.env.__WORKFLOW_JOB_ID;
if (!workflowJobId) {
stepsCtx.logger.error('Failed to create submission entity: no workflow job ID found');
Sentry.capture('Failed to create submission entity: missing workflow job ID', {
extras: {
buildId,
workflowJobId,
},
});
return;
}

const expoApiServerURL = stepsCtx.global.staticContext.expoApiServerURL;
if (!expoApiServerURL) {
stepsCtx.logger.error('Failed to create submission entity: no Expo API server URL found');
Sentry.capture('Failed to create submission entity: missing Expo API server URL', {
extras: {
buildId,
workflowJobId,
},
});
return;
}

Expand All @@ -83,7 +108,7 @@ export function createSubmissionEntityFunction(): BuildFunction {

try {
const response = await retryOnDNSFailure(fetch)(
new URL('/v2/app-store-submissions/', stepsCtx.global.staticContext.expoApiServerURL),
new URL('/v2/app-store-submissions/', expoApiServerURL),
{
method: 'POST',
headers: {
Expand Down
25 changes: 15 additions & 10 deletions packages/build-tools/src/steps/functions/downloadArtifact.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { UserError } from '@expo/eas-build-job';
import { SystemError } from '@expo/eas-build-job';
import { bunyan } from '@expo/logger';
import { asyncResult } from '@expo/results';
import {
Expand Down Expand Up @@ -56,18 +56,23 @@ export function createDownloadArtifactFunction(): BuildFunction {
const interpolationContext = stepsCtx.global.getInterpolationContext();

if (!('workflow' in interpolationContext)) {
throw new UserError(
'EAS_DOWNLOAD_ARTIFACT_NO_WORKFLOW',
'No workflow found in the interpolation context.'
);
throw new SystemError('No workflow found in the interpolation context.', {
trackingCode: 'EAS_DOWNLOAD_ARTIFACT_NO_WORKFLOW',
});
}

const robotAccessToken = stepsCtx.global.staticContext.job.secrets?.robotAccessToken;
if (!robotAccessToken) {
throw new UserError(
'EAS_DOWNLOAD_ARTIFACT_NO_ROBOT_ACCESS_TOKEN',
'No robot access token found in the job secrets.'
);
throw new SystemError('No robot access token found in the job secrets.', {
trackingCode: 'EAS_DOWNLOAD_ARTIFACT_NO_ROBOT_ACCESS_TOKEN',
});
}

const expoApiServerURL = stepsCtx.global.staticContext.expoApiServerURL;
if (!expoApiServerURL) {
throw new SystemError('Missing Expo API server URL.', {
trackingCode: 'EAS_DOWNLOAD_ARTIFACT_NO_EXPO_API_SERVER_URL',
});
}

const workflowRunId = interpolationContext.workflow.id;
Expand All @@ -82,7 +87,7 @@ export function createDownloadArtifactFunction(): BuildFunction {
const { artifactPath } = await downloadArtifactAsync({
logger,
workflowRunId,
expoApiServerURL: stepsCtx.global.staticContext.expoApiServerURL,
expoApiServerURL,
robotAccessToken,
params,
});
Expand Down
6 changes: 5 additions & 1 deletion packages/build-tools/src/steps/functions/restoreCache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,10 @@ export function createRestoreCacheFunction(): BuildFunction {
.filter(key => key !== '');

const jobId = nullthrows(env.EAS_BUILD_ID, 'EAS_BUILD_ID is not set');
const expoApiServerURL = nullthrows(
stepsCtx.global.staticContext.expoApiServerURL,
'expoApiServerURL is not set'
);
const robotAccessToken = nullthrows(
stepsCtx.global.staticContext.job.secrets?.robotAccessToken,
'robotAccessToken is not set'
Expand All @@ -77,7 +81,7 @@ export function createRestoreCacheFunction(): BuildFunction {
const { archivePath, matchedKey } = await downloadCacheAsync({
logger,
jobId,
expoApiServerURL: stepsCtx.global.staticContext.expoApiServerURL,
expoApiServerURL,
robotAccessToken,
paths,
key,
Expand Down
8 changes: 6 additions & 2 deletions packages/build-tools/src/steps/functions/saveCache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@ export function createSaveCacheFunction(): BuildFunction {
.filter(path => path.length > 0);
const key = z.string().parse(inputs.key.value);
const jobId = nullthrows(env.EAS_BUILD_ID, 'EAS_BUILD_ID is not set');
const expoApiServerURL = nullthrows(
stepsCtx.global.staticContext.expoApiServerURL,
'expoApiServerURL is not set'
);
const robotAccessToken = nullthrows(
stepsCtx.global.staticContext.job.secrets?.robotAccessToken,
'robotAccessToken is not set'
Expand All @@ -61,7 +65,7 @@ export function createSaveCacheFunction(): BuildFunction {
await uploadPublicCacheAsync({
logger,
jobId,
expoApiServerURL: stepsCtx.global.staticContext.expoApiServerURL,
expoApiServerURL,
robotAccessToken,
archivePath,
key,
Expand All @@ -73,7 +77,7 @@ export function createSaveCacheFunction(): BuildFunction {
await uploadCacheAsync({
logger,
jobId,
expoApiServerURL: stepsCtx.global.staticContext.expoApiServerURL,
expoApiServerURL,
robotAccessToken,
archivePath,
key,
Expand Down
3 changes: 2 additions & 1 deletion packages/build-tools/src/utils/expoUpdates.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import assert from 'assert';
import fs from 'fs-extra';
import { graphql } from 'gql.tada';
import fetch from 'node-fetch';
import nullthrows from 'nullthrows';
import os from 'os';
import path from 'path';
import { v4 as uuidv4 } from 'uuid';
Expand Down Expand Up @@ -257,7 +258,7 @@ async function logDiffFingerprints({
}
}
`),
{ id: ctx.env.EAS_BUILD_ID }
{ id: nullthrows(ctx.env.EAS_BUILD_ID, 'EAS_BUILD_ID is not set') }

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it safe to do nullthrows here? What about local builds?

)
.toPromise();

Expand Down
2 changes: 1 addition & 1 deletion packages/eas-build-job/src/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ export const ArchiveSourceSchemaZ = z.discriminatedUnion('type', [
}),
]);

export type Env = Record<string, string>;
export type Env = Record<string, string | undefined>;
export const EnvSchema = Joi.object().pattern(Joi.string(), Joi.string());

export type EnvironmentSecret = {
Expand Down
2 changes: 1 addition & 1 deletion packages/eas-build-job/src/context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ type StaticJobOnlyInterpolationContext = {
outputs: Record<string, string | undefined>;
}
>;
expoApiServerURL: string;
expoApiServerURL: string | undefined;
};
Comment thread
sjchmiela marked this conversation as resolved.

export type StaticJobInterpolationContext =
Expand Down
4 changes: 2 additions & 2 deletions packages/eas-cli/src/build/context.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { ExpoConfig } from '@expo/config';
import { Platform, Workflow } from '@expo/eas-build-job';
import { Env, Platform, Workflow } from '@expo/eas-build-job';
import { BuildProfile, EasJson } from '@expo/eas-json';
import { LoggerLevel } from '@expo/logger';
import { NodePackageManager } from '@expo/package-manager';
Expand Down Expand Up @@ -65,5 +65,5 @@ export interface BuildContext<T extends Platform> {
loggerLevel?: LoggerLevel;
isVerboseLoggingEnabled: boolean;
whatToTest?: string;
env: Record<string, string>;
env: Env;
}
4 changes: 2 additions & 2 deletions packages/eas-cli/src/build/createContext.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Platform } from '@expo/eas-build-job';
import { Env, Platform } from '@expo/eas-build-job';
import { BuildProfile, EasJson, ResourceClass } from '@expo/eas-json';
import JsonFile from '@expo/json-file';
import { LoggerLevel } from '@expo/logger';
Expand Down Expand Up @@ -69,7 +69,7 @@ export async function createBuildContextAsync<T extends Platform>({
refreshAdHocProvisioningProfile?: boolean;
isVerboseLoggingEnabled: boolean;
whatToTest?: string;
env: Record<string, string>;
env: Env;
}): Promise<BuildContext<T>> {
const { exp, projectId } = await getDynamicPrivateProjectConfigAsync({
env,
Expand Down
4 changes: 2 additions & 2 deletions packages/eas-cli/src/build/local.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Job, Metadata, version } from '@expo/eas-build-job';
import { Env, Job, Metadata, version } from '@expo/eas-build-job';
import spawnAsync from '@expo/spawn-async';
import { ChildProcess } from 'child_process';
import semver from 'semver';
Expand Down Expand Up @@ -42,7 +42,7 @@ export async function runLocalBuildAsync(
job: Job,
metadata: Metadata,
options: LocalBuildOptions,
env: Record<string, string>
env: Env
): Promise<void> {
const { command, args } = await getCommandAndArgsAsync(job, metadata);
let spinner;
Expand Down
4 changes: 2 additions & 2 deletions packages/eas-cli/src/fingerprint/utils.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Platform, Workflow } from '@expo/eas-build-job';
import { Env, Platform, Workflow } from '@expo/eas-build-job';

import { createFingerprintAsync } from './cli';
import { Fingerprint } from './types';
Expand All @@ -16,7 +16,7 @@ export async function getFingerprintInfoFromLocalProjectForPlatformsAsync(
projectId: string,
vcsClient: Client,
platforms: AppPlatform[],
{ env }: { env?: Record<string, string> } = {}
{ env }: { env?: Env } = {}
): Promise<Fingerprint> {
const workflows = await resolveWorkflowPerPlatformAsync(projectDir, vcsClient);
const optionsFromWorkflow = getFingerprintOptionsFromWorkflow(platforms, workflows);
Expand Down
5 changes: 3 additions & 2 deletions packages/eas-cli/src/project/ios/entitlements.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { ExportedConfig, IOSConfig, compileModsAsync } from '@expo/config-plugins';
import { Env } from '@expo/eas-build-job';
import { JSONObject } from '@expo/json-file';
import { getPrebuildConfigAsync } from '@expo/prebuild-config';

Expand All @@ -17,7 +18,7 @@ interface Target {

export async function getManagedApplicationTargetEntitlementsAsync(
projectDir: string,
env: Record<string, string>,
env: Env,
vcsClient: Client
): Promise<JSONObject> {
let expoConfigError: any;
Expand Down Expand Up @@ -95,7 +96,7 @@ export async function getManagedApplicationTargetEntitlementsAsync(

async function resolveManagedApplicationTargetEntitlementsWithBundledConfigAsync(
projectDir: string,
env: Record<string, string>,
env: Env,
vcsClient: Client
): Promise<JSONObject> {
const originalProcessEnv = process.env;
Expand Down
4 changes: 2 additions & 2 deletions packages/eas-cli/src/project/ios/target.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { ExpoConfig } from '@expo/config';
import { IOSConfig, XcodeProject } from '@expo/config-plugins';
import { Platform, Workflow } from '@expo/eas-build-job';
import { Env, Platform, Workflow } from '@expo/eas-build-job';
import { JSONObject } from '@expo/json-file';
import Joi from 'joi';
import type { XCBuildConfiguration } from 'xcode';
Expand All @@ -26,7 +26,7 @@ interface UserDefinedTarget {
interface ResolveTargetOptions {
projectDir: string;
exp: ExpoConfig;
env?: Record<string, string>;
env?: Env;
xcodeBuildContext: XcodeBuildContext;
vcsClient: Client;
}
Expand Down
4 changes: 2 additions & 2 deletions packages/eas-cli/src/submit/context.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { ExpoConfig } from '@expo/config';
import { Platform } from '@expo/eas-build-job';
import { Env, Platform } from '@expo/eas-build-job';
import { SubmitProfile } from '@expo/eas-json';
import { v4 as uuidv4 } from 'uuid';

Expand Down Expand Up @@ -47,7 +47,7 @@ export interface SubmitArchiveFlags {
export async function createSubmissionContextAsync<T extends Platform>(params: {
archiveFlags: SubmitArchiveFlags;
credentialsCtx?: CredentialsContext;
env?: Record<string, string>;
env?: Env;
nonInteractive: boolean;
isVerboseFastlaneEnabled: boolean;
groups: string[] | undefined;
Expand Down
16 changes: 11 additions & 5 deletions packages/worker/src/displayRuntimeInfo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,24 +70,30 @@ function printImageDescription(ctx: BuildContext<Job>): void {
function printEnvs(ctx: BuildContext<Job>): void {
const { logger, job } = ctx;
const publicEnv: Record<string, string> = {};
const secretEnv: Record<string, string> = {};
// We don't expect environment secrets to be missing from ctx.env,
// but if they do we want to see it in logs as "=undefined".
const secretEnv: Record<string, string | undefined> = {};
const instanceEnv: Record<string, string> = {};

// skip development and testing to avoid leaking local credentials from envs to bucket
if (config.env !== Environment.DEVELOPMENT && config.env !== Environment.TEST) {
Object.entries(ctx.env).forEach(([key, value]) => {
instanceEnv[key] = value;
if (value !== undefined) {
instanceEnv[key] = value;
}
});
}
Object.entries(job.builderEnvironment?.env ?? ({} as Record<string, string>)).forEach(
([key, value]) => {
Object.entries(job.builderEnvironment?.env ?? {}).forEach(([key, value]) => {
if (value !== undefined) {
publicEnv[key] = value;
delete instanceEnv[key];
}
);
});

job.secrets?.environmentSecrets?.forEach(({ name, type }) => {
if (type === EnvironmentSecretType.FILE) {
// ctx.env[name] for a FILE-typed environment secret
// should be a path to the file.
secretEnv[name] = ctx.env[name];
} else {
secretEnv[name] = '********';
Expand Down
Loading