@expo/build-tools 0.1.164 → 0.1.166

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/dist/buildErrors/userErrorHandlers.js +17 -0
  2. package/dist/buildErrors/userErrorHandlers.js.map +1 -1
  3. package/dist/builders/android.js +3 -3
  4. package/dist/builders/android.js.map +1 -1
  5. package/dist/builders/ios.js +41 -4
  6. package/dist/builders/ios.js.map +1 -1
  7. package/dist/common/easBuildInternal.d.ts +4 -0
  8. package/dist/common/easBuildInternal.js +106 -0
  9. package/dist/common/easBuildInternal.js.map +1 -0
  10. package/dist/common/installDependencies.d.ts +3 -0
  11. package/dist/common/installDependencies.js +38 -0
  12. package/dist/common/installDependencies.js.map +1 -0
  13. package/dist/{utils → common}/prebuild.d.ts +0 -0
  14. package/dist/{utils → common}/prebuild.js +3 -2
  15. package/dist/common/prebuild.js.map +1 -0
  16. package/dist/common/projectSources.d.ts +4 -0
  17. package/dist/common/projectSources.js +91 -0
  18. package/dist/common/projectSources.js.map +1 -0
  19. package/dist/common/setup.d.ts +3 -0
  20. package/dist/common/setup.js +97 -0
  21. package/dist/common/setup.js.map +1 -0
  22. package/dist/context.d.ts +8 -3
  23. package/dist/context.js +28 -4
  24. package/dist/context.js.map +1 -1
  25. package/dist/ios/credentials/distributionCertificate.d.ts +2 -2
  26. package/dist/ios/credentials/distributionCertificate.js +8 -1
  27. package/dist/ios/credentials/distributionCertificate.js.map +1 -1
  28. package/dist/ios/credentials/manager.d.ts +4 -3
  29. package/dist/ios/credentials/manager.js +13 -3
  30. package/dist/ios/credentials/manager.js.map +1 -1
  31. package/dist/ios/credentials/provisioningProfile.d.ts +6 -1
  32. package/dist/ios/credentials/provisioningProfile.js +6 -1
  33. package/dist/ios/credentials/provisioningProfile.js.map +1 -1
  34. package/dist/ios/fastfile.d.ts +8 -0
  35. package/dist/ios/fastfile.js +28 -0
  36. package/dist/ios/fastfile.js.map +1 -0
  37. package/dist/ios/fastlane.d.ts +4 -0
  38. package/dist/ios/fastlane.js +19 -1
  39. package/dist/ios/fastlane.js.map +1 -1
  40. package/dist/ios/gymfile.js.map +1 -1
  41. package/dist/ios/resign.d.ts +3 -0
  42. package/dist/ios/resign.js +33 -0
  43. package/dist/ios/resign.js.map +1 -0
  44. package/dist/utils/project.d.ts +0 -2
  45. package/dist/utils/project.js +2 -133
  46. package/dist/utils/project.js.map +1 -1
  47. package/package.json +7 -4
  48. package/templates/Fastfile.resign.template +8 -0
  49. package/dist/utils/prebuild.js.map +0 -1
