Compare commits

...
5 changed files with 166 additions and 0 deletions

No files matched your search

+1
View File
@@ -12,6 +12,7 @@ This is the log of notable changes to EAS CLI and related packages.
- [build-tools][eas-cli] Detect iOS Development provisioning profiles and set correct code signing identity instead of treating them as Ad Hoc. ([#3496](https://github.com/expo/eas-cli/pull/3496) by [@qwertey6](https://github.com/qwertey6))
- [build-tools] Prevent detecting Yarn Modern as Classic based on lockfile ([#3572](https://github.com/expo/eas-cli/pull/3572) by [@kitten](https://github.com/kitten))
- [worker] Read `WORKER_CAPABILITIES_BASE64` and set `EAS_BUILD_NESTED_VIRTUALIZATION_ENABLED` from declared worker capabilities. ([dca786a9](https://github.com/expo/eas-cli/commit/dca786a9948dce43ddbb753a2c4371bd2b8386f0) by [@gwdp](https://github.com/gwdp))
### 🧹 Chores
@@ -0,0 +1,66 @@
function workerCapabilitiesB64(payload: Record<string, unknown>): string {
return Buffer.from(JSON.stringify(payload), 'utf8').toString('base64');
}
function loadConfigFresh(): typeof import('../config').default {
jest.resetModules();
// eslint-disable-next-line @typescript-eslint/no-require-imports
return require('../config').default;
}
describe('config capabilities (WORKER_CAPABILITIES_BASE64)', () => {
beforeEach(() => {
delete process.env.WORKER_CAPABILITIES_BASE64;
jest.resetModules();
});
afterEach(() => {
delete process.env.WORKER_CAPABILITIES_BASE64;
jest.resetModules();
});
it('defaults nestedVirtualizationEnabled to false when the env var is unset', () => {
const config = loadConfigFresh();
expect(config.capabilities.nestedVirtualizationEnabled).toBe(false);
});
it('treats empty or whitespace WORKER_CAPABILITIES_BASE64 as nested virt disabled', () => {
process.env.WORKER_CAPABILITIES_BASE64 = '';
let config = loadConfigFresh();
expect(config.capabilities.nestedVirtualizationEnabled).toBe(false);
process.env.WORKER_CAPABILITIES_BASE64 = ' \t ';
config = loadConfigFresh();
expect(config.capabilities.nestedVirtualizationEnabled).toBe(false);
});
it('reads nested_virtualization_enabled true from base64 JSON', () => {
process.env.WORKER_CAPABILITIES_BASE64 = workerCapabilitiesB64({
nested_virtualization_enabled: true,
});
const config = loadConfigFresh();
expect(config.capabilities.nestedVirtualizationEnabled).toBe(true);
});
it('reads nested_virtualization_enabled false from base64 JSON', () => {
process.env.WORKER_CAPABILITIES_BASE64 = workerCapabilitiesB64({
nested_virtualization_enabled: false,
});
const config = loadConfigFresh();
expect(config.capabilities.nestedVirtualizationEnabled).toBe(false);
});
it('treats non-boolean nested_virtualization_enabled as false', () => {
process.env.WORKER_CAPABILITIES_BASE64 = workerCapabilitiesB64({
nested_virtualization_enabled: '1',
});
const config = loadConfigFresh();
expect(config.capabilities.nestedVirtualizationEnabled).toBe(false);
});
it('treats missing nested_virtualization_enabled as false', () => {
process.env.WORKER_CAPABILITIES_BASE64 = workerCapabilitiesB64({});
const config = loadConfigFresh();
expect(config.capabilities.nestedVirtualizationEnabled).toBe(false);
});
});
+66
View File
@@ -5,9 +5,11 @@ import { getBuildEnv } from '../env';
describe(getBuildEnv.name, () => {
const originalSentryDsn = config.sentry.dsn;
const originalNestedVirt = config.capabilities.nestedVirtualizationEnabled;
afterEach(() => {
config.sentry.dsn = originalSentryDsn;
config.capabilities.nestedVirtualizationEnabled = originalNestedVirt;
});
it('passes the CLI sentry DSN to worker child processes', () => {
@@ -57,4 +59,68 @@ describe(getBuildEnv.name, () => {
expect(env.EXPO_USE_PRECOMPILED_MODULES).toBe('1');
expect(env.EXPO_PRECOMPILED_MODULES_PATH).toBeUndefined();
});
it('sets EAS_BUILD_NESTED_VIRTUALIZATION_ENABLED from worker capabilities when known', () => {
config.capabilities.nestedVirtualizationEnabled = true;
const env = getBuildEnv({
job: {
platform: Platform.ANDROID,
type: Workflow.MANAGED,
builderEnvironment: { env: {} },
username: 'expo-user',
} as any,
projectId: 'project-id',
metadata: {
buildProfile: 'production',
gitCommitHash: 'abc123',
username: 'expo-user',
} as any,
buildId: 'build-id',
});
expect(env.EAS_BUILD_NESTED_VIRTUALIZATION_ENABLED).toBe('1');
});
it('sets EAS_BUILD_NESTED_VIRTUALIZATION_ENABLED to 0 when nested virt is disabled', () => {
config.capabilities.nestedVirtualizationEnabled = false;
const env = getBuildEnv({
job: {
platform: Platform.ANDROID,
type: Workflow.MANAGED,
builderEnvironment: { env: {} },
username: 'expo-user',
} as any,
projectId: 'project-id',
metadata: {
buildProfile: 'production',
gitCommitHash: 'abc123',
username: 'expo-user',
} as any,
buildId: 'build-id',
});
expect(env.EAS_BUILD_NESTED_VIRTUALIZATION_ENABLED).toBe('0');
});
it('defaults EAS_BUILD_NESTED_VIRTUALIZATION_ENABLED to 0 when capability defaults to false', () => {
const env = getBuildEnv({
job: {
platform: Platform.ANDROID,
type: Workflow.MANAGED,
builderEnvironment: { env: {} },
username: 'expo-user',
} as any,
projectId: 'project-id',
metadata: {
buildProfile: 'production',
gitCommitHash: 'abc123',
username: 'expo-user',
} as any,
buildId: 'build-id',
});
expect(env.EAS_BUILD_NESTED_VIRTUALIZATION_ENABLED).toBe('0');
});
});
+27
View File
@@ -21,6 +21,27 @@ function createBase64EnvTransformer<TFieldName extends string>(
};
}
/** JSON inside `WORKER_CAPABILITIES_BASE64` (see workflow-orchestration `worker_capabilities.go`). */
type WorkerCapabilitiesJson = {
nested_virtualization_enabled?: boolean;
};
function createWorkerCapabilitiesEnvTransformer<TFieldName extends keyof WorkerCapabilitiesJson>(
field: TFieldName
): (valueRaw: string) => boolean {
return (valueRaw: string) => {
// Set-but-empty behaves like unset (`defaultValue: false` is not applied when the key exists).
if (!valueRaw.trim()) {
return false;
}
const json = JSON.parse(
Buffer.from(valueRaw, 'base64').toString('utf8')
) as WorkerCapabilitiesJson;
const value = json?.[field];
return typeof value === 'boolean' ? value : false;
};
}
export default {
env: env<Environment>('ENVIRONMENT', { oneOf: Environment }),
port: env('PORT', { defaultValue: 3005, transform: Number }),
@@ -98,6 +119,12 @@ export default {
transform: createBase64EnvTransformer('cocoapodsCacheUrl'),
defaultValue: null,
}),
capabilities: {
nestedVirtualizationEnabled: env<boolean>('WORKER_CAPABILITIES_BASE64', {
transform: createWorkerCapabilitiesEnvTransformer('nested_virtualization_enabled'),
defaultValue: false,
}),
},
runMetricsServer: env<boolean | null>('WORKER_RUNTIME_CONFIG_BASE64', {
transform: createBase64EnvTransformer('runMetricsServer'),
defaultValue: null,
+6
View File
@@ -48,6 +48,12 @@ export function getBuildEnv({
setEnv(env, 'EAS_BUILD_WORKINGDIR', path.join(config.workingdir, 'build'));
setEnv(env, 'EAS_BUILD_PROJECT_ID', projectId);
setEnv(
env,
'EAS_BUILD_NESTED_VIRTUALIZATION_ENABLED',
config.capabilities.nestedVirtualizationEnabled ? '1' : '0'
);
const runnerPlatform =
job.platform ?? (config.resourceClass && ResourceClassToPlatform[config.resourceClass]);
if (runnerPlatform === Platform.IOS) {