Compare commits

...
Author SHA1 Message Date
Gabe Debes d596ad4f1c [build-tools] Use local argent binary when EXPO_LOCAL=1 2026-06-30 23:29:35 -07:00
2 changed files with 76 additions and 6 deletions

No files matched your search

@@ -1,11 +1,20 @@
import { SystemError } from '@expo/eas-build-job';
import { type bunyan } from '@expo/logger';
import { spawnSync } from 'node:child_process';
import {
MIN_ARGENT_REMOTE_SESSION_VERSION,
resolveArgentInvocation,
resolveLocalArgentBin,
warnIfArgentPackageVersionCannotBeVerified,
} from '../startArgentRemoteSession';
jest.mock('node:child_process', () => ({
spawnSync: jest.fn(),
}));
const mockedSpawnSync = jest.mocked(spawnSync);
describe(warnIfArgentPackageVersionCannotBeVerified, () => {
const warn = jest.fn();
const logger = { warn } as unknown as bunyan;
@@ -70,3 +79,32 @@ describe(warnIfArgentPackageVersionCannotBeVerified, () => {
);
});
});
describe(resolveArgentInvocation, () => {
it('runs the local binary directly when one is provided', () => {
expect(
resolveArgentInvocation({ localArgentBin: '/usr/local/bin/argent', versionSpec: '1.2.3' })
).toEqual({ command: '/usr/local/bin/argent', packageArgs: [] });
});
it('fetches the pinned package via bunx when there is no local binary', () => {
expect(resolveArgentInvocation({ localArgentBin: null, versionSpec: '1.2.3' })).toEqual({
command: 'bunx',
packageArgs: ['@swmansion/[email protected]'],
});
});
});
describe(resolveLocalArgentBin, () => {
it('returns the resolved path when argent is on PATH', () => {
mockedSpawnSync.mockReturnValue({ status: 0, stdout: '/usr/local/bin/argent\n' } as ReturnType<
typeof spawnSync
>);
expect(resolveLocalArgentBin()).toBe('/usr/local/bin/argent');
});
it('returns null when argent is not on PATH', () => {
mockedSpawnSync.mockReturnValue({ status: 1, stdout: '' } as ReturnType<typeof spawnSync>);
expect(resolveLocalArgentBin()).toBeNull();
});
});
@@ -7,6 +7,7 @@ import {
BuildStepInputValueTypeName,
} from '@expo/steps';
import spawn from '@expo/turtle-spawn';
import { spawnSync } from 'node:child_process';
import fs from 'node:fs';
import os from 'node:os';
import path from 'node:path';
@@ -70,6 +71,13 @@ export function createStartArgentRemoteSessionBuildFunction(
`Starting argent remote session (version: ${versionSpec}, runtime: ${runtimePlatform}).`
);
// In local dev, run the argent already on PATH instead of fetching it via bunx.
const localArgentBin = env.EXPO_LOCAL === '1' ? resolveLocalArgentBin() : null;
const { command: argentCommand, packageArgs: argentPackageArgs } = resolveArgentInvocation({
localArgentBin,
versionSpec,
});
if (runtimePlatform === BuildRuntimePlatform.DARWIN) {
await selectXcodeDeveloperDirectoryAsync({ env, logger });
}
@@ -78,16 +86,23 @@ export function createStartArgentRemoteSessionBuildFunction(
await fs.promises.rm(ARGENT_STATE_FILE, { force: true });
logger.info('Enabling the Argent artifacts list endpoint flag.');
await spawn(
'bunx',
[`${ARGENT_PACKAGE_NAME}@${versionSpec}`, 'enable', ARGENT_ARTIFACTS_LIST_ENDPOINT_FLAG],
{ env, logger }
argentCommand,
[...argentPackageArgs, 'enable', ARGENT_ARTIFACTS_LIST_ENDPOINT_FLAG],
{
env,
logger,
}
);
logger.info(`Launching ${ARGENT_PACKAGE_NAME}@${versionSpec} tool-server via bunx.`);
logger.info(
localArgentBin
? `Launching local argent tool-server (${localArgentBin}).`
: `Launching ${ARGENT_PACKAGE_NAME}@${versionSpec} tool-server via bunx.`
);
const argentServer = spawnDetached({
command: 'bunx',
command: argentCommand,
args: [
`${ARGENT_PACKAGE_NAME}@${versionSpec}`,
...argentPackageArgs,
'server',
'start',
'--port',
@@ -199,6 +214,23 @@ export function warnIfArgentPackageVersionCannotBeVerified({
}
}
export function resolveLocalArgentBin(): string | null {
const result = spawnSync('which', ['argent'], { encoding: 'utf8' });
return result.status === 0 ? result.stdout.trim() : null;
}
export function resolveArgentInvocation({
localArgentBin,
versionSpec,
}: {
localArgentBin: string | null;
versionSpec: string;
}): { command: string; packageArgs: string[] } {
return localArgentBin
? { command: localArgentBin, packageArgs: [] }
: { command: 'bunx', packageArgs: [`${ARGENT_PACKAGE_NAME}@${versionSpec}`] };
}
function parseArgentToolServerState(raw: string): { port: number; token?: string } {
const result = ArgentToolServerStateSchema.safeParse(JSON.parse(raw));
if (!result.success) {