@@ -0,0 +1,91 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.downloadAndUnpackProjectFromTarGzAsync = exports.prepareProjectSourcesAsync = void 0;
7
+ const path_1 = __importDefault(require("path"));
8
+ const turtle_spawn_1 = __importDefault(require("@expo/turtle-spawn"));
9
+ const fs_extra_1 = __importDefault(require("fs-extra"));
10
+ const eas_build_job_1 = require("@expo/eas-build-job");
11
+ const downloader_1 = __importDefault(require("@expo/downloader"));
12
+ async function prepareProjectSourcesAsync(ctx) {
13
+ if ([eas_build_job_1.ArchiveSourceType.S3, eas_build_job_1.ArchiveSourceType.GCS].includes(ctx.job.projectArchive.type)) {
14
+ throw new Error('GCS and S3 project sources should be resolved earlier to url');
15
+ }
16
+ else if (ctx.job.projectArchive.type === eas_build_job_1.ArchiveSourceType.PATH) {
17
+ await prepareProjectSourcesLocallyAsync(ctx, ctx.job.projectArchive.path); // used in eas build --local
18
+ }
19
+ else if (ctx.job.projectArchive.type === eas_build_job_1.ArchiveSourceType.URL) {
20
+ await downloadAndUnpackProjectFromTarGzAsync(ctx, ctx.job.projectArchive.url);
21
+ }
22
+ else if (ctx.job.projectArchive.type === eas_build_job_1.ArchiveSourceType.GIT) {
23
+ await shallowCloneRepositoryAsync(ctx, ctx.job.projectArchive.repositoryUrl, ctx.job.projectArchive.gitRef);
24
+ }
25
+ }
26
+ exports.prepareProjectSourcesAsync = prepareProjectSourcesAsync;
27
+ async function shallowCloneRepositoryAsync(ctx, projectRepoUrl, gitRef) {
28
+ try {
29
+ await (0, turtle_spawn_1.default)('git', ['init'], { cwd: ctx.buildDirectory });
30
+ await (0, turtle_spawn_1.default)('git', ['remote', 'add', 'origin', projectRepoUrl], { cwd: ctx.buildDirectory });
31
+ await (0, turtle_spawn_1.default)('git', ['fetch', 'origin', '--depth', '1', gitRef], { cwd: ctx.buildDirectory });
32
+ await (0, turtle_spawn_1.default)('git', ['checkout', gitRef], { cwd: ctx.buildDirectory });
33
+ }
34
+ catch (err) {
35
+ const sanitizedUrl = getSanitizedGitUrl(projectRepoUrl);
36
+ if (sanitizedUrl) {
37
+ ctx.logger.error(`Failed to clone git repository: ${sanitizedUrl}.`);
38
+ }
39
+ else {
40
+ ctx.logger.error('Failed to clone git repository.');
41
+ }
42
+ ctx.logger.error(err.stderr);
43
+ throw err;
44
+ }
45
+ }
46
+ function getSanitizedGitUrl(maybeGitUrl) {
47
+ try {
48
+ const url = new URL(maybeGitUrl);
49
+ if (url.password) {
50
+ url.password = '*******';
51
+ }
52
+ return url.toString();
53
+ }
54
+ catch (_a) {
55
+ return null;
56
+ }
57
+ }
58
+ async function downloadAndUnpackProjectFromTarGzAsync(ctx, projectArchiveUrl) {
59
+ var _a;
60
+ const projectTarball = path_1.default.join(ctx.workingdir, 'project.tar.gz');
61
+ try {
62
+ await (0, downloader_1.default)(projectArchiveUrl, projectTarball, { retry: 3 });
63
+ }
64
+ catch (err) {
65
+ (_a = ctx.reportError) === null || _a === void 0 ? void 0 : _a.call(ctx, 'Failed to download project archive', err, {
66
+ extras: { buildId: ctx.env.EAS_BUILD_ID },
67
+ });
68
+ throw err;
69
+ }
70
+ await unpackTarGzAsync({
71
+ destination: ctx.buildDirectory,
72
+ source: projectTarball,
73
+ logger: ctx.logger,
74
+ });
75
+ }
76
+ exports.downloadAndUnpackProjectFromTarGzAsync = downloadAndUnpackProjectFromTarGzAsync;
77
+ async function prepareProjectSourcesLocallyAsync(ctx, projectArchivePath) {
78
+ const projectTarball = path_1.default.join(ctx.workingdir, 'project.tar.gz');
79
+ await fs_extra_1.default.copy(projectArchivePath, projectTarball);
80
+ await unpackTarGzAsync({
81
+ destination: ctx.buildDirectory,
82
+ source: projectTarball,
83
+ logger: ctx.logger,
84
+ });
85
+ }
86
+ async function unpackTarGzAsync({ logger, source, destination, }) {
87
+ await (0, turtle_spawn_1.default)('tar', ['-C', destination, '--strip-components', '1', '-zxf', source], {
88
+ logger,
89
+ });
90
+ }
91
+ //# sourceMappingURL=projectSources.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"projectSources.js","sourceRoot":"","sources":["../../src/common/projectSources.ts"],"names":[],"mappings":"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","sourcesContent":["import path from 'path';\n\nimport spawn from '@expo/turtle-spawn';\nimport fs from 'fs-extra';\nimport { ArchiveSourceType, Job } from '@expo/eas-build-job';\nimport { bunyan } from '@expo/logger';\nimport downloadFile from '@expo/downloader';\n\nimport { BuildContext } from '../context';\n\nexport async function prepareProjectSourcesAsync<TJob extends Job>(\n ctx: BuildContext<TJob>\n): Promise<void> {\n if ([ArchiveSourceType.S3, ArchiveSourceType.GCS].includes(ctx.job.projectArchive.type)) {\n throw new Error('GCS and S3 project sources should be resolved earlier to url');\n } else if (ctx.job.projectArchive.type === ArchiveSourceType.PATH) {\n await prepareProjectSourcesLocallyAsync(ctx, ctx.job.projectArchive.path); // used in eas build --local\n } else if (ctx.job.projectArchive.type === ArchiveSourceType.URL) {\n await downloadAndUnpackProjectFromTarGzAsync(ctx, ctx.job.projectArchive.url);\n } else if (ctx.job.projectArchive.type === ArchiveSourceType.GIT) {\n await shallowCloneRepositoryAsync(\n ctx,\n ctx.job.projectArchive.repositoryUrl,\n ctx.job.projectArchive.gitRef\n );\n }\n}\n\nasync function shallowCloneRepositoryAsync<TJob extends Job>(\n ctx: BuildContext<TJob>,\n projectRepoUrl: string,\n gitRef: string\n): Promise<void> {\n try {\n await spawn('git', ['init'], { cwd: ctx.buildDirectory });\n await spawn('git', ['remote', 'add', 'origin', projectRepoUrl], { cwd: ctx.buildDirectory });\n await spawn('git', ['fetch', 'origin', '--depth', '1', gitRef], { cwd: ctx.buildDirectory });\n await spawn('git', ['checkout', gitRef], { cwd: ctx.buildDirectory });\n } catch (err: any) {\n const sanitizedUrl = getSanitizedGitUrl(projectRepoUrl);\n if (sanitizedUrl) {\n ctx.logger.error(`Failed to clone git repository: ${sanitizedUrl}.`);\n } else {\n ctx.logger.error('Failed to clone git repository.');\n }\n ctx.logger.error(err.stderr);\n throw err;\n }\n}\n\nfunction getSanitizedGitUrl(maybeGitUrl: string): string | null {\n try {\n const url = new URL(maybeGitUrl);\n if (url.password) {\n url.password = '*******';\n }\n return url.toString();\n } catch {\n return null;\n }\n}\n\nexport async function downloadAndUnpackProjectFromTarGzAsync<TJob extends Job>(\n ctx: BuildContext<TJob>,\n projectArchiveUrl: string\n): Promise<void> {\n const projectTarball = path.join(ctx.workingdir, 'project.tar.gz');\n try {\n await downloadFile(projectArchiveUrl, projectTarball, { retry: 3 });\n } catch (err: any) {\n ctx.reportError?.('Failed to download project archive', err, {\n extras: { buildId: ctx.env.EAS_BUILD_ID },\n });\n throw err;\n }\n\n await unpackTarGzAsync({\n destination: ctx.buildDirectory,\n source: projectTarball,\n logger: ctx.logger,\n });\n}\n\nasync function prepareProjectSourcesLocallyAsync<TJob extends Job>(\n ctx: BuildContext<TJob>,\n projectArchivePath: string\n): Promise<void> {\n const projectTarball = path.join(ctx.workingdir, 'project.tar.gz');\n await fs.copy(projectArchivePath, projectTarball);\n\n await unpackTarGzAsync({\n destination: ctx.buildDirectory,\n source: projectTarball,\n logger: ctx.logger,\n });\n}\n\nasync function unpackTarGzAsync({\n logger,\n source,\n destination,\n}: {\n logger: bunyan;\n source: string;\n destination: string;\n}): Promise<void> {\n await spawn('tar', ['-C', destination, '--strip-components', '1', '-zxf', source], {\n logger,\n });\n}\n"]}
@@ -0,0 +1,3 @@
1
+ import { Job } from '@expo/eas-build-job';
2
+ import { BuildContext } from '../context';
3
+ export declare function setupAsync<TJob extends Job>(ctx: BuildContext<TJob>): Promise<void>;
@@ -0,0 +1,97 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.setupAsync = void 0;
4
+ const eas_build_job_1 = require("@expo/eas-build-job");
5
+ const common_1 = require("@expo/eas-build-job/dist/common");
6
+ const xcodeEnv_1 = require("../ios/xcodeEnv");
7
+ const hooks_1 = require("../utils/hooks");
8
+ const npmrc_1 = require("../utils/npmrc");
9
+ const project_1 = require("../utils/project");
10
+ const projectSources_1 = require("./projectSources");
11
+ const installDependencies_1 = require("./installDependencies");
12
+ const easBuildInternal_1 = require("./easBuildInternal");
13
+ const MAX_EXPO_DOCTOR_TIMEOUT_MS = 20 * 1000;
14
+ async function setupAsync(ctx) {
15
+ var _a;
16
+ const packageJson = await ctx.runBuildPhase(eas_build_job_1.BuildPhase.PREPARE_PROJECT, async () => {
17
+ await (0, projectSources_1.prepareProjectSourcesAsync)(ctx);
18
+ if (ctx.env.NPM_TOKEN) {
19
+ await (0, npmrc_1.createNpmrcIfNotExistsAsync)(ctx);
20
+ }
21
+ else {
22
+ await (0, npmrc_1.logIfNpmrcExistsAsync)(ctx);
23
+ }
24
+ if (ctx.job.platform === eas_build_job_1.Platform.IOS && ctx.env.EAS_BUILD_RUNNER === 'eas-build') {
25
+ await (0, xcodeEnv_1.deleteXcodeEnvLocalIfExistsAsync)(ctx);
26
+ }
27
+ if (ctx.job.triggeredBy === common_1.BuildTrigger.GIT_BASED_INTEGRATION) {
28
+ // We need to setup envs from eas.json before
29
+ // eas-build-pre-install hook is called.
30
+ await (0, easBuildInternal_1.configureEnvFromBuildProfileAsync)(ctx);
31
+ }
32
+ // try to read package.json to see if it exists and is valid
33
+ return (0, project_1.readPackageJson)(ctx.reactNativeProjectDirectory);
34
+ });
35
+ await ctx.runBuildPhase(eas_build_job_1.BuildPhase.PRE_INSTALL_HOOK, async () => {
36
+ await (0, hooks_1.runHookIfPresent)(ctx, hooks_1.Hook.PRE_INSTALL);
37
+ });
38
+ await ctx.runBuildPhase(eas_build_job_1.BuildPhase.READ_PACKAGE_JSON, async () => {
39
+ ctx.logger.info('Using package.json:');
40
+ ctx.logger.info(JSON.stringify(packageJson, null, 2));
41
+ });
42
+ await ctx.runBuildPhase(eas_build_job_1.BuildPhase.INSTALL_DEPENDENCIES, async () => {
43
+ await (0, installDependencies_1.installDependenciesAsync)(ctx);
44
+ });
45
+ if (ctx.job.triggeredBy === common_1.BuildTrigger.GIT_BASED_INTEGRATION) {
46
+ await ctx.runBuildPhase(eas_build_job_1.BuildPhase.EAS_BUILD_INTERNAL, async () => {
47
+ await (0, easBuildInternal_1.runEasBuildInternalAsync)(ctx);
48
+ });
49
+ }
50
+ await ctx.runBuildPhase(eas_build_job_1.BuildPhase.READ_APP_CONFIG, async () => {
51
+ ctx.logger.info('Using app configuration:');
52
+ ctx.logger.info(JSON.stringify(ctx.appConfig, null, 2));
53
+ });
54
+ const hasExpoPackage = !!((_a = packageJson.dependencies) === null || _a === void 0 ? void 0 : _a.expo);
55
+ if (hasExpoPackage) {
56
+ await ctx.runBuildPhase(eas_build_job_1.BuildPhase.RUN_EXPO_DOCTOR, async () => {
57
+ try {
58
+ const { stdout } = await runExpoDoctor(ctx);
59
+ if (!stdout.match(/Didn't find any issues with the project/)) {
60
+ ctx.markBuildPhaseHasWarnings();
61
+ }
62
+ }
63
+ catch (err) {
64
+ ctx.logger.error({ err }, 'Command "expo doctor" failed.');
65
+ ctx.markBuildPhaseHasWarnings();
66
+ }
67
+ });
68
+ }
69
+ }
70
+ exports.setupAsync = setupAsync;
71
+ async function runExpoDoctor(ctx) {
72
+ ctx.logger.info('Running "expo doctor"');
73
+ let timeout;
74
+ try {
75
+ const promise = (0, project_1.runExpoCliCommand)(ctx, ['doctor'], {
76
+ cwd: ctx.reactNativeProjectDirectory,
77
+ logger: ctx.logger,
78
+ env: ctx.env,
79
+ },
80
+ // local Expo CLI does not have "doctor" for now
81
+ { forceUseGlobalExpoCli: true });
82
+ timeout = setTimeout(() => {
83
+ var _a;
84
+ promise.child.kill();
85
+ (_a = ctx.reportError) === null || _a === void 0 ? void 0 : _a.call(ctx, `"expo doctor" timed out`, undefined, {
86
+ extras: { buildId: ctx.env.EAS_BUILD_ID },
87
+ });
88
+ }, MAX_EXPO_DOCTOR_TIMEOUT_MS);
89
+ return await promise;
90
+ }
91
+ finally {
92
+ if (timeout) {
93
+ clearTimeout(timeout);
94
+ }
95
+ }
96
+ }
97
+ //# sourceMappingURL=setup.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"setup.js","sourceRoot":"","sources":["../../src/common/setup.ts"],"names":[],"mappings":"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","sourcesContent":["import { SpawnResult } from '@expo/turtle-spawn';\nimport { BuildPhase, Ios, Job, Platform } from '@expo/eas-build-job';\nimport { BuildTrigger } from '@expo/eas-build-job/dist/common';\n\nimport { BuildContext } from '../context';\nimport { deleteXcodeEnvLocalIfExistsAsync } from '../ios/xcodeEnv';\nimport { Hook, runHookIfPresent } from '../utils/hooks';\nimport { createNpmrcIfNotExistsAsync, logIfNpmrcExistsAsync } from '../utils/npmrc';\nimport { readPackageJson, runExpoCliCommand } from '../utils/project';\n\nimport { prepareProjectSourcesAsync } from './projectSources';\nimport { installDependenciesAsync } from './installDependencies';\nimport { configureEnvFromBuildProfileAsync, runEasBuildInternalAsync } from './easBuildInternal';\n\nconst MAX_EXPO_DOCTOR_TIMEOUT_MS = 20 * 1000;\n\nexport async function setupAsync<TJob extends Job>(ctx: BuildContext<TJob>): Promise<void> {\n const packageJson = await ctx.runBuildPhase(BuildPhase.PREPARE_PROJECT, async () => {\n await prepareProjectSourcesAsync(ctx);\n if (ctx.env.NPM_TOKEN) {\n await createNpmrcIfNotExistsAsync(ctx);\n } else {\n await logIfNpmrcExistsAsync(ctx);\n }\n if (ctx.job.platform === Platform.IOS && ctx.env.EAS_BUILD_RUNNER === 'eas-build') {\n await deleteXcodeEnvLocalIfExistsAsync(ctx as BuildContext<Ios.Job>);\n }\n if (ctx.job.triggeredBy === BuildTrigger.GIT_BASED_INTEGRATION) {\n // We need to setup envs from eas.json before\n // eas-build-pre-install hook is called.\n await configureEnvFromBuildProfileAsync(ctx);\n }\n // try to read package.json to see if it exists and is valid\n return readPackageJson(ctx.reactNativeProjectDirectory);\n });\n\n await ctx.runBuildPhase(BuildPhase.PRE_INSTALL_HOOK, async () => {\n await runHookIfPresent(ctx, Hook.PRE_INSTALL);\n });\n\n await ctx.runBuildPhase(BuildPhase.READ_PACKAGE_JSON, async () => {\n ctx.logger.info('Using package.json:');\n ctx.logger.info(JSON.stringify(packageJson, null, 2));\n });\n\n await ctx.runBuildPhase(BuildPhase.INSTALL_DEPENDENCIES, async () => {\n await installDependenciesAsync(ctx);\n });\n\n if (ctx.job.triggeredBy === BuildTrigger.GIT_BASED_INTEGRATION) {\n await ctx.runBuildPhase(BuildPhase.EAS_BUILD_INTERNAL, async () => {\n await runEasBuildInternalAsync(ctx);\n });\n }\n\n await ctx.runBuildPhase(BuildPhase.READ_APP_CONFIG, async () => {\n ctx.logger.info('Using app configuration:');\n ctx.logger.info(JSON.stringify(ctx.appConfig, null, 2));\n });\n\n const hasExpoPackage = !!packageJson.dependencies?.expo;\n if (hasExpoPackage) {\n await ctx.runBuildPhase(BuildPhase.RUN_EXPO_DOCTOR, async () => {\n try {\n const { stdout } = await runExpoDoctor(ctx);\n if (!stdout.match(/Didn't find any issues with the project/)) {\n ctx.markBuildPhaseHasWarnings();\n }\n } catch (err) {\n ctx.logger.error({ err }, 'Command \"expo doctor\" failed.');\n ctx.markBuildPhaseHasWarnings();\n }\n });\n }\n}\n\nasync function runExpoDoctor<TJob extends Job>(ctx: BuildContext<TJob>): Promise<SpawnResult> {\n ctx.logger.info('Running \"expo doctor\"');\n let timeout: NodeJS.Timeout | undefined;\n try {\n const promise = runExpoCliCommand(\n ctx,\n ['doctor'],\n {\n cwd: ctx.reactNativeProjectDirectory,\n logger: ctx.logger,\n env: ctx.env,\n },\n // local Expo CLI does not have \"doctor\" for now\n { forceUseGlobalExpoCli: true }\n );\n timeout = setTimeout(() => {\n promise.child.kill();\n ctx.reportError?.(`\"expo doctor\" timed out`, undefined, {\n extras: { buildId: ctx.env.EAS_BUILD_ID },\n });\n }, MAX_EXPO_DOCTOR_TIMEOUT_MS);\n return await promise;\n } finally {\n if (timeout) {\n clearTimeout(timeout);\n }\n }\n}\n"]}
package/dist/context.d.ts CHANGED
@@ -42,11 +42,9 @@ export interface BuildContextOptions {
42
42
  export declare class SkipNativeBuildError extends Error {
43
43
  }
44
44
  export declare class BuildContext<TJob extends Job> {
45
- readonly job: TJob;
46
45
  readonly workingdir: string;
47
46
  logger: bunyan;
48
47
  readonly logBuffer: LogBuffer;
49
- readonly env: Env;
50
48
  readonly cacheManager?: CacheManager;
51
49
  /**
52
50
  * @deprecated
@@ -56,9 +54,11 @@ export declare class BuildContext<TJob extends Job> {
56
54
  tags?: Record<string, string>;
57
55
  extras?: Record<string, string>;
58
56
  }) => void;
59
- readonly metadata?: Metadata;
60
57
  readonly skipNativeBuild?: boolean;
61
58
  artifacts: Artifacts;
59
+ private _env;
60
+ private _job;
61
+ private _metadata?;
62
62
  private readonly defaultLogger;
63
63
  private readonly _uploadArtifacts;
64
64
  private buildPhase?;
@@ -67,6 +67,9 @@ export declare class BuildContext<TJob extends Job> {
67
67
  private _appConfig?;
68
68
  private readonly reportBuildPhaseStats?;
69
69
  constructor(job: TJob, options: BuildContextOptions);
70
+ get job(): TJob;
71
+ get metadata(): Metadata | undefined;
72
+ get env(): Env;
70
73
  get buildDirectory(): string;
71
74
  get buildLogsDirectory(): string;
72
75
  get environmentSecrectsDirectory(): string;
@@ -80,6 +83,8 @@ export declare class BuildContext<TJob extends Job> {
80
83
  markBuildPhaseSkipped(): void;
81
84
  markBuildPhaseHasWarnings(): void;
82
85
  uploadArtifacts(type: ArtifactType, paths: string[], logger?: bunyan): Promise<void>;
86
+ updateEnv(env: Env): void;
87
+ updateJobInformation(job: TJob, metadata: Metadata): void;
83
88
  private handleBuildPhaseErrorAsync;
84
89
  private setBuildPhase;
85
90
  private endCurrentBuildPhase;
package/dist/context.js CHANGED
@@ -6,6 +6,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.BuildContext = exports.SkipNativeBuildError = exports.ArtifactType = void 0;
7
7
  const path_1 = __importDefault(require("path"));
8
8
  const eas_build_job_1 = require("@expo/eas-build-job");
9
+ const common_1 = require("@expo/eas-build-job/dist/common");
9
10
  const packageManager_1 = require("./utils/packageManager");
10
11
  const detectError_1 = require("./buildErrors/detectError");
11
12
  const appConfig_1 = require("./utils/appConfig");
@@ -25,7 +26,6 @@ exports.SkipNativeBuildError = SkipNativeBuildError;
25
26
  class BuildContext {
26
27
  constructor(job, options) {
27
28
  var _a;
28
- this.job = job;
29
29
  this.artifacts = {};
30
30
  this.buildPhaseSkipped = false;
31
31
  this.buildPhaseHasWarnings = false;
@@ -37,11 +37,21 @@ class BuildContext {
37
37
  this.runGlobalExpoCliCommand = options.runGlobalExpoCliCommand;
38
38
  this._uploadArtifacts = options.uploadArtifacts;
39
39
  this.reportError = options.reportError;
40
- this.metadata = options.metadata;
40
+ this._job = job;
41
+ this._metadata = options.metadata;
41
42
  this.skipNativeBuild = options.skipNativeBuild;
42
43
  this.reportBuildPhaseStats = options.reportBuildPhaseStats;
43
44
  const environmentSecrets = this.getEnvironmentSecrets(job);
44
- this.env = Object.assign(Object.assign(Object.assign({}, options.env), (_a = job === null || job === void 0 ? void 0 : job.builderEnvironment) === null || _a === void 0 ? void 0 : _a.env), environmentSecrets);
45
+ this._env = Object.assign(Object.assign(Object.assign({}, options.env), (_a = job === null || job === void 0 ? void 0 : job.builderEnvironment) === null || _a === void 0 ? void 0 : _a.env), environmentSecrets);
46
+ }
47
+ get job() {
48
+ return this._job;
49
+ }
50
+ get metadata() {
51
+ return this._metadata;
52
+ }
53
+ get env() {
54
+ return this._env;
45
55
  }
46
56
  get buildDirectory() {
47
57
  return path_1.default.join(this.workingdir, 'build');
@@ -53,7 +63,8 @@ class BuildContext {
53
63
  return path_1.default.join(this.workingdir, 'environment-secrets');
54
64
  }
55
65
  get reactNativeProjectDirectory() {
56
- return path_1.default.join(this.buildDirectory, this.job.projectRootDirectory);
66
+ var _a;
67
+ return path_1.default.join(this.buildDirectory, (_a = this.job.projectRootDirectory) !== null && _a !== void 0 ? _a : '.');
57
68
  }
58
69
  get packageManager() {
59
70
  return (0, packageManager_1.resolvePackageManager)(this.reactNativeProjectDirectory);
@@ -98,6 +109,19 @@ class BuildContext {
98
109
  this.artifacts[type] = url;
99
110
  }
100
111
  }
112
+ updateEnv(env) {
113
+ if (this._job.triggeredBy === common_1.BuildTrigger.GIT_BASED_INTEGRATION) {
114
+ throw new Error('Updating environment variables is only allowed when build was triggered by a git-based integration.');
115
+ }
116
+ this._env = Object.assign(Object.assign({}, env), this._env);
117
+ }
118
+ updateJobInformation(job, metadata) {
119
+ if (this._job.triggeredBy === common_1.BuildTrigger.GIT_BASED_INTEGRATION) {
120
+ throw new Error('Updating job information is only allowed when build was triggered by a git-based integration.');
121
+ }
122
+ this._job = Object.assign(Object.assign({}, job), { triggeredBy: this._job.triggeredBy });
123
+ this._metadata = metadata;
124
+ }
101
125
  async handleBuildPhaseErrorAsync(err, buildPhase) {
102
126
  const buildError = await (0, detectError_1.resolveBuildPhaseErrorAsync)(err, this.logBuffer.getPhaseLogs(buildPhase), {
103
127
  job: this.job,
@@ -1 +1 @@
1
- {"version":3,"file":"context.js","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"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","sourcesContent":["import path from 'path';\n\nimport {\n BuildPhase,\n BuildPhaseResult,\n BuildPhaseStats,\n Job,\n LogMarker,\n Env,\n errors,\n Metadata,\n EnvironmentSecretType,\n} from '@expo/eas-build-job';\nimport { ExpoConfig } from '@expo/config';\nimport { bunyan } from '@expo/logger';\nimport { SpawnPromise, SpawnOptions, SpawnResult } from '@expo/turtle-spawn';\n\nimport { PackageManager, resolvePackageManager } from './utils/packageManager';\nimport { resolveBuildPhaseErrorAsync } from './buildErrors/detectError';\nimport { readAppConfig } from './utils/appConfig';\nimport { createTemporaryEnvironmentSecretFile } from './utils/environmentSecrets';\n\nexport enum ArtifactType {\n APPLICATION_ARCHIVE = 'APPLICATION_ARCHIVE',\n BUILD_ARTIFACTS = 'BUILD_ARTIFACTS',\n /**\n * @deprecated\n */\n XCODE_BUILD_LOGS = 'XCODE_BUILD_LOGS',\n}\n\nexport type Artifacts = Partial<Record<ArtifactType, string>>;\n\nexport interface CacheManager {\n saveCache(ctx: BuildContext<Job>): Promise<void>;\n restoreCache(ctx: BuildContext<Job>): Promise<void>;\n}\n\nexport interface LogBuffer {\n getLogs(): string[];\n getPhaseLogs(buildPhase: string): string[];\n}\n\nexport interface BuildContextOptions {\n workingdir: string;\n logger: bunyan;\n logBuffer: LogBuffer;\n env: Env;\n cacheManager?: CacheManager;\n /**\n * @deprecated\n */\n runGlobalExpoCliCommand: (args: string, options: SpawnOptions) => SpawnPromise<SpawnResult>;\n uploadArtifacts: (type: ArtifactType, paths: string[], logger?: bunyan) => Promise<string | null>;\n reportError?: (\n msg: string,\n err?: Error,\n options?: { tags?: Record<string, string>; extras?: Record<string, string> }\n ) => void;\n reportBuildPhaseStats?: (stats: BuildPhaseStats) => void;\n skipNativeBuild?: boolean;\n metadata?: Metadata;\n}\n\nexport class SkipNativeBuildError extends Error {}\n\nexport class BuildContext<TJob extends Job> {\n public readonly workingdir: string;\n public logger: bunyan;\n public readonly logBuffer: LogBuffer;\n public readonly env: Env;\n public readonly cacheManager?: CacheManager;\n /**\n * @deprecated\n */\n public readonly runGlobalExpoCliCommand: (\n args: string,\n options: SpawnOptions\n ) => SpawnPromise<SpawnResult>;\n public readonly reportError?: (\n msg: string,\n err?: Error,\n options?: { tags?: Record<string, string>; extras?: Record<string, string> }\n ) => void;\n public readonly metadata?: Metadata;\n public readonly skipNativeBuild?: boolean;\n public artifacts: Artifacts = {};\n\n private readonly defaultLogger: bunyan;\n private readonly _uploadArtifacts: (\n type: ArtifactType,\n paths: string[],\n logger?: bunyan\n ) => Promise<string | null>;\n private buildPhase?: BuildPhase;\n private buildPhaseSkipped = false;\n private buildPhaseHasWarnings = false;\n private _appConfig?: ExpoConfig;\n private readonly reportBuildPhaseStats?: (stats: BuildPhaseStats) => void;\n\n constructor(public readonly job: TJob, options: BuildContextOptions) {\n this.workingdir = options.workingdir;\n this.defaultLogger = options.logger;\n this.logger = this.defaultLogger;\n this.logBuffer = options.logBuffer;\n this.cacheManager = options.cacheManager;\n this.runGlobalExpoCliCommand = options.runGlobalExpoCliCommand;\n this._uploadArtifacts = options.uploadArtifacts;\n this.reportError = options.reportError;\n this.metadata = options.metadata;\n this.skipNativeBuild = options.skipNativeBuild;\n this.reportBuildPhaseStats = options.reportBuildPhaseStats;\n\n const environmentSecrets = this.getEnvironmentSecrets(job);\n this.env = {\n ...options.env,\n ...job?.builderEnvironment?.env,\n ...environmentSecrets,\n };\n }\n\n public get buildDirectory(): string {\n return path.join(this.workingdir, 'build');\n }\n public get buildLogsDirectory(): string {\n return path.join(this.workingdir, 'logs');\n }\n public get environmentSecrectsDirectory(): string {\n return path.join(this.workingdir, 'environment-secrets');\n }\n public get reactNativeProjectDirectory(): string {\n return path.join(this.buildDirectory, this.job.projectRootDirectory);\n }\n public get packageManager(): PackageManager {\n return resolvePackageManager(this.reactNativeProjectDirectory);\n }\n public get appConfig(): ExpoConfig {\n if (!this._appConfig) {\n this._appConfig = readAppConfig(this.reactNativeProjectDirectory, this.env, this.logger).exp;\n }\n return this._appConfig;\n }\n\n public async runBuildPhase<T>(\n buildPhase: BuildPhase,\n phase: () => Promise<T>,\n {\n doNotMarkStart = false,\n doNotMarkEnd = false,\n }: {\n doNotMarkStart?: boolean;\n doNotMarkEnd?: boolean;\n } = {}\n ): Promise<T> {\n let startTimestamp = Date.now();\n try {\n this.setBuildPhase(buildPhase, { doNotMarkStart });\n startTimestamp = Date.now();\n const result = await phase();\n const durationMs = Date.now() - startTimestamp;\n const buildPhaseResult: BuildPhaseResult = this.buildPhaseSkipped\n ? BuildPhaseResult.SKIPPED\n : this.buildPhaseHasWarnings\n ? BuildPhaseResult.WARNING\n : BuildPhaseResult.SUCCESS;\n this.endCurrentBuildPhase({ result: buildPhaseResult, doNotMarkEnd, durationMs });\n return result;\n } catch (err: any) {\n const durationMs = Date.now() - startTimestamp;\n const resolvedError = await this.handleBuildPhaseErrorAsync(err, buildPhase);\n this.endCurrentBuildPhase({ result: BuildPhaseResult.FAIL, durationMs });\n throw resolvedError;\n }\n }\n\n public markBuildPhaseSkipped(): void {\n this.buildPhaseSkipped = true;\n }\n\n public markBuildPhaseHasWarnings(): void {\n this.buildPhaseHasWarnings = true;\n }\n\n public async uploadArtifacts(\n type: ArtifactType,\n paths: string[],\n logger?: bunyan\n ): Promise<void> {\n const url = await this._uploadArtifacts(type, paths, logger);\n if (url) {\n this.artifacts[type] = url;\n }\n }\n\n private async handleBuildPhaseErrorAsync(\n err: any,\n buildPhase: BuildPhase\n ): Promise<errors.BuildError> {\n const buildError = await resolveBuildPhaseErrorAsync(\n err,\n this.logBuffer.getPhaseLogs(buildPhase),\n {\n job: this.job,\n phase: buildPhase,\n env: this.env,\n },\n this.buildLogsDirectory\n );\n if (buildError.errorCode === errors.ErrorCode.UNKNOWN_ERROR) {\n // leaving message empty, website will display err.stack which already includes err.message\n this.logger.error({ err }, '');\n } else {\n this.logger.error(`Error: ${buildError.userFacingMessage}`);\n }\n return buildError;\n }\n\n private setBuildPhase(buildPhase: BuildPhase, { doNotMarkStart = false } = {}): void {\n if (this.buildPhase) {\n if (this.buildPhase === buildPhase) {\n return;\n } else {\n this.logger.info(\n { marker: LogMarker.END_PHASE, result: BuildPhaseResult.UNKNOWN },\n `End phase: ${this.buildPhase}`\n );\n this.logger = this.defaultLogger;\n }\n }\n this.buildPhase = buildPhase;\n this.logger = this.defaultLogger.child({ phase: buildPhase });\n if (!doNotMarkStart) {\n this.logger.info({ marker: LogMarker.START_PHASE }, `Start phase: ${this.buildPhase}`);\n }\n }\n\n private endCurrentBuildPhase({\n result,\n doNotMarkEnd = false,\n durationMs,\n }: {\n result: BuildPhaseResult;\n doNotMarkEnd?: boolean;\n durationMs: number;\n }): void {\n if (!this.buildPhase) {\n return;\n }\n\n this.reportBuildPhaseStats?.({ buildPhase: this.buildPhase, result, durationMs });\n\n if (!doNotMarkEnd) {\n this.logger.info(\n { marker: LogMarker.END_PHASE, result, durationMs },\n `End phase: ${this.buildPhase}`\n );\n }\n this.logger = this.defaultLogger;\n this.buildPhase = undefined;\n this.buildPhaseSkipped = false;\n this.buildPhaseHasWarnings = false;\n }\n\n private getEnvironmentSecrets(job: TJob): Record<string, string> {\n if (!job?.secrets?.environmentSecrets) {\n return {};\n }\n\n const environmentSecrets: Record<string, string> = {};\n for (const { name, type, value } of job.secrets.environmentSecrets) {\n if (type === EnvironmentSecretType.STRING) {\n environmentSecrets[name] = value;\n } else {\n environmentSecrets[name] = createTemporaryEnvironmentSecretFile(\n this.environmentSecrectsDirectory,\n value\n );\n }\n }\n return environmentSecrets;\n }\n}\n"]}
1
+ {"version":3,"file":"context.js","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"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","sourcesContent":["import path from 'path';\n\nimport {\n BuildPhase,\n BuildPhaseResult,\n BuildPhaseStats,\n Job,\n LogMarker,\n Env,\n errors,\n Metadata,\n EnvironmentSecretType,\n} from '@expo/eas-build-job';\nimport { ExpoConfig } from '@expo/config';\nimport { bunyan } from '@expo/logger';\nimport { SpawnPromise, SpawnOptions, SpawnResult } from '@expo/turtle-spawn';\nimport { BuildTrigger } from '@expo/eas-build-job/dist/common';\n\nimport { PackageManager, resolvePackageManager } from './utils/packageManager';\nimport { resolveBuildPhaseErrorAsync } from './buildErrors/detectError';\nimport { readAppConfig } from './utils/appConfig';\nimport { createTemporaryEnvironmentSecretFile } from './utils/environmentSecrets';\n\nexport enum ArtifactType {\n APPLICATION_ARCHIVE = 'APPLICATION_ARCHIVE',\n BUILD_ARTIFACTS = 'BUILD_ARTIFACTS',\n /**\n * @deprecated\n */\n XCODE_BUILD_LOGS = 'XCODE_BUILD_LOGS',\n}\n\nexport type Artifacts = Partial<Record<ArtifactType, string>>;\n\nexport interface CacheManager {\n saveCache(ctx: BuildContext<Job>): Promise<void>;\n restoreCache(ctx: BuildContext<Job>): Promise<void>;\n}\n\nexport interface LogBuffer {\n getLogs(): string[];\n getPhaseLogs(buildPhase: string): string[];\n}\n\nexport interface BuildContextOptions {\n workingdir: string;\n logger: bunyan;\n logBuffer: LogBuffer;\n env: Env;\n cacheManager?: CacheManager;\n /**\n * @deprecated\n */\n runGlobalExpoCliCommand: (args: string, options: SpawnOptions) => SpawnPromise<SpawnResult>;\n uploadArtifacts: (type: ArtifactType, paths: string[], logger?: bunyan) => Promise<string | null>;\n reportError?: (\n msg: string,\n err?: Error,\n options?: { tags?: Record<string, string>; extras?: Record<string, string> }\n ) => void;\n reportBuildPhaseStats?: (stats: BuildPhaseStats) => void;\n skipNativeBuild?: boolean;\n metadata?: Metadata;\n}\n\nexport class SkipNativeBuildError extends Error {}\n\nexport class BuildContext<TJob extends Job> {\n public readonly workingdir: string;\n public logger: bunyan;\n public readonly logBuffer: LogBuffer;\n public readonly cacheManager?: CacheManager;\n /**\n * @deprecated\n */\n public readonly runGlobalExpoCliCommand: (\n args: string,\n options: SpawnOptions\n ) => SpawnPromise<SpawnResult>;\n public readonly reportError?: (\n msg: string,\n err?: Error,\n options?: { tags?: Record<string, string>; extras?: Record<string, string> }\n ) => void;\n public readonly skipNativeBuild?: boolean;\n public artifacts: Artifacts = {};\n\n private _env: Env;\n private _job: TJob;\n private _metadata?: Metadata;\n private readonly defaultLogger: bunyan;\n private readonly _uploadArtifacts: (\n type: ArtifactType,\n paths: string[],\n logger?: bunyan\n ) => Promise<string | null>;\n private buildPhase?: BuildPhase;\n private buildPhaseSkipped = false;\n private buildPhaseHasWarnings = false;\n private _appConfig?: ExpoConfig;\n private readonly reportBuildPhaseStats?: (stats: BuildPhaseStats) => void;\n\n constructor(job: TJob, options: BuildContextOptions) {\n this.workingdir = options.workingdir;\n this.defaultLogger = options.logger;\n this.logger = this.defaultLogger;\n this.logBuffer = options.logBuffer;\n this.cacheManager = options.cacheManager;\n this.runGlobalExpoCliCommand = options.runGlobalExpoCliCommand;\n this._uploadArtifacts = options.uploadArtifacts;\n this.reportError = options.reportError;\n this._job = job;\n this._metadata = options.metadata;\n this.skipNativeBuild = options.skipNativeBuild;\n this.reportBuildPhaseStats = options.reportBuildPhaseStats;\n\n const environmentSecrets = this.getEnvironmentSecrets(job);\n this._env = {\n ...options.env,\n ...job?.builderEnvironment?.env,\n ...environmentSecrets,\n };\n }\n\n public get job(): TJob {\n return this._job;\n }\n public get metadata(): Metadata | undefined {\n return this._metadata;\n }\n public get env(): Env {\n return this._env;\n }\n public get buildDirectory(): string {\n return path.join(this.workingdir, 'build');\n }\n public get buildLogsDirectory(): string {\n return path.join(this.workingdir, 'logs');\n }\n public get environmentSecrectsDirectory(): string {\n return path.join(this.workingdir, 'environment-secrets');\n }\n public get reactNativeProjectDirectory(): string {\n return path.join(this.buildDirectory, this.job.projectRootDirectory ?? '.');\n }\n public get packageManager(): PackageManager {\n return resolvePackageManager(this.reactNativeProjectDirectory);\n }\n public get appConfig(): ExpoConfig {\n if (!this._appConfig) {\n this._appConfig = readAppConfig(this.reactNativeProjectDirectory, this.env, this.logger).exp;\n }\n return this._appConfig;\n }\n\n public async runBuildPhase<T>(\n buildPhase: BuildPhase,\n phase: () => Promise<T>,\n {\n doNotMarkStart = false,\n doNotMarkEnd = false,\n }: {\n doNotMarkStart?: boolean;\n doNotMarkEnd?: boolean;\n } = {}\n ): Promise<T> {\n let startTimestamp = Date.now();\n try {\n this.setBuildPhase(buildPhase, { doNotMarkStart });\n startTimestamp = Date.now();\n const result = await phase();\n const durationMs = Date.now() - startTimestamp;\n const buildPhaseResult: BuildPhaseResult = this.buildPhaseSkipped\n ? BuildPhaseResult.SKIPPED\n : this.buildPhaseHasWarnings\n ? BuildPhaseResult.WARNING\n : BuildPhaseResult.SUCCESS;\n this.endCurrentBuildPhase({ result: buildPhaseResult, doNotMarkEnd, durationMs });\n return result;\n } catch (err: any) {\n const durationMs = Date.now() - startTimestamp;\n const resolvedError = await this.handleBuildPhaseErrorAsync(err, buildPhase);\n this.endCurrentBuildPhase({ result: BuildPhaseResult.FAIL, durationMs });\n throw resolvedError;\n }\n }\n\n public markBuildPhaseSkipped(): void {\n this.buildPhaseSkipped = true;\n }\n\n public markBuildPhaseHasWarnings(): void {\n this.buildPhaseHasWarnings = true;\n }\n\n public async uploadArtifacts(\n type: ArtifactType,\n paths: string[],\n logger?: bunyan\n ): Promise<void> {\n const url = await this._uploadArtifacts(type, paths, logger);\n if (url) {\n this.artifacts[type] = url;\n }\n }\n\n public updateEnv(env: Env): void {\n if (this._job.triggeredBy === BuildTrigger.GIT_BASED_INTEGRATION) {\n throw new Error(\n 'Updating environment variables is only allowed when build was triggered by a git-based integration.'\n );\n }\n this._env = {\n ...env,\n ...this._env,\n };\n }\n\n public updateJobInformation(job: TJob, metadata: Metadata): void {\n if (this._job.triggeredBy === BuildTrigger.GIT_BASED_INTEGRATION) {\n throw new Error(\n 'Updating job information is only allowed when build was triggered by a git-based integration.'\n );\n }\n this._job = { ...job, triggeredBy: this._job.triggeredBy };\n this._metadata = metadata;\n }\n\n private async handleBuildPhaseErrorAsync(\n err: any,\n buildPhase: BuildPhase\n ): Promise<errors.BuildError> {\n const buildError = await resolveBuildPhaseErrorAsync(\n err,\n this.logBuffer.getPhaseLogs(buildPhase),\n {\n job: this.job,\n phase: buildPhase,\n env: this.env,\n },\n this.buildLogsDirectory\n );\n if (buildError.errorCode === errors.ErrorCode.UNKNOWN_ERROR) {\n // leaving message empty, website will display err.stack which already includes err.message\n this.logger.error({ err }, '');\n } else {\n this.logger.error(`Error: ${buildError.userFacingMessage}`);\n }\n return buildError;\n }\n\n private setBuildPhase(buildPhase: BuildPhase, { doNotMarkStart = false } = {}): void {\n if (this.buildPhase) {\n if (this.buildPhase === buildPhase) {\n return;\n } else {\n this.logger.info(\n { marker: LogMarker.END_PHASE, result: BuildPhaseResult.UNKNOWN },\n `End phase: ${this.buildPhase}`\n );\n this.logger = this.defaultLogger;\n }\n }\n this.buildPhase = buildPhase;\n this.logger = this.defaultLogger.child({ phase: buildPhase });\n if (!doNotMarkStart) {\n this.logger.info({ marker: LogMarker.START_PHASE }, `Start phase: ${this.buildPhase}`);\n }\n }\n\n private endCurrentBuildPhase({\n result,\n doNotMarkEnd = false,\n durationMs,\n }: {\n result: BuildPhaseResult;\n doNotMarkEnd?: boolean;\n durationMs: number;\n }): void {\n if (!this.buildPhase) {\n return;\n }\n\n this.reportBuildPhaseStats?.({ buildPhase: this.buildPhase, result, durationMs });\n\n if (!doNotMarkEnd) {\n this.logger.info(\n { marker: LogMarker.END_PHASE, result, durationMs },\n `End phase: ${this.buildPhase}`\n );\n }\n this.logger = this.defaultLogger;\n this.buildPhase = undefined;\n this.buildPhaseSkipped = false;\n this.buildPhaseHasWarnings = false;\n }\n\n private getEnvironmentSecrets(job: TJob): Record<string, string> {\n if (!job?.secrets?.environmentSecrets) {\n return {};\n }\n\n const environmentSecrets: Record<string, string> = {};\n for (const { name, type, value } of job.secrets.environmentSecrets) {\n if (type === EnvironmentSecretType.STRING) {\n environmentSecrets[name] = value;\n } else {\n environmentSecrets[name] = createTemporaryEnvironmentSecretFile(\n this.environmentSecrectsDirectory,\n value\n );\n }\n }\n return environmentSecrets;\n }\n}\n"]}
@@ -1,3 +1,3 @@
1
1
  import { Ios } from '@expo/eas-build-job';
2
- declare function getFingerprint({ dataBase64, password }: Ios.DistributionCertificate): string;
3
- export { getFingerprint };
2
+ export declare function getFingerprint({ dataBase64, password }: Ios.DistributionCertificate): string;
3
+ export declare function getCommonName({ dataBase64, password }: Ios.DistributionCertificate): string;
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.getFingerprint = void 0;
6
+ exports.getCommonName = exports.getFingerprint = void 0;
7
7
  const node_forge_1 = __importDefault(require("node-forge"));
8
8
  function getFingerprint({ dataBase64, password }) {
9
9
  const certData = getCertData(dataBase64, password);
@@ -13,6 +13,13 @@ function getFingerprint({ dataBase64, password }) {
13
13
  return fingerprint;
14
14
  }
15
15
  exports.getFingerprint = getFingerprint;
16
+ function getCommonName({ dataBase64, password }) {
17
+ const certData = getCertData(dataBase64, password);
18
+ const { attributes } = certData.subject;
19
+ const commonNameAttribute = attributes.find(({ name }) => name === 'commonName');
20
+ return commonNameAttribute.value;
21
+ }
22
+ exports.getCommonName = getCommonName;
16
23
  function getCertData(certificateBase64, password) {
17
24
  var _a, _b, _c;
18
25
  const p12Der = node_forge_1.default.util.decode64(certificateBase64);
@@ -1 +1 @@
1
- {"version":3,"file":"distributionCertificate.js","sourceRoot":"","sources":["../../../src/ios/credentials/distributionCertificate.ts"],"names":[],"mappings":";;;;;;AACA,4DAA+B;AAE/B,SAAS,cAAc,CAAC,EAAE,UAAU,EAAE,QAAQ,EAA+B;IAC3E,MAAM,QAAQ,GAAG,WAAW,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;IACnD,MAAM,QAAQ,GAAG,oBAAK,CAAC,GAAG,CAAC,iBAAiB,CAAC,QAAQ,CAAC,CAAC;IACvD,MAAM,OAAO,GAAG,oBAAK,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,QAAQ,EAAE,CAAC;IACtD,MAAM,WAAW,GAAG,oBAAK,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,CAAC,WAAW,EAAE,CAAC;IAC1F,OAAO,WAAW,CAAC;AACrB,CAAC;AA6BQ,wCAAc;AA3BvB,SAAS,WAAW,CAAC,iBAAyB,EAAE,QAAgB;;IAC9D,MAAM,MAAM,GAAG,oBAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,iBAAiB,CAAC,CAAC;IACtD,MAAM,OAAO,GAAG,oBAAK,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IAC3C,IAAI,GAA2B,CAAC;IAChC,IAAI;QACF,IAAI,QAAQ,EAAE;YACZ,GAAG,GAAG,oBAAK,CAAC,MAAM,CAAC,cAAc,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;SACtD;aAAM;YACL,GAAG,GAAG,oBAAK,CAAC,MAAM,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC;SAC5C;KACF;IAAC,OAAO,MAAW,EAAE;QACpB,MAAM,KAAK,GAAU,MAAM,CAAC;QAC5B,IAAI,kBAAkB,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE;YAC1C,MAAM,IAAI,KAAK,CAAC,wEAAwE,CAAC,CAAC;SAC3F;aAAM;YACL,MAAM,KAAK,CAAC;SACb;KACF;IAED,MAAM,WAAW,GAAG,oBAAK,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC;IAC3C,MAAM,QAAQ,GAAG,MAAA,MAAA,MAAA,GAAG,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,WAAW,EAAE,CAAC,0CAAG,WAAW,CAAC,0CAAG,CAAC,CAAC,0CAAE,IAAI,CAAC;IACjF,IAAI,CAAC,QAAQ,EAAE;QACb,MAAM,IAAI,KAAK,CAAC,qCAAqC,CAAC,CAAC;KACxD;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC","sourcesContent":["import { Ios } from '@expo/eas-build-job';\nimport forge from 'node-forge';\n\nfunction getFingerprint({ dataBase64, password }: Ios.DistributionCertificate): string {\n const certData = getCertData(dataBase64, password);\n const certAsn1 = forge.pki.certificateToAsn1(certData);\n const certDer = forge.asn1.toDer(certAsn1).getBytes();\n const fingerprint = forge.md.sha1.create().update(certDer).digest().toHex().toUpperCase();\n return fingerprint;\n}\n\nfunction getCertData(certificateBase64: string, password: string): any {\n const p12Der = forge.util.decode64(certificateBase64);\n const p12Asn1 = forge.asn1.fromDer(p12Der);\n let p12: forge.pkcs12.Pkcs12Pfx;\n try {\n if (password) {\n p12 = forge.pkcs12.pkcs12FromAsn1(p12Asn1, password);\n } else {\n p12 = forge.pkcs12.pkcs12FromAsn1(p12Asn1);\n }\n } catch (_error: any) {\n const error: Error = _error;\n if (/Invalid password/.exec(error.message)) {\n throw new Error('Provided password for the distribution certificate is probably invalid');\n } else {\n throw error;\n }\n }\n\n const certBagType = forge.pki.oids.certBag;\n const certData = p12.getBags({ bagType: certBagType })?.[certBagType]?.[0]?.cert;\n if (!certData) {\n throw new Error(\"getCertData: couldn't find cert bag\");\n }\n return certData;\n}\n\nexport { getFingerprint };\n"]}
1
+ {"version":3,"file":"distributionCertificate.js","sourceRoot":"","sources":["../../../src/ios/credentials/distributionCertificate.ts"],"names":[],"mappings":";;;;;;AACA,4DAA+B;AAE/B,SAAgB,cAAc,CAAC,EAAE,UAAU,EAAE,QAAQ,EAA+B;IAClF,MAAM,QAAQ,GAAG,WAAW,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;IACnD,MAAM,QAAQ,GAAG,oBAAK,CAAC,GAAG,CAAC,iBAAiB,CAAC,QAAQ,CAAC,CAAC;IACvD,MAAM,OAAO,GAAG,oBAAK,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,QAAQ,EAAE,CAAC;IACtD,MAAM,WAAW,GAAG,oBAAK,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,CAAC,WAAW,EAAE,CAAC;IAC1F,OAAO,WAAW,CAAC;AACrB,CAAC;AAND,wCAMC;AAED,SAAgB,aAAa,CAAC,EAAE,UAAU,EAAE,QAAQ,EAA+B;IACjF,MAAM,QAAQ,GAAG,WAAW,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;IACnD,MAAM,EAAE,UAAU,EAAE,GAAG,QAAQ,CAAC,OAAO,CAAC;IACxC,MAAM,mBAAmB,GAAG,UAAU,CAAC,IAAI,CACzC,CAAC,EAAE,IAAI,EAAqB,EAAE,EAAE,CAAC,IAAI,KAAK,YAAY,CACvD,CAAC;IACF,OAAO,mBAAmB,CAAC,KAAK,CAAC;AACnC,CAAC;AAPD,sCAOC;AAED,SAAS,WAAW,CAAC,iBAAyB,EAAE,QAAgB;;IAC9D,MAAM,MAAM,GAAG,oBAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,iBAAiB,CAAC,CAAC;IACtD,MAAM,OAAO,GAAG,oBAAK,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IAC3C,IAAI,GAA2B,CAAC;IAChC,IAAI;QACF,IAAI,QAAQ,EAAE;YACZ,GAAG,GAAG,oBAAK,CAAC,MAAM,CAAC,cAAc,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;SACtD;aAAM;YACL,GAAG,GAAG,oBAAK,CAAC,MAAM,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC;SAC5C;KACF;IAAC,OAAO,MAAW,EAAE;QACpB,MAAM,KAAK,GAAU,MAAM,CAAC;QAC5B,IAAI,kBAAkB,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE;YAC1C,MAAM,IAAI,KAAK,CAAC,wEAAwE,CAAC,CAAC;SAC3F;aAAM;YACL,MAAM,KAAK,CAAC;SACb;KACF;IAED,MAAM,WAAW,GAAG,oBAAK,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC;IAC3C,MAAM,QAAQ,GAAG,MAAA,MAAA,MAAA,GAAG,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,WAAW,EAAE,CAAC,0CAAG,WAAW,CAAC,0CAAG,CAAC,CAAC,0CAAE,IAAI,CAAC;IACjF,IAAI,CAAC,QAAQ,EAAE;QACb,MAAM,IAAI,KAAK,CAAC,qCAAqC,CAAC,CAAC;KACxD;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC","sourcesContent":["import { Ios } from '@expo/eas-build-job';\nimport forge from 'node-forge';\n\nexport function getFingerprint({ dataBase64, password }: Ios.DistributionCertificate): string {\n const certData = getCertData(dataBase64, password);\n const certAsn1 = forge.pki.certificateToAsn1(certData);\n const certDer = forge.asn1.toDer(certAsn1).getBytes();\n const fingerprint = forge.md.sha1.create().update(certDer).digest().toHex().toUpperCase();\n return fingerprint;\n}\n\nexport function getCommonName({ dataBase64, password }: Ios.DistributionCertificate): string {\n const certData = getCertData(dataBase64, password);\n const { attributes } = certData.subject;\n const commonNameAttribute = attributes.find(\n ({ name }: { name?: string }) => name === 'commonName'\n );\n return commonNameAttribute.value;\n}\n\nfunction getCertData(certificateBase64: string, password: string): any {\n const p12Der = forge.util.decode64(certificateBase64);\n const p12Asn1 = forge.asn1.fromDer(p12Der);\n let p12: forge.pkcs12.Pkcs12Pfx;\n try {\n if (password) {\n p12 = forge.pkcs12.pkcs12FromAsn1(p12Asn1, password);\n } else {\n p12 = forge.pkcs12.pkcs12FromAsn1(p12Asn1);\n }\n } catch (_error: any) {\n const error: Error = _error;\n if (/Invalid password/.exec(error.message)) {\n throw new Error('Provided password for the distribution certificate is probably invalid');\n } else {\n throw error;\n }\n }\n\n const certBagType = forge.pki.oids.certBag;\n const certData = p12.getBags({ bagType: certBagType })?.[certBagType]?.[0]?.cert;\n if (!certData) {\n throw new Error(\"getCertData: couldn't find cert bag\");\n }\n return certData;\n}\n"]}
@@ -1,13 +1,14 @@
1
1
  import { Ios } from '@expo/eas-build-job';
2
2
  import { BuildContext } from '../../context';
3
- import { DistributionType, ProvisioningProfileData } from './provisioningProfile';
3
+ import ProvisioningProfile, { DistributionType, ProvisioningProfileData } from './provisioningProfile';
4
4
  export interface Credentials {
5
+ applicationTargetProvisioningProfile: ProvisioningProfile<Ios.Job>;
5
6
  keychainPath: string;
6
7
  targetProvisioningProfiles: TargetProvisioningProfiles;
7
8
  distributionType: DistributionType;
8
9
  teamId: string;
9
10
  }
10
- declare type TargetProvisioningProfiles = Record<string, ProvisioningProfileData>;
11
+ export declare type TargetProvisioningProfiles = Record<string, ProvisioningProfileData>;
11
12
  export default class IosCredentialsManager<TJob extends Ios.Job> {
12
13
  private readonly ctx;
13
14
  private keychain?;
@@ -17,5 +18,5 @@ export default class IosCredentialsManager<TJob extends Ios.Job> {
17
18
  prepare(): Promise<Credentials | null>;
18
19
  cleanUp(): Promise<void>;
19
20
  private prepareTargetCredentials;
21
+ private getApplicationTargetProvisioningProfile;
20
22
  }
21
- export {};
@@ -30,6 +30,7 @@ const assert_1 = __importDefault(require("assert"));
30
30
  const os_1 = __importDefault(require("os"));
31
31
  const path_1 = __importDefault(require("path"));
32
32
  const fs_extra_1 = __importDefault(require("fs-extra"));
33
+ const lodash_1 = require("lodash");
33
34
  const uuid_1 = require("uuid");
34
35
  const distributionCertificateUtils = __importStar(require("./distributionCertificate"));
35
36
  const keychain_1 = __importDefault(require("./keychain"));
@@ -59,9 +60,11 @@ class IosCredentialsManager {
59
60
  this.provisioningProfiles.push(provisioningProfile);
60
61
  targetProvisioningProfiles[target] = provisioningProfile.data;
61
62
  }
63
+ const applicationTargetProvisioningProfile = this.getApplicationTargetProvisioningProfile();
62
64
  // TODO: ensure that all dist types and team ids in the array are the same
63
- const { distributionType, teamId } = this.provisioningProfiles[0].data;
65
+ const { distributionType, teamId } = applicationTargetProvisioningProfile.data;
64
66
  return {
67
+ applicationTargetProvisioningProfile,
65
68
  keychainPath: this.keychain.data.path,
66
69
  targetProvisioningProfiles,
67
70
  distributionType,
@@ -87,14 +90,16 @@ class IosCredentialsManager {
87
90
  (0, assert_1.default)(this.keychain, 'Keychain should be initialized');
88
91
  this.ctx.logger.info(`Preparing credentials for target '${target}'`);
89
92
  const distCertPath = path_1.default.join(os_1.default.tmpdir(), `${(0, uuid_1.v4)()}.p12`);
90
- this.ctx.logger.info('Getting distribution certificate fingerprint');
93
+ this.ctx.logger.info('Getting distribution certificate fingerprint and common name');
91
94
  const certificateFingerprint = distributionCertificateUtils.getFingerprint(targetCredentials.distributionCertificate);
95
+ const certificateCommonName = distributionCertificateUtils.getCommonName(targetCredentials.distributionCertificate);
96
+ this.ctx.logger.info(`Fingerprint = "${certificateFingerprint}", common name = ${certificateCommonName}`);
92
97
  this.ctx.logger.info(`Writing distribution certificate to ${distCertPath}`);
93
98
  await fs_extra_1.default.writeFile(distCertPath, Buffer.from(targetCredentials.distributionCertificate.dataBase64, 'base64'));
94
99
  this.ctx.logger.info('Importing distribution certificate into the keychain');
95
100
  await this.keychain.importCertificate(distCertPath, targetCredentials.distributionCertificate.password);
96
101
  this.ctx.logger.info('Initializing provisioning profile');
97
- const provisioningProfile = new provisioningProfile_1.default(this.ctx, Buffer.from(targetCredentials.provisioningProfileBase64, 'base64'), this.keychain.data.path);
102
+ const provisioningProfile = new provisioningProfile_1.default(this.ctx, Buffer.from(targetCredentials.provisioningProfileBase64, 'base64'), this.keychain.data.path, target, certificateCommonName);
98
103
  await provisioningProfile.init();
99
104
  this.ctx.logger.info('Validating whether distribution certificate has been imported successfully');
100
105
  await this.keychain.ensureCertificateImported(provisioningProfile.data.teamId, certificateFingerprint);
@@ -107,6 +112,11 @@ class IosCredentialsManager {
107
112
  throw err;
108
113
  }
109
114
  }
115
+ getApplicationTargetProvisioningProfile() {
116
+ // sorting works because bundle ids share common prefix
117
+ const sorted = (0, lodash_1.orderBy)(this.provisioningProfiles, 'data.bundleIdentifier', 'asc');
118
+ return sorted[0];
119
+ }
110
120
  }
111
121
  exports.default = IosCredentialsManager;
112
122
  //# sourceMappingURL=manager.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"manager.js","sourceRoot":"","sources":["../../../src/ios/credentials/manager.ts"],"names":[],"mappings":"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","sourcesContent":["import assert from 'assert';\nimport os from 'os';\nimport path from 'path';\n\nimport { Ios } from '@expo/eas-build-job';\nimport fs from 'fs-extra';\nimport { v4 as uuid } from 'uuid';\n\nimport { BuildContext } from '../../context';\n\nimport * as distributionCertificateUtils from './distributionCertificate';\nimport Keychain from './keychain';\nimport ProvisioningProfile, {\n DistributionType,\n ProvisioningProfileData,\n} from './provisioningProfile';\n\nexport interface Credentials {\n keychainPath: string;\n targetProvisioningProfiles: TargetProvisioningProfiles;\n distributionType: DistributionType;\n teamId: string;\n}\n\ntype TargetProvisioningProfiles = Record<string, ProvisioningProfileData>;\n\nexport default class IosCredentialsManager<TJob extends Ios.Job> {\n private keychain?: Keychain<TJob>;\n private readonly provisioningProfiles: ProvisioningProfile<TJob>[] = [];\n private cleanedUp = false;\n\n constructor(private readonly ctx: BuildContext<TJob>) {}\n\n public async prepare(): Promise<Credentials | null> {\n if (this.ctx.job.simulator) {\n return null;\n }\n\n const { buildCredentials } = this.ctx.job.secrets;\n if (!buildCredentials) {\n throw new Error('credentials are required for an iOS build');\n }\n\n this.ctx.logger.info('Preparing credentials');\n\n this.ctx.logger.info('Creating keychain');\n this.keychain = new Keychain(this.ctx);\n await this.keychain.create();\n\n const targets = Object.keys(buildCredentials);\n const targetProvisioningProfiles: TargetProvisioningProfiles = {};\n for (const target of targets) {\n const provisioningProfile = await this.prepareTargetCredentials(\n target,\n buildCredentials[target]\n );\n this.provisioningProfiles.push(provisioningProfile);\n targetProvisioningProfiles[target] = provisioningProfile.data;\n }\n\n // TODO: ensure that all dist types and team ids in the array are the same\n const { distributionType, teamId } = this.provisioningProfiles[0].data;\n\n return {\n keychainPath: this.keychain.data.path,\n targetProvisioningProfiles,\n distributionType,\n teamId,\n };\n }\n\n public async cleanUp(): Promise<void> {\n if (this.cleanedUp || (!this.keychain && this.provisioningProfiles.length === 0)) {\n return;\n }\n\n if (this.keychain) {\n await this.keychain.destroy();\n }\n if (this.provisioningProfiles) {\n for (const provisioningProfile of this.provisioningProfiles) {\n await provisioningProfile.destroy();\n }\n }\n this.cleanedUp = true;\n }\n\n private async prepareTargetCredentials(\n target: string,\n targetCredentials: Ios.TargetCredentials\n ): Promise<ProvisioningProfile<TJob>> {\n try {\n assert(this.keychain, 'Keychain should be initialized');\n\n this.ctx.logger.info(`Preparing credentials for target '${target}'`);\n const distCertPath = path.join(os.tmpdir(), `${uuid()}.p12`);\n\n this.ctx.logger.info('Getting distribution certificate fingerprint');\n const certificateFingerprint = distributionCertificateUtils.getFingerprint(\n targetCredentials.distributionCertificate\n );\n\n this.ctx.logger.info(`Writing distribution certificate to ${distCertPath}`);\n await fs.writeFile(\n distCertPath,\n Buffer.from(targetCredentials.distributionCertificate.dataBase64, 'base64')\n );\n\n this.ctx.logger.info('Importing distribution certificate into the keychain');\n await this.keychain.importCertificate(\n distCertPath,\n targetCredentials.distributionCertificate.password\n );\n\n this.ctx.logger.info('Initializing provisioning profile');\n const provisioningProfile = new ProvisioningProfile(\n this.ctx,\n Buffer.from(targetCredentials.provisioningProfileBase64, 'base64'),\n this.keychain.data.path\n );\n await provisioningProfile.init();\n\n this.ctx.logger.info(\n 'Validating whether distribution certificate has been imported successfully'\n );\n await this.keychain.ensureCertificateImported(\n provisioningProfile.data.teamId,\n certificateFingerprint\n );\n\n this.ctx.logger.info(\n 'Verifying whether the distribution certificate and provisioning profile match'\n );\n provisioningProfile.verifyCertificate(certificateFingerprint);\n\n return provisioningProfile;\n } catch (err) {\n await this.cleanUp();\n throw err;\n }\n }\n}\n"]}
1
+ {"version":3,"file":"manager.js","sourceRoot":"","sources":["../../../src/ios/credentials/manager.ts"],"names":[],"mappings":"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","sourcesContent":["import assert from 'assert';\nimport os from 'os';\nimport path from 'path';\n\nimport { Ios } from '@expo/eas-build-job';\nimport fs from 'fs-extra';\nimport { orderBy } from 'lodash';\nimport { v4 as uuid } from 'uuid';\n\nimport { BuildContext } from '../../context';\n\nimport * as distributionCertificateUtils from './distributionCertificate';\nimport Keychain from './keychain';\nimport ProvisioningProfile, {\n DistributionType,\n ProvisioningProfileData,\n} from './provisioningProfile';\n\nexport interface Credentials {\n applicationTargetProvisioningProfile: ProvisioningProfile<Ios.Job>;\n keychainPath: string;\n targetProvisioningProfiles: TargetProvisioningProfiles;\n distributionType: DistributionType;\n teamId: string;\n}\n\nexport type TargetProvisioningProfiles = Record<string, ProvisioningProfileData>;\n\nexport default class IosCredentialsManager<TJob extends Ios.Job> {\n private keychain?: Keychain<TJob>;\n private readonly provisioningProfiles: ProvisioningProfile<TJob>[] = [];\n private cleanedUp = false;\n\n constructor(private readonly ctx: BuildContext<TJob>) {}\n\n public async prepare(): Promise<Credentials | null> {\n if (this.ctx.job.simulator) {\n return null;\n }\n\n const { buildCredentials } = this.ctx.job.secrets;\n if (!buildCredentials) {\n throw new Error('credentials are required for an iOS build');\n }\n\n this.ctx.logger.info('Preparing credentials');\n\n this.ctx.logger.info('Creating keychain');\n this.keychain = new Keychain(this.ctx);\n await this.keychain.create();\n\n const targets = Object.keys(buildCredentials);\n const targetProvisioningProfiles: TargetProvisioningProfiles = {};\n for (const target of targets) {\n const provisioningProfile = await this.prepareTargetCredentials(\n target,\n buildCredentials[target]\n );\n this.provisioningProfiles.push(provisioningProfile);\n targetProvisioningProfiles[target] = provisioningProfile.data;\n }\n\n const applicationTargetProvisioningProfile = this.getApplicationTargetProvisioningProfile();\n\n // TODO: ensure that all dist types and team ids in the array are the same\n const { distributionType, teamId } = applicationTargetProvisioningProfile.data;\n\n return {\n applicationTargetProvisioningProfile,\n keychainPath: this.keychain.data.path,\n targetProvisioningProfiles,\n distributionType,\n teamId,\n };\n }\n\n public async cleanUp(): Promise<void> {\n if (this.cleanedUp || (!this.keychain && this.provisioningProfiles.length === 0)) {\n return;\n }\n\n if (this.keychain) {\n await this.keychain.destroy();\n }\n if (this.provisioningProfiles) {\n for (const provisioningProfile of this.provisioningProfiles) {\n await provisioningProfile.destroy();\n }\n }\n this.cleanedUp = true;\n }\n\n private async prepareTargetCredentials(\n target: string,\n targetCredentials: Ios.TargetCredentials\n ): Promise<ProvisioningProfile<TJob>> {\n try {\n assert(this.keychain, 'Keychain should be initialized');\n\n this.ctx.logger.info(`Preparing credentials for target '${target}'`);\n const distCertPath = path.join(os.tmpdir(), `${uuid()}.p12`);\n\n this.ctx.logger.info('Getting distribution certificate fingerprint and common name');\n const certificateFingerprint = distributionCertificateUtils.getFingerprint(\n targetCredentials.distributionCertificate\n );\n const certificateCommonName = distributionCertificateUtils.getCommonName(\n targetCredentials.distributionCertificate\n );\n this.ctx.logger.info(\n `Fingerprint = \"${certificateFingerprint}\", common name = ${certificateCommonName}`\n );\n\n this.ctx.logger.info(`Writing distribution certificate to ${distCertPath}`);\n await fs.writeFile(\n distCertPath,\n Buffer.from(targetCredentials.distributionCertificate.dataBase64, 'base64')\n );\n\n this.ctx.logger.info('Importing distribution certificate into the keychain');\n await this.keychain.importCertificate(\n distCertPath,\n targetCredentials.distributionCertificate.password\n );\n\n this.ctx.logger.info('Initializing provisioning profile');\n const provisioningProfile = new ProvisioningProfile(\n this.ctx,\n Buffer.from(targetCredentials.provisioningProfileBase64, 'base64'),\n this.keychain.data.path,\n target,\n certificateCommonName\n );\n await provisioningProfile.init();\n\n this.ctx.logger.info(\n 'Validating whether distribution certificate has been imported successfully'\n );\n await this.keychain.ensureCertificateImported(\n provisioningProfile.data.teamId,\n certificateFingerprint\n );\n\n this.ctx.logger.info(\n 'Verifying whether the distribution certificate and provisioning profile match'\n );\n provisioningProfile.verifyCertificate(certificateFingerprint);\n\n return provisioningProfile;\n } catch (err) {\n await this.cleanUp();\n throw err;\n }\n }\n\n private getApplicationTargetProvisioningProfile(): ProvisioningProfile<TJob> {\n // sorting works because bundle ids share common prefix\n const sorted = orderBy(this.provisioningProfiles, 'data.bundleIdentifier', 'asc');\n return sorted[0];\n }\n}\n"]}
@@ -2,11 +2,14 @@
2
2
  import { Ios } from '@expo/eas-build-job';
3
3
  import { BuildContext } from '../../context';
4
4
  export interface ProvisioningProfileData {
5
+ path: string;
6
+ target: string;
5
7
  bundleIdentifier: string;
6
8
  teamId: string;
7
9
  uuid: string;
8
10
  name: string;
9
11
  developerCertificate: Buffer;
12
+ certificateCommonName: string;
10
13
  distributionType: DistributionType;
11
14
  }
12
15
  export declare enum DistributionType {
@@ -18,10 +21,12 @@ export default class ProvisioningProfile<TJob extends Ios.Job> {
18
21
  private readonly ctx;
19
22
  private readonly profile;
20
23
  private readonly keychainPath;
24
+ private readonly target;
25
+ private readonly certificateCommonName;
21
26
  get data(): ProvisioningProfileData;
22
27
  private readonly profilePath;
23
28
  private profileData?;
24
- constructor(ctx: BuildContext<TJob>, profile: Buffer, keychainPath: string);
29
+ constructor(ctx: BuildContext<TJob>, profile: Buffer, keychainPath: string, target: string, certificateCommonName: string);
25
30
  init(): Promise<void>;
26
31
  destroy(): Promise<void>;
27
32
  verifyCertificate(fingerprint: string): void;