diff --git a/CHANGELOG.md b/CHANGELOG.md index a002eecdd3..808610b237 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ This is the log of notable changes to EAS CLI and related packages. - [eas-cli] Add `--refresh-ad-hoc-provisioning-profile` flag to refresh managed ad-hoc provisioning profiles from App Store Connect before gathering build credentials in non-interactive mode. ([#3716](https://github.com/expo/eas-cli/pull/3716) by [@sswrk](https://github.com/sswrk)) - [eas-build-job] Add optional `refreshAdHocProvisioningProfile` field to iOS build jobs. ([#3717](https://github.com/expo/eas-cli/pull/3717) by [@sswrk](https://github.com/sswrk)) +- [build-tools] Pass `refreshAdHocProvisioningProfile` through `eas build:internal` for git-based integration builds. ([#3770](https://github.com/expo/eas-cli/pull/3770) by [@sswrk](https://github.com/sswrk)) ### 🐛 Bug fixes diff --git a/packages/build-tools/src/common/__tests__/easBuildInternal.test.ts b/packages/build-tools/src/common/__tests__/easBuildInternal.test.ts index 9bb469cda3..64b566157f 100644 --- a/packages/build-tools/src/common/__tests__/easBuildInternal.test.ts +++ b/packages/build-tools/src/common/__tests__/easBuildInternal.test.ts @@ -1,4 +1,4 @@ -import { BuildJob } from '@expo/eas-build-job'; +import { ArchiveSourceType, BuildJob, Platform, Workflow } from '@expo/eas-build-job'; import spawn from '@expo/turtle-spawn'; import { resolveEnvFromBuildProfileAsync, runEasBuildInternalAsync } from '../easBuildInternal'; @@ -15,7 +15,7 @@ jest.mock('../../utils/easCli', () => ({ describe('easBuildInternal', () => { beforeEach(() => { - jest.resetAllMocks(); + jest.clearAllMocks(); jest.mocked(resolveEasCommandPrefixAndEnvAsync).mockResolvedValue({ cmd: 'npx', args: ['-y', 'eas-cli@latest'], @@ -69,4 +69,131 @@ describe('easBuildInternal', () => { expect(resolveEasCommandPrefixAndEnvAsync).toHaveBeenCalledWith(); expect(spawn).not.toHaveBeenCalled(); }); + + it('passes --refresh-ad-hoc-provisioning-profile to build:internal for iOS jobs with refreshAdHocProvisioningProfile', async () => { + const logger = { + info: jest.fn(), + warn: jest.fn(), + error: jest.fn(), + child: jest.fn(), + } as any; + + const internalJob = { + platform: Platform.IOS, + type: Workflow.GENERIC, + triggeredBy: 'EAS_CLI', + projectArchive: { type: ArchiveSourceType.URL, url: 'https://example.com' }, + projectRootDirectory: '.', + secrets: { + buildCredentials: { + testapp: { + distributionCertificate: { + dataBase64: 'YmluYXJ5Y29udGVudDE=', + password: 'distCertPassword', + }, + provisioningProfileBase64: 'MnRuZXRub2N5cmFuaWI=', + }, + }, + }, + initiatingUserId: 'user-id', + appId: 'app-id', + }; + + jest.mocked(spawn).mockResolvedValue({ + stdout: Buffer.from( + JSON.stringify({ + job: internalJob, + metadata: {}, + }) + ), + stderr: Buffer.from(''), + } as any); + + const job = { + platform: Platform.IOS, + buildProfile: 'preview', + refreshAdHocProvisioningProfile: true, + appId: 'app-id', + initiatingUserId: 'user-id', + secrets: { robotAccessToken: 'token' }, + } as unknown as BuildJob; + + await runEasBuildInternalAsync({ + job, + logger, + env: {}, + cwd: '/tmp/project', + }); + + expect(spawn).toHaveBeenCalledWith( + 'npx', + expect.arrayContaining([ + 'build:internal', + '--platform', + Platform.IOS, + '--profile', + 'preview', + '--refresh-ad-hoc-provisioning-profile', + ]), + expect.any(Object) + ); + }); + + it('preserves refreshAdHocProvisioningProfile from the incoming job', async () => { + const logger = { + info: jest.fn(), + warn: jest.fn(), + error: jest.fn(), + child: jest.fn(), + } as any; + + const internalJob = { + platform: Platform.IOS, + type: Workflow.GENERIC, + triggeredBy: 'EAS_CLI', + projectArchive: { type: ArchiveSourceType.URL, url: 'https://example.com' }, + projectRootDirectory: '.', + secrets: { + buildCredentials: { + testapp: { + distributionCertificate: { + dataBase64: 'YmluYXJ5Y29udGVudDE=', + password: 'distCertPassword', + }, + provisioningProfileBase64: 'MnRuZXRub2N5cmFuaWI=', + }, + }, + }, + initiatingUserId: 'user-id', + appId: 'app-id', + }; + + jest.mocked(spawn).mockResolvedValue({ + stdout: Buffer.from( + JSON.stringify({ + job: internalJob, + metadata: {}, + }) + ), + stderr: Buffer.from(''), + } as any); + + const job = { + platform: Platform.IOS, + buildProfile: 'preview', + refreshAdHocProvisioningProfile: true, + appId: 'app-id', + initiatingUserId: 'user-id', + secrets: { robotAccessToken: 'token' }, + } as unknown as BuildJob; + + const { newJob } = await runEasBuildInternalAsync({ + job, + logger, + env: {}, + cwd: '/tmp/project', + }); + + expect((newJob as any).refreshAdHocProvisioningProfile).toBe(true); + }); }); diff --git a/packages/build-tools/src/common/easBuildInternal.ts b/packages/build-tools/src/common/easBuildInternal.ts index 368f5b0fb1..b923389d75 100644 --- a/packages/build-tools/src/common/easBuildInternal.ts +++ b/packages/build-tools/src/common/easBuildInternal.ts @@ -1,4 +1,12 @@ -import { BuildJob, Env, Metadata, sanitizeBuildJob, sanitizeMetadata } from '@expo/eas-build-job'; +import { + BuildJob, + Env, + Ios, + Metadata, + Platform, + sanitizeBuildJob, + sanitizeMetadata, +} from '@expo/eas-build-job'; import { PipeMode, bunyan } from '@expo/logger'; import { BuildStepEnv } from '@expo/steps'; import spawn from '@expo/turtle-spawn'; @@ -42,6 +50,11 @@ export async function runEasBuildInternalAsync({ autoSubmitArgs.push('--auto-submit'); } + const refreshAdHocProvisioningProfileArgs = []; + if (job.platform === Platform.IOS && job.refreshAdHocProvisioningProfile === true) { + refreshAdHocProvisioningProfileArgs.push('--refresh-ad-hoc-provisioning-profile'); + } + try { const result = await spawn( cmd, @@ -53,6 +66,7 @@ export async function runEasBuildInternalAsync({ '--profile', buildProfile, ...autoSubmitArgs, + ...refreshAdHocProvisioningProfileArgs, ], { cwd, @@ -138,6 +152,9 @@ function validateEasBuildInternalResult({ // We want to retain values that we have set on the job. appId: oldJob.appId, initiatingUserId: oldJob.initiatingUserId, + ...(oldJob.platform === Platform.IOS && oldJob.refreshAdHocProvisioningProfile === true + ? { refreshAdHocProvisioningProfile: true } + : null), }) as TJob; assert(newJob.platform === oldJob.platform, 'eas-cli returned a job for a wrong platform'); const newMetadata = sanitizeMetadata(value.metadata);