@expo/build-tools 1.0.32 → 1.0.36
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.
- package/dist/builders/custom.js +1 -1
- package/dist/builders/custom.js.map +1 -1
- package/dist/customBuildContext.d.ts +1 -0
- package/dist/customBuildContext.js +1 -0
- package/dist/customBuildContext.js.map +1 -1
- package/dist/steps/easFunctions.d.ts +1 -3
- package/dist/steps/easFunctions.js +26 -17
- package/dist/steps/easFunctions.js.map +1 -1
- package/dist/steps/functions/checkout.js.map +1 -0
- package/dist/steps/functions/{utils/configureAndroidVersion.js → configureAndroidVersion.js} +2 -2
- package/dist/steps/functions/configureAndroidVersion.js.map +1 -0
- package/dist/steps/functions/{eas/configureExpoUpdatesIfInstalled.js → configureEASUpdateIfInstalled.js} +5 -5
- package/dist/steps/functions/configureEASUpdateIfInstalled.js.map +1 -0
- package/dist/steps/functions/configureIosCredentials.d.ts +2 -0
- package/dist/steps/functions/configureIosCredentials.js +54 -0
- package/dist/steps/functions/configureIosCredentials.js.map +1 -0
- package/dist/steps/functions/configureIosVersion.d.ts +2 -0
- package/dist/steps/functions/configureIosVersion.js +77 -0
- package/dist/steps/functions/configureIosVersion.js.map +1 -0
- package/dist/steps/functions/{eas/findAndUploadBuildArtifacts.d.ts → findAndUploadBuildArtifacts.d.ts} +1 -1
- package/dist/steps/functions/{eas/findAndUploadBuildArtifacts.js → findAndUploadBuildArtifacts.js} +4 -8
- package/dist/steps/functions/findAndUploadBuildArtifacts.js.map +1 -0
- package/dist/steps/functions/generateGymfileFromTemplate.d.ts +2 -0
- package/dist/steps/functions/generateGymfileFromTemplate.js +209 -0
- package/dist/steps/functions/generateGymfileFromTemplate.js.map +1 -0
- package/dist/steps/functions/{utils/injectAndroidCredentials.js → injectAndroidCredentials.js} +2 -2
- package/dist/steps/functions/injectAndroidCredentials.js.map +1 -0
- package/dist/steps/functions/installNodeModules.d.ts +4 -0
- package/dist/steps/functions/{eas/installNodeModules.js → installNodeModules.js} +6 -6
- package/dist/steps/functions/installNodeModules.js.map +1 -0
- package/dist/steps/functions/prebuild.d.ts +2 -0
- package/dist/steps/functions/{eas/prebuild.js → prebuild.js} +18 -26
- package/dist/steps/functions/prebuild.js.map +1 -0
- package/dist/steps/functions/resolveAppleTeamIdFromCredentials.d.ts +2 -0
- package/dist/steps/functions/resolveAppleTeamIdFromCredentials.js +47 -0
- package/dist/steps/functions/resolveAppleTeamIdFromCredentials.js.map +1 -0
- package/dist/steps/functions/runFastlane.d.ts +2 -0
- package/dist/steps/functions/runFastlane.js +26 -0
- package/dist/steps/functions/runFastlane.js.map +1 -0
- package/dist/steps/functions/runGradle.d.ts +2 -0
- package/dist/steps/functions/runGradle.js +36 -0
- package/dist/steps/functions/runGradle.js.map +1 -0
- package/dist/steps/functions/{utils/uploadArtifact.d.ts → uploadArtifact.d.ts} +1 -1
- package/dist/steps/functions/{utils/uploadArtifact.js → uploadArtifact.js} +2 -2
- package/dist/steps/functions/uploadArtifact.js.map +1 -0
- package/dist/steps/functions/useNpmToken.d.ts +2 -0
- package/dist/steps/functions/{eas/setUpNpmrc.js → useNpmToken.js} +5 -5
- package/dist/steps/functions/useNpmToken.js.map +1 -0
- package/dist/steps/utils/android/gradle.d.ts +11 -0
- package/dist/steps/utils/android/gradle.js +110 -0
- package/dist/steps/utils/android/gradle.js.map +1 -0
- package/dist/steps/utils/expoUpdates.js +2 -2
- package/dist/steps/utils/expoUpdates.js.map +1 -1
- package/dist/steps/utils/ios/configure.d.ts +15 -0
- package/dist/steps/utils/ios/configure.js +78 -0
- package/dist/steps/utils/ios/configure.js.map +1 -0
- package/dist/steps/utils/ios/credentials/credentials.d.ts +4 -0
- package/dist/steps/utils/ios/credentials/credentials.js +16 -0
- package/dist/steps/utils/ios/credentials/credentials.js.map +1 -0
- package/dist/steps/utils/ios/credentials/distributionCertificate.d.ts +3 -0
- package/dist/steps/utils/ios/credentials/distributionCertificate.js +52 -0
- package/dist/steps/utils/ios/credentials/distributionCertificate.js.map +1 -0
- package/dist/steps/utils/ios/credentials/keychain.d.ts +19 -0
- package/dist/steps/utils/ios/credentials/keychain.js +93 -0
- package/dist/steps/utils/ios/credentials/keychain.js.map +1 -0
- package/dist/steps/utils/ios/credentials/manager.d.ts +23 -0
- package/dist/steps/utils/ios/credentials/manager.js +115 -0
- package/dist/steps/utils/ios/credentials/manager.js.map +1 -0
- package/dist/steps/utils/ios/credentials/provisioningProfile.d.ts +35 -0
- package/dist/steps/utils/ios/credentials/provisioningProfile.js +114 -0
- package/dist/steps/utils/ios/credentials/provisioningProfile.js.map +1 -0
- package/dist/steps/utils/ios/fastlane.d.ts +7 -3
- package/dist/steps/utils/ios/fastlane.js +21 -34
- package/dist/steps/utils/ios/fastlane.js.map +1 -1
- package/dist/steps/utils/ios/resolve.d.ts +2 -4
- package/dist/steps/utils/ios/resolve.js +9 -3
- package/dist/steps/utils/ios/resolve.js.map +1 -1
- package/dist/steps/utils/ios/xcpretty.d.ts +16 -0
- package/dist/steps/utils/ios/xcpretty.js +88 -0
- package/dist/steps/utils/ios/xcpretty.js.map +1 -0
- package/package.json +3 -3
- package/dist/steps/functions/eas/buildReactNativeApp.d.ts +0 -4
- package/dist/steps/functions/eas/buildReactNativeApp.js +0 -53
- package/dist/steps/functions/eas/buildReactNativeApp.js.map +0 -1
- package/dist/steps/functions/eas/checkout.js.map +0 -1
- package/dist/steps/functions/eas/configureExpoUpdatesIfInstalled.js.map +0 -1
- package/dist/steps/functions/eas/findAndUploadBuildArtifacts.js.map +0 -1
- package/dist/steps/functions/eas/installNodeModules.d.ts +0 -5
- package/dist/steps/functions/eas/installNodeModules.js.map +0 -1
- package/dist/steps/functions/eas/prebuild.d.ts +0 -3
- package/dist/steps/functions/eas/prebuild.js.map +0 -1
- package/dist/steps/functions/eas/setUpNpmrc.d.ts +0 -3
- package/dist/steps/functions/eas/setUpNpmrc.js.map +0 -1
- package/dist/steps/functions/utils/configureAndroidVersion.js.map +0 -1
- package/dist/steps/functions/utils/injectAndroidCredentials.js.map +0 -1
- package/dist/steps/functions/utils/uploadArtifact.js.map +0 -1
- /package/dist/steps/functions/{eas/checkout.d.ts → checkout.d.ts} +0 -0
- /package/dist/steps/functions/{eas/checkout.js → checkout.js} +0 -0
- /package/dist/steps/functions/{utils/configureAndroidVersion.d.ts → configureAndroidVersion.d.ts} +0 -0
- /package/dist/steps/functions/{eas/configureExpoUpdatesIfInstalled.d.ts → configureEASUpdateIfInstalled.d.ts} +0 -0
- /package/dist/steps/functions/{utils/injectAndroidCredentials.d.ts → injectAndroidCredentials.d.ts} +0 -0
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
26
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
27
|
+
};
|
|
28
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
|
+
const assert_1 = __importDefault(require("assert"));
|
|
30
|
+
const os_1 = __importDefault(require("os"));
|
|
31
|
+
const path_1 = __importDefault(require("path"));
|
|
32
|
+
const fs_extra_1 = __importDefault(require("fs-extra"));
|
|
33
|
+
const lodash_1 = require("lodash");
|
|
34
|
+
const uuid_1 = require("uuid");
|
|
35
|
+
const distributionCertificateUtils = __importStar(require("./distributionCertificate"));
|
|
36
|
+
const keychain_1 = __importDefault(require("./keychain"));
|
|
37
|
+
const provisioningProfile_1 = __importDefault(require("./provisioningProfile"));
|
|
38
|
+
class IosCredentialsManager {
|
|
39
|
+
constructor(buildCredentials) {
|
|
40
|
+
this.buildCredentials = buildCredentials;
|
|
41
|
+
this.provisioningProfiles = [];
|
|
42
|
+
this.cleanedUp = false;
|
|
43
|
+
}
|
|
44
|
+
async prepare(logger) {
|
|
45
|
+
logger.info('Preparing credentials');
|
|
46
|
+
logger.info('Creating keychain');
|
|
47
|
+
this.keychain = new keychain_1.default();
|
|
48
|
+
await this.keychain.create(logger);
|
|
49
|
+
const targets = Object.keys(this.buildCredentials);
|
|
50
|
+
const targetProvisioningProfiles = {};
|
|
51
|
+
for (const target of targets) {
|
|
52
|
+
const provisioningProfile = await this.prepareTargetCredentials(logger, target, this.buildCredentials[target]);
|
|
53
|
+
this.provisioningProfiles.push(provisioningProfile);
|
|
54
|
+
targetProvisioningProfiles[target] = provisioningProfile.data;
|
|
55
|
+
}
|
|
56
|
+
const applicationTargetProvisioningProfile = this.getApplicationTargetProvisioningProfile();
|
|
57
|
+
// TODO: ensure that all dist types and team ids in the array are the same
|
|
58
|
+
const { distributionType, teamId } = applicationTargetProvisioningProfile.data;
|
|
59
|
+
return {
|
|
60
|
+
applicationTargetProvisioningProfile,
|
|
61
|
+
keychainPath: this.keychain.data.path,
|
|
62
|
+
targetProvisioningProfiles,
|
|
63
|
+
distributionType,
|
|
64
|
+
teamId,
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
async cleanUp(logger) {
|
|
68
|
+
if (this.cleanedUp || (!this.keychain && this.provisioningProfiles.length === 0)) {
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
if (this.keychain) {
|
|
72
|
+
await this.keychain.destroy(logger);
|
|
73
|
+
}
|
|
74
|
+
if (this.provisioningProfiles) {
|
|
75
|
+
for (const provisioningProfile of this.provisioningProfiles) {
|
|
76
|
+
await provisioningProfile.destroy(logger);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
this.cleanedUp = true;
|
|
80
|
+
}
|
|
81
|
+
async prepareTargetCredentials(logger, target, targetCredentials) {
|
|
82
|
+
try {
|
|
83
|
+
(0, assert_1.default)(this.keychain, 'Keychain should be initialized');
|
|
84
|
+
logger.info(`Preparing credentials for target '${target}'`);
|
|
85
|
+
const distCertPath = path_1.default.join(os_1.default.tmpdir(), `${(0, uuid_1.v4)()}.p12`);
|
|
86
|
+
logger.info('Getting distribution certificate fingerprint and common name');
|
|
87
|
+
const certificateFingerprint = distributionCertificateUtils.getFingerprint(targetCredentials.distributionCertificate);
|
|
88
|
+
const certificateCommonName = distributionCertificateUtils.getCommonName(targetCredentials.distributionCertificate);
|
|
89
|
+
logger.info(`Fingerprint = "${certificateFingerprint}", common name = ${certificateCommonName}`);
|
|
90
|
+
logger.info(`Writing distribution certificate to ${distCertPath}`);
|
|
91
|
+
await fs_extra_1.default.writeFile(distCertPath, Buffer.from(targetCredentials.distributionCertificate.dataBase64, 'base64'));
|
|
92
|
+
logger.info('Importing distribution certificate into the keychain');
|
|
93
|
+
await this.keychain.importCertificate(logger, distCertPath, targetCredentials.distributionCertificate.password);
|
|
94
|
+
logger.info('Initializing provisioning profile');
|
|
95
|
+
const provisioningProfile = new provisioningProfile_1.default(Buffer.from(targetCredentials.provisioningProfileBase64, 'base64'), this.keychain.data.path, target, certificateCommonName);
|
|
96
|
+
await provisioningProfile.init(logger);
|
|
97
|
+
logger.info('Validating whether distribution certificate has been imported successfully');
|
|
98
|
+
await this.keychain.ensureCertificateImported(provisioningProfile.data.teamId, certificateFingerprint);
|
|
99
|
+
logger.info('Verifying whether the distribution certificate and provisioning profile match');
|
|
100
|
+
provisioningProfile.verifyCertificate(certificateFingerprint);
|
|
101
|
+
return provisioningProfile;
|
|
102
|
+
}
|
|
103
|
+
catch (err) {
|
|
104
|
+
await this.cleanUp(logger);
|
|
105
|
+
throw err;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
getApplicationTargetProvisioningProfile() {
|
|
109
|
+
// sorting works because bundle ids share common prefix
|
|
110
|
+
const sorted = (0, lodash_1.orderBy)(this.provisioningProfiles, 'data.bundleIdentifier', 'asc');
|
|
111
|
+
return sorted[0];
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
exports.default = IosCredentialsManager;
|
|
115
|
+
//# sourceMappingURL=manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manager.js","sourceRoot":"","sources":["../../../../../src/steps/utils/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';\nimport { bunyan } from '@expo/logger';\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;\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 {\n private keychain?: Keychain;\n private readonly provisioningProfiles: ProvisioningProfile[] = [];\n private cleanedUp = false;\n\n constructor(private readonly buildCredentials: Ios.BuildCredentials) {}\n\n public async prepare(logger: bunyan): Promise<Credentials> {\n logger.info('Preparing credentials');\n\n logger.info('Creating keychain');\n this.keychain = new Keychain();\n await this.keychain.create(logger);\n\n const targets = Object.keys(this.buildCredentials);\n const targetProvisioningProfiles: TargetProvisioningProfiles = {};\n for (const target of targets) {\n const provisioningProfile = await this.prepareTargetCredentials(\n logger,\n target,\n this.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(logger: bunyan): 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(logger);\n }\n if (this.provisioningProfiles) {\n for (const provisioningProfile of this.provisioningProfiles) {\n await provisioningProfile.destroy(logger);\n }\n }\n this.cleanedUp = true;\n }\n\n private async prepareTargetCredentials(\n logger: bunyan,\n target: string,\n targetCredentials: Ios.TargetCredentials\n ): Promise<ProvisioningProfile> {\n try {\n assert(this.keychain, 'Keychain should be initialized');\n\n logger.info(`Preparing credentials for target '${target}'`);\n const distCertPath = path.join(os.tmpdir(), `${uuid()}.p12`);\n\n 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 logger.info(\n `Fingerprint = \"${certificateFingerprint}\", common name = ${certificateCommonName}`\n );\n\n logger.info(`Writing distribution certificate to ${distCertPath}`);\n await fs.writeFile(\n distCertPath,\n Buffer.from(targetCredentials.distributionCertificate.dataBase64, 'base64')\n );\n\n logger.info('Importing distribution certificate into the keychain');\n await this.keychain.importCertificate(\n logger,\n distCertPath,\n targetCredentials.distributionCertificate.password\n );\n\n logger.info('Initializing provisioning profile');\n const provisioningProfile = new ProvisioningProfile(\n Buffer.from(targetCredentials.provisioningProfileBase64, 'base64'),\n this.keychain.data.path,\n target,\n certificateCommonName\n );\n await provisioningProfile.init(logger);\n\n logger.info('Validating whether distribution certificate has been imported successfully');\n await this.keychain.ensureCertificateImported(\n provisioningProfile.data.teamId,\n certificateFingerprint\n );\n\n logger.info('Verifying whether the distribution certificate and provisioning profile match');\n provisioningProfile.verifyCertificate(certificateFingerprint);\n\n return provisioningProfile;\n } catch (err) {\n await this.cleanUp(logger);\n throw err;\n }\n }\n\n private getApplicationTargetProvisioningProfile(): ProvisioningProfile {\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"]}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
/// <reference types="bunyan" />
|
|
3
|
+
import { bunyan } from '@expo/logger';
|
|
4
|
+
export interface ProvisioningProfileData {
|
|
5
|
+
path: string;
|
|
6
|
+
target: string;
|
|
7
|
+
bundleIdentifier: string;
|
|
8
|
+
teamId: string;
|
|
9
|
+
uuid: string;
|
|
10
|
+
name: string;
|
|
11
|
+
developerCertificate: Buffer;
|
|
12
|
+
certificateCommonName: string;
|
|
13
|
+
distributionType: DistributionType;
|
|
14
|
+
}
|
|
15
|
+
export declare enum DistributionType {
|
|
16
|
+
AD_HOC = "ad-hoc",
|
|
17
|
+
APP_STORE = "app-store",
|
|
18
|
+
ENTERPRISE = "enterprise"
|
|
19
|
+
}
|
|
20
|
+
export default class ProvisioningProfile {
|
|
21
|
+
private readonly profile;
|
|
22
|
+
private readonly keychainPath;
|
|
23
|
+
private readonly target;
|
|
24
|
+
private readonly certificateCommonName;
|
|
25
|
+
get data(): ProvisioningProfileData;
|
|
26
|
+
private readonly profilePath;
|
|
27
|
+
private profileData?;
|
|
28
|
+
constructor(profile: Buffer, keychainPath: string, target: string, certificateCommonName: string);
|
|
29
|
+
init(logger: bunyan): Promise<void>;
|
|
30
|
+
destroy(logger: bunyan): Promise<void>;
|
|
31
|
+
verifyCertificate(fingerprint: string): void;
|
|
32
|
+
private load;
|
|
33
|
+
private resolveDistributionType;
|
|
34
|
+
private genDerCertFingerprint;
|
|
35
|
+
}
|
|
@@ -0,0 +1,114 @@
|
|
|
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.DistributionType = void 0;
|
|
7
|
+
const crypto_1 = __importDefault(require("crypto"));
|
|
8
|
+
const os_1 = __importDefault(require("os"));
|
|
9
|
+
const path_1 = __importDefault(require("path"));
|
|
10
|
+
const eas_build_job_1 = require("@expo/eas-build-job");
|
|
11
|
+
const turtle_spawn_1 = __importDefault(require("@expo/turtle-spawn"));
|
|
12
|
+
const fs_extra_1 = __importDefault(require("fs-extra"));
|
|
13
|
+
const plist_1 = __importDefault(require("plist"));
|
|
14
|
+
const uuid_1 = require("uuid");
|
|
15
|
+
var DistributionType;
|
|
16
|
+
(function (DistributionType) {
|
|
17
|
+
DistributionType["AD_HOC"] = "ad-hoc";
|
|
18
|
+
DistributionType["APP_STORE"] = "app-store";
|
|
19
|
+
DistributionType["ENTERPRISE"] = "enterprise";
|
|
20
|
+
})(DistributionType || (exports.DistributionType = DistributionType = {}));
|
|
21
|
+
const PROVISIONING_PROFILES_DIRECTORY = path_1.default.join(os_1.default.homedir(), 'Library/MobileDevice/Provisioning Profiles');
|
|
22
|
+
class ProvisioningProfile {
|
|
23
|
+
get data() {
|
|
24
|
+
if (!this.profileData) {
|
|
25
|
+
throw new Error('You must init the profile first!');
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
return this.profileData;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
constructor(profile, keychainPath, target, certificateCommonName) {
|
|
32
|
+
this.profile = profile;
|
|
33
|
+
this.keychainPath = keychainPath;
|
|
34
|
+
this.target = target;
|
|
35
|
+
this.certificateCommonName = certificateCommonName;
|
|
36
|
+
this.profilePath = path_1.default.join(PROVISIONING_PROFILES_DIRECTORY, `${(0, uuid_1.v4)()}.mobileprovision`);
|
|
37
|
+
}
|
|
38
|
+
async init(logger) {
|
|
39
|
+
logger.debug(`Making sure ${PROVISIONING_PROFILES_DIRECTORY} exits`);
|
|
40
|
+
await fs_extra_1.default.ensureDir(PROVISIONING_PROFILES_DIRECTORY);
|
|
41
|
+
logger.debug(`Writing provisioning profile to ${this.profilePath}`);
|
|
42
|
+
await fs_extra_1.default.writeFile(this.profilePath, this.profile);
|
|
43
|
+
logger.debug('Loading provisioning profile');
|
|
44
|
+
await this.load();
|
|
45
|
+
}
|
|
46
|
+
async destroy(logger) {
|
|
47
|
+
if (!this.profilePath) {
|
|
48
|
+
logger.warn("There is nothing to destroy, a provisioning profile hasn't been created yet.");
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
logger.info('Removing provisioning profile');
|
|
52
|
+
await fs_extra_1.default.remove(this.profilePath);
|
|
53
|
+
}
|
|
54
|
+
verifyCertificate(fingerprint) {
|
|
55
|
+
const devCertFingerprint = this.genDerCertFingerprint();
|
|
56
|
+
if (devCertFingerprint !== fingerprint) {
|
|
57
|
+
throw new eas_build_job_1.errors.CredentialsDistCertMismatchError(`Provisioning profile and distribution certificate don't match.
|
|
58
|
+
Profile's certificate fingerprint = ${devCertFingerprint}, distribution certificate fingerprint = ${fingerprint}`);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
async load() {
|
|
62
|
+
let result;
|
|
63
|
+
try {
|
|
64
|
+
result = await (0, turtle_spawn_1.default)('security', ['cms', '-D', '-k', this.keychainPath, '-i', this.profilePath], {
|
|
65
|
+
stdio: 'pipe',
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
catch (err) {
|
|
69
|
+
throw new Error(err.stderr.trim());
|
|
70
|
+
}
|
|
71
|
+
const { output } = result;
|
|
72
|
+
const plistRaw = output.join('');
|
|
73
|
+
let plistData;
|
|
74
|
+
try {
|
|
75
|
+
plistData = plist_1.default.parse(plistRaw);
|
|
76
|
+
}
|
|
77
|
+
catch (error) {
|
|
78
|
+
throw new Error(`Error when parsing plist: ${error.message}`);
|
|
79
|
+
}
|
|
80
|
+
const applicationIdentifier = plistData.Entitlements['application-identifier'];
|
|
81
|
+
const bundleIdentifier = applicationIdentifier.replace(/^.+?\./, '');
|
|
82
|
+
this.profileData = {
|
|
83
|
+
path: this.profilePath,
|
|
84
|
+
target: this.target,
|
|
85
|
+
bundleIdentifier,
|
|
86
|
+
teamId: plistData.TeamIdentifier[0],
|
|
87
|
+
uuid: plistData.UUID,
|
|
88
|
+
name: plistData.Name,
|
|
89
|
+
developerCertificate: Buffer.from(plistData.DeveloperCertificates[0], 'base64'),
|
|
90
|
+
certificateCommonName: this.certificateCommonName,
|
|
91
|
+
distributionType: this.resolveDistributionType(plistData),
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
resolveDistributionType(plistData) {
|
|
95
|
+
if (plistData.ProvisionsAllDevices) {
|
|
96
|
+
return DistributionType.ENTERPRISE;
|
|
97
|
+
}
|
|
98
|
+
else if (plistData.ProvisionedDevices) {
|
|
99
|
+
return DistributionType.AD_HOC;
|
|
100
|
+
}
|
|
101
|
+
else {
|
|
102
|
+
return DistributionType.APP_STORE;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
genDerCertFingerprint() {
|
|
106
|
+
return crypto_1.default
|
|
107
|
+
.createHash('sha1')
|
|
108
|
+
.update(this.data.developerCertificate)
|
|
109
|
+
.digest('hex')
|
|
110
|
+
.toUpperCase();
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
exports.default = ProvisioningProfile;
|
|
114
|
+
//# sourceMappingURL=provisioningProfile.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provisioningProfile.js","sourceRoot":"","sources":["../../../../../src/steps/utils/ios/credentials/provisioningProfile.ts"],"names":[],"mappings":"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","sourcesContent":["import crypto from 'crypto';\nimport os from 'os';\nimport path from 'path';\n\nimport { errors } from '@expo/eas-build-job';\nimport spawn from '@expo/turtle-spawn';\nimport fs from 'fs-extra';\nimport plist from 'plist';\nimport { v4 as uuid } from 'uuid';\nimport { bunyan } from '@expo/logger';\n\nexport interface ProvisioningProfileData {\n path: string;\n target: string;\n bundleIdentifier: string;\n teamId: string;\n uuid: string;\n name: string;\n developerCertificate: Buffer;\n certificateCommonName: string;\n distributionType: DistributionType;\n}\n\nexport enum DistributionType {\n AD_HOC = 'ad-hoc',\n APP_STORE = 'app-store',\n ENTERPRISE = 'enterprise',\n}\n\nconst PROVISIONING_PROFILES_DIRECTORY = path.join(\n os.homedir(),\n 'Library/MobileDevice/Provisioning Profiles'\n);\n\nexport default class ProvisioningProfile {\n get data(): ProvisioningProfileData {\n if (!this.profileData) {\n throw new Error('You must init the profile first!');\n } else {\n return this.profileData;\n }\n }\n\n private readonly profilePath: string;\n private profileData?: ProvisioningProfileData;\n\n constructor(\n private readonly profile: Buffer,\n private readonly keychainPath: string,\n private readonly target: string,\n private readonly certificateCommonName: string\n ) {\n this.profilePath = path.join(PROVISIONING_PROFILES_DIRECTORY, `${uuid()}.mobileprovision`);\n }\n\n public async init(logger: bunyan): Promise<void> {\n logger.debug(`Making sure ${PROVISIONING_PROFILES_DIRECTORY} exits`);\n await fs.ensureDir(PROVISIONING_PROFILES_DIRECTORY);\n\n logger.debug(`Writing provisioning profile to ${this.profilePath}`);\n await fs.writeFile(this.profilePath, this.profile);\n\n logger.debug('Loading provisioning profile');\n await this.load();\n }\n\n public async destroy(logger: bunyan): Promise<void> {\n if (!this.profilePath) {\n logger.warn(\"There is nothing to destroy, a provisioning profile hasn't been created yet.\");\n return;\n }\n logger.info('Removing provisioning profile');\n await fs.remove(this.profilePath);\n }\n\n public verifyCertificate(fingerprint: string): void {\n const devCertFingerprint = this.genDerCertFingerprint();\n if (devCertFingerprint !== fingerprint) {\n throw new errors.CredentialsDistCertMismatchError(\n `Provisioning profile and distribution certificate don't match.\nProfile's certificate fingerprint = ${devCertFingerprint}, distribution certificate fingerprint = ${fingerprint}`\n );\n }\n }\n\n private async load(): Promise<void> {\n let result;\n try {\n result = await spawn(\n 'security',\n ['cms', '-D', '-k', this.keychainPath, '-i', this.profilePath],\n {\n stdio: 'pipe',\n }\n );\n } catch (err: any) {\n throw new Error(err.stderr.trim());\n }\n const { output } = result;\n\n const plistRaw = output.join('');\n let plistData;\n try {\n plistData = plist.parse(plistRaw) as plist.PlistObject;\n } catch (error: any) {\n throw new Error(`Error when parsing plist: ${error.message}`);\n }\n\n const applicationIdentifier = (plistData.Entitlements as plist.PlistObject)[\n 'application-identifier'\n ] as string;\n const bundleIdentifier = applicationIdentifier.replace(/^.+?\\./, '');\n\n this.profileData = {\n path: this.profilePath,\n target: this.target,\n bundleIdentifier,\n teamId: (plistData.TeamIdentifier as string[])[0],\n uuid: plistData.UUID as string,\n name: plistData.Name as string,\n developerCertificate: Buffer.from((plistData.DeveloperCertificates as string[])[0], 'base64'),\n certificateCommonName: this.certificateCommonName,\n distributionType: this.resolveDistributionType(plistData),\n };\n }\n\n private resolveDistributionType(plistData: plist.PlistObject): DistributionType {\n if (plistData.ProvisionsAllDevices) {\n return DistributionType.ENTERPRISE;\n } else if (plistData.ProvisionedDevices) {\n return DistributionType.AD_HOC;\n } else {\n return DistributionType.APP_STORE;\n }\n }\n\n private genDerCertFingerprint(): string {\n return crypto\n .createHash('sha1')\n .update(this.data.developerCertificate)\n .digest('hex')\n .toUpperCase();\n }\n}\n"]}
|
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
/// <reference types="bunyan" />
|
|
2
2
|
import { bunyan } from '@expo/logger';
|
|
3
3
|
import { Env } from '@expo/eas-build-job';
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
buildConfiguration?: string;
|
|
4
|
+
import { SpawnResult } from '@expo/turtle-spawn';
|
|
5
|
+
export declare function runFastlaneGym({ workingDir, logger, buildLogsDirectory, env, }: {
|
|
7
6
|
workingDir: string;
|
|
8
7
|
logger: bunyan;
|
|
9
8
|
buildLogsDirectory: string;
|
|
10
9
|
env: Env;
|
|
11
10
|
}): Promise<void>;
|
|
11
|
+
export declare function runFastlane(fastlaneArgs: string[], { logger, env, cwd, }?: {
|
|
12
|
+
logger?: bunyan;
|
|
13
|
+
env?: Record<string, string>;
|
|
14
|
+
cwd?: string;
|
|
15
|
+
}): Promise<SpawnResult>;
|
|
@@ -3,44 +3,15 @@ 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.runFastlaneGym = void 0;
|
|
6
|
+
exports.runFastlane = exports.runFastlaneGym = void 0;
|
|
7
7
|
const path_1 = __importDefault(require("path"));
|
|
8
|
-
const
|
|
9
|
-
const
|
|
10
|
-
|
|
11
|
-
const fastlane_1 = require("../../../ios/fastlane");
|
|
12
|
-
const tvos_1 = require("./tvos");
|
|
13
|
-
async function ensureGymfileExists({ logger, scheme, buildConfiguration, logsDirectory, workingDir, }) {
|
|
14
|
-
const gymfilePath = path_1.default.join(workingDir, 'ios/Gymfile');
|
|
15
|
-
if (await fs_extra_1.default.pathExists(gymfilePath)) {
|
|
16
|
-
logger.info('Gymfile already exists');
|
|
17
|
-
return;
|
|
18
|
-
}
|
|
19
|
-
const isTV = await (0, tvos_1.isTVOS)({ scheme, buildConfiguration, workingDir });
|
|
20
|
-
const simulatorDestination = `generic/platform=${isTV ? 'tvOS' : 'iOS'} Simulator`;
|
|
21
|
-
await (0, gymfile_1.createGymfileForSimulatorBuild)({
|
|
22
|
-
outputFile: gymfilePath,
|
|
23
|
-
scheme,
|
|
24
|
-
buildConfiguration: buildConfiguration !== null && buildConfiguration !== void 0 ? buildConfiguration : 'release',
|
|
25
|
-
derivedDataPath: './build',
|
|
26
|
-
clean: false,
|
|
27
|
-
logsDirectory,
|
|
28
|
-
simulatorDestination,
|
|
29
|
-
});
|
|
30
|
-
logger.info('Creating Gymfile');
|
|
31
|
-
}
|
|
32
|
-
async function runFastlaneGym({ scheme, buildConfiguration, workingDir, logger, buildLogsDirectory, env, }) {
|
|
33
|
-
await ensureGymfileExists({
|
|
34
|
-
scheme,
|
|
35
|
-
buildConfiguration: buildConfiguration !== null && buildConfiguration !== void 0 ? buildConfiguration : 'release',
|
|
36
|
-
logsDirectory: buildLogsDirectory,
|
|
37
|
-
workingDir,
|
|
38
|
-
logger,
|
|
39
|
-
});
|
|
8
|
+
const turtle_spawn_1 = __importDefault(require("@expo/turtle-spawn"));
|
|
9
|
+
const xcpretty_1 = require("./xcpretty");
|
|
10
|
+
async function runFastlaneGym({ workingDir, logger, buildLogsDirectory, env, }) {
|
|
40
11
|
const buildLogger = new xcpretty_1.XcodeBuildLogger(logger, workingDir);
|
|
41
12
|
void buildLogger.watchLogFiles(buildLogsDirectory);
|
|
42
13
|
try {
|
|
43
|
-
await
|
|
14
|
+
await runFastlane(['gym'], {
|
|
44
15
|
cwd: path_1.default.join(workingDir, 'ios'),
|
|
45
16
|
logger,
|
|
46
17
|
env,
|
|
@@ -51,4 +22,20 @@ async function runFastlaneGym({ scheme, buildConfiguration, workingDir, logger,
|
|
|
51
22
|
}
|
|
52
23
|
}
|
|
53
24
|
exports.runFastlaneGym = runFastlaneGym;
|
|
25
|
+
async function runFastlane(fastlaneArgs, { logger, env, cwd, } = {}) {
|
|
26
|
+
const fastlaneEnvVars = {
|
|
27
|
+
FASTLANE_DISABLE_COLORS: '1',
|
|
28
|
+
FASTLANE_SKIP_UPDATE_CHECK: '1',
|
|
29
|
+
SKIP_SLOW_FASTLANE_WARNING: 'true',
|
|
30
|
+
FASTLANE_HIDE_TIMESTAMP: 'true',
|
|
31
|
+
LC_ALL: 'en_US.UTF-8',
|
|
32
|
+
...(env !== null && env !== void 0 ? env : process.env),
|
|
33
|
+
};
|
|
34
|
+
return await (0, turtle_spawn_1.default)('fastlane', fastlaneArgs, {
|
|
35
|
+
env: fastlaneEnvVars,
|
|
36
|
+
logger,
|
|
37
|
+
cwd,
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
exports.runFastlane = runFastlane;
|
|
54
41
|
//# sourceMappingURL=fastlane.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fastlane.js","sourceRoot":"","sources":["../../../../src/steps/utils/ios/fastlane.ts"],"names":[],"mappings":";;;;;;AAAA,gDAAwB;
|
|
1
|
+
{"version":3,"file":"fastlane.js","sourceRoot":"","sources":["../../../../src/steps/utils/ios/fastlane.ts"],"names":[],"mappings":";;;;;;AAAA,gDAAwB;AAIxB,sEAAwD;AAExD,yCAA8C;AAEvC,KAAK,UAAU,cAAc,CAAC,EACnC,UAAU,EACV,MAAM,EACN,kBAAkB,EAClB,GAAG,GAMJ;IACC,MAAM,WAAW,GAAG,IAAI,2BAAgB,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IAC7D,KAAK,WAAW,CAAC,aAAa,CAAC,kBAAkB,CAAC,CAAC;IACnD,IAAI;QACF,MAAM,WAAW,CAAC,CAAC,KAAK,CAAC,EAAE;YACzB,GAAG,EAAE,cAAI,CAAC,IAAI,CAAC,UAAU,EAAE,KAAK,CAAC;YACjC,MAAM;YACN,GAAG;SACJ,CAAC,CAAC;KACJ;YAAS;QACR,MAAM,WAAW,CAAC,KAAK,EAAE,CAAC;KAC3B;AACH,CAAC;AAtBD,wCAsBC;AAEM,KAAK,UAAU,WAAW,CAC/B,YAAsB,EACtB,EACE,MAAM,EACN,GAAG,EACH,GAAG,MAKD,EAAE;IAEN,MAAM,eAAe,GAAG;QACtB,uBAAuB,EAAE,GAAG;QAC5B,0BAA0B,EAAE,GAAG;QAC/B,0BAA0B,EAAE,MAAM;QAClC,uBAAuB,EAAE,MAAM;QAC/B,MAAM,EAAE,aAAa;QACrB,GAAG,CAAC,GAAG,aAAH,GAAG,cAAH,GAAG,GAAI,OAAO,CAAC,GAAG,CAAC;KACxB,CAAC;IACF,OAAO,MAAM,IAAA,sBAAK,EAAC,UAAU,EAAE,YAAY,EAAE;QAC3C,GAAG,EAAE,eAAe;QACpB,MAAM;QACN,GAAG;KACJ,CAAC,CAAC;AACL,CAAC;AAzBD,kCAyBC","sourcesContent":["import path from 'path';\n\nimport { bunyan } from '@expo/logger';\nimport { Env } from '@expo/eas-build-job';\nimport spawn, { SpawnResult } from '@expo/turtle-spawn';\n\nimport { XcodeBuildLogger } from './xcpretty';\n\nexport async function runFastlaneGym({\n workingDir,\n logger,\n buildLogsDirectory,\n env,\n}: {\n workingDir: string;\n logger: bunyan;\n buildLogsDirectory: string;\n env: Env;\n}): Promise<void> {\n const buildLogger = new XcodeBuildLogger(logger, workingDir);\n void buildLogger.watchLogFiles(buildLogsDirectory);\n try {\n await runFastlane(['gym'], {\n cwd: path.join(workingDir, 'ios'),\n logger,\n env,\n });\n } finally {\n await buildLogger.flush();\n }\n}\n\nexport async function runFastlane(\n fastlaneArgs: string[],\n {\n logger,\n env,\n cwd,\n }: {\n logger?: bunyan;\n env?: Record<string, string>;\n cwd?: string;\n } = {}\n): Promise<SpawnResult> {\n const fastlaneEnvVars = {\n FASTLANE_DISABLE_COLORS: '1',\n FASTLANE_SKIP_UPDATE_CHECK: '1',\n SKIP_SLOW_FASTLANE_WARNING: 'true',\n FASTLANE_HIDE_TIMESTAMP: 'true',\n LC_ALL: 'en_US.UTF-8',\n ...(env ?? process.env),\n };\n return await spawn('fastlane', fastlaneArgs, {\n env: fastlaneEnvVars,\n logger,\n cwd,\n });\n}\n"]}
|
|
@@ -1,5 +1,3 @@
|
|
|
1
1
|
import { Ios } from '@expo/eas-build-job';
|
|
2
|
-
export declare function resolveScheme(job: Ios.Job,
|
|
3
|
-
|
|
4
|
-
}): string;
|
|
5
|
-
export declare function resolveBuildConfiguration(job: Ios.Job): string;
|
|
2
|
+
export declare function resolveScheme(workingDir: string, job: Ios.Job, scheme?: string): string;
|
|
3
|
+
export declare function resolveBuildConfiguration(job: Ios.Job, buildConfiguration?: string): string;
|
|
@@ -6,7 +6,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
exports.resolveBuildConfiguration = exports.resolveScheme = void 0;
|
|
7
7
|
const assert_1 = __importDefault(require("assert"));
|
|
8
8
|
const config_plugins_1 = require("@expo/config-plugins");
|
|
9
|
-
function resolveScheme(job,
|
|
9
|
+
function resolveScheme(workingDir, job, scheme) {
|
|
10
|
+
if (scheme) {
|
|
11
|
+
return scheme;
|
|
12
|
+
}
|
|
10
13
|
if (job.scheme) {
|
|
11
14
|
return job.scheme;
|
|
12
15
|
}
|
|
@@ -15,8 +18,11 @@ function resolveScheme(job, { workingDir }) {
|
|
|
15
18
|
return schemes[0];
|
|
16
19
|
}
|
|
17
20
|
exports.resolveScheme = resolveScheme;
|
|
18
|
-
function resolveBuildConfiguration(job) {
|
|
19
|
-
if (
|
|
21
|
+
function resolveBuildConfiguration(job, buildConfiguration) {
|
|
22
|
+
if (buildConfiguration) {
|
|
23
|
+
return buildConfiguration;
|
|
24
|
+
}
|
|
25
|
+
else if (job.buildConfiguration) {
|
|
20
26
|
return job.buildConfiguration;
|
|
21
27
|
}
|
|
22
28
|
else if (job.developmentClient) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolve.js","sourceRoot":"","sources":["../../../../src/steps/utils/ios/resolve.ts"],"names":[],"mappings":";;;;;;AAAA,oDAA4B;AAG5B,yDAAiD;AAEjD,SAAgB,aAAa,CAAC,GAAY,EAAE,EAAE,
|
|
1
|
+
{"version":3,"file":"resolve.js","sourceRoot":"","sources":["../../../../src/steps/utils/ios/resolve.ts"],"names":[],"mappings":";;;;;;AAAA,oDAA4B;AAG5B,yDAAiD;AAEjD,SAAgB,aAAa,CAAC,UAAkB,EAAE,GAAY,EAAE,MAAe;IAC7E,IAAI,MAAM,EAAE;QACV,OAAO,MAAM,CAAC;KACf;IACD,IAAI,GAAG,CAAC,MAAM,EAAE;QACd,OAAO,GAAG,CAAC,MAAM,CAAC;KACnB;IACD,MAAM,OAAO,GAAG,0BAAS,CAAC,WAAW,CAAC,uBAAuB,CAAC,UAAU,CAAC,CAAC;IAC1E,IAAA,gBAAM,EAAC,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,gDAAgD,CAAC,CAAC;IAC/E,OAAO,OAAO,CAAC,CAAC,CAAC,CAAC;AACpB,CAAC;AAVD,sCAUC;AAED,SAAgB,yBAAyB,CAAC,GAAY,EAAE,kBAA2B;IACjF,IAAI,kBAAkB,EAAE;QACtB,OAAO,kBAAkB,CAAC;KAC3B;SAAM,IAAI,GAAG,CAAC,kBAAkB,EAAE;QACjC,OAAO,GAAG,CAAC,kBAAkB,CAAC;KAC/B;SAAM,IAAI,GAAG,CAAC,iBAAiB,EAAE;QAChC,OAAO,OAAO,CAAC;KAChB;SAAM;QACL,OAAO,SAAS,CAAC;KAClB;AACH,CAAC;AAVD,8DAUC","sourcesContent":["import assert from 'assert';\n\nimport { Ios } from '@expo/eas-build-job';\nimport { IOSConfig } from '@expo/config-plugins';\n\nexport function resolveScheme(workingDir: string, job: Ios.Job, scheme?: string): string {\n if (scheme) {\n return scheme;\n }\n if (job.scheme) {\n return job.scheme;\n }\n const schemes = IOSConfig.BuildScheme.getSchemesFromXcodeproj(workingDir);\n assert(schemes.length === 1, 'Ejected project should have exactly one scheme');\n return schemes[0];\n}\n\nexport function resolveBuildConfiguration(job: Ios.Job, buildConfiguration?: string): string {\n if (buildConfiguration) {\n return buildConfiguration;\n } else if (job.buildConfiguration) {\n return job.buildConfiguration;\n } else if (job.developmentClient) {\n return 'Debug';\n } else {\n return 'Release';\n }\n}\n"]}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/// <reference types="bunyan" />
|
|
2
|
+
import { bunyan } from '@expo/logger';
|
|
3
|
+
export declare class XcodeBuildLogger {
|
|
4
|
+
private readonly logger;
|
|
5
|
+
private readonly projectRoot;
|
|
6
|
+
private loggerError?;
|
|
7
|
+
private flushing;
|
|
8
|
+
private logReaderPromise?;
|
|
9
|
+
private logsPath?;
|
|
10
|
+
constructor(logger: bunyan, projectRoot: string);
|
|
11
|
+
watchLogFiles(logsDirectory: string): Promise<void>;
|
|
12
|
+
flush(): Promise<void>;
|
|
13
|
+
private getBuildLogFilename;
|
|
14
|
+
private startBuildLogger;
|
|
15
|
+
private findBundlerErrors;
|
|
16
|
+
}
|
|
@@ -0,0 +1,88 @@
|
|
|
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.XcodeBuildLogger = void 0;
|
|
7
|
+
const assert_1 = __importDefault(require("assert"));
|
|
8
|
+
const path_1 = __importDefault(require("path"));
|
|
9
|
+
const fs_extra_1 = __importDefault(require("fs-extra"));
|
|
10
|
+
const xcpretty_1 = require("@expo/xcpretty");
|
|
11
|
+
const spawn_async_1 = __importDefault(require("@expo/spawn-async"));
|
|
12
|
+
const fast_glob_1 = __importDefault(require("fast-glob"));
|
|
13
|
+
const CHECK_FILE_INTERVAL_MS = 1000;
|
|
14
|
+
class XcodeBuildLogger {
|
|
15
|
+
constructor(logger, projectRoot) {
|
|
16
|
+
this.logger = logger;
|
|
17
|
+
this.projectRoot = projectRoot;
|
|
18
|
+
this.flushing = false;
|
|
19
|
+
}
|
|
20
|
+
async watchLogFiles(logsDirectory) {
|
|
21
|
+
while (!this.flushing) {
|
|
22
|
+
const logsFilename = await this.getBuildLogFilename(logsDirectory);
|
|
23
|
+
if (logsFilename) {
|
|
24
|
+
this.logsPath = path_1.default.join(logsDirectory, logsFilename);
|
|
25
|
+
void this.startBuildLogger(this.logsPath);
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
await new Promise((res) => setTimeout(res, CHECK_FILE_INTERVAL_MS));
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
async flush() {
|
|
32
|
+
this.flushing = true;
|
|
33
|
+
if (this.loggerError) {
|
|
34
|
+
throw this.loggerError;
|
|
35
|
+
}
|
|
36
|
+
if (this.logReaderPromise) {
|
|
37
|
+
this.logReaderPromise.child.kill('SIGINT');
|
|
38
|
+
try {
|
|
39
|
+
await this.logReaderPromise;
|
|
40
|
+
}
|
|
41
|
+
catch { }
|
|
42
|
+
}
|
|
43
|
+
if (this.logsPath) {
|
|
44
|
+
await this.findBundlerErrors(this.logsPath);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
async getBuildLogFilename(logsDirectory) {
|
|
48
|
+
const paths = await (0, fast_glob_1.default)('*.log', { cwd: logsDirectory });
|
|
49
|
+
return paths.length >= 1 ? paths[0] : undefined;
|
|
50
|
+
}
|
|
51
|
+
async startBuildLogger(logsPath) {
|
|
52
|
+
try {
|
|
53
|
+
const formatter = xcpretty_1.ExpoRunFormatter.create(this.projectRoot, {
|
|
54
|
+
// TODO: Can provide xcode project name for better parsing
|
|
55
|
+
isDebug: false,
|
|
56
|
+
});
|
|
57
|
+
this.logReaderPromise = (0, spawn_async_1.default)('tail', ['-n', '+0', '-f', logsPath], { stdio: 'pipe' });
|
|
58
|
+
(0, assert_1.default)(this.logReaderPromise.child.stdout, 'stdout is not available');
|
|
59
|
+
this.logReaderPromise.child.stdout.on('data', (data) => {
|
|
60
|
+
const lines = formatter.pipe(data.toString());
|
|
61
|
+
for (const line of lines) {
|
|
62
|
+
this.logger.info(line);
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
await this.logReaderPromise;
|
|
66
|
+
this.logger.info(formatter.getBuildSummary());
|
|
67
|
+
}
|
|
68
|
+
catch (err) {
|
|
69
|
+
if (!this.flushing) {
|
|
70
|
+
this.loggerError = err;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
async findBundlerErrors(logsPath) {
|
|
75
|
+
try {
|
|
76
|
+
const logFile = await fs_extra_1.default.readFile(logsPath, 'utf-8');
|
|
77
|
+
const match = logFile.match(/Welcome to Metro!\s* Fast - Scalable - Integrated\s*([\s\S]*)Run CLI with --verbose flag for more details.\nCommand PhaseScriptExecution failed with a nonzero exit code/);
|
|
78
|
+
if (match) {
|
|
79
|
+
this.logger.info(match[1]);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
catch (err) {
|
|
83
|
+
this.logger.error({ err }, 'Failed to read Xcode logs');
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
exports.XcodeBuildLogger = XcodeBuildLogger;
|
|
88
|
+
//# sourceMappingURL=xcpretty.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"xcpretty.js","sourceRoot":"","sources":["../../../../src/steps/utils/ios/xcpretty.ts"],"names":[],"mappings":";;;;;;AAAA,oDAA4B;AAC5B,gDAAwB;AAExB,wDAA0B;AAE1B,6CAAkD;AAClD,oEAA0E;AAC1E,0DAA2B;AAE3B,MAAM,sBAAsB,GAAG,IAAI,CAAC;AAEpC,MAAa,gBAAgB;IAM3B,YAA6B,MAAc,EAAmB,WAAmB;QAApD,WAAM,GAAN,MAAM,CAAQ;QAAmB,gBAAW,GAAX,WAAW,CAAQ;QAJzE,aAAQ,GAAY,KAAK,CAAC;IAIkD,CAAC;IAE9E,KAAK,CAAC,aAAa,CAAC,aAAqB;QAC9C,OAAO,CAAC,IAAI,CAAC,QAAQ,EAAE;YACrB,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,mBAAmB,CAAC,aAAa,CAAC,CAAC;YACnE,IAAI,YAAY,EAAE;gBAChB,IAAI,CAAC,QAAQ,GAAG,cAAI,CAAC,IAAI,CAAC,aAAa,EAAE,YAAY,CAAC,CAAC;gBACvD,KAAK,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;gBAC1C,OAAO;aACR;YACD,MAAM,IAAI,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,UAAU,CAAC,GAAG,EAAE,sBAAsB,CAAC,CAAC,CAAC;SACrE;IACH,CAAC;IAEM,KAAK,CAAC,KAAK;QAChB,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;QACrB,IAAI,IAAI,CAAC,WAAW,EAAE;YACpB,MAAM,IAAI,CAAC,WAAW,CAAC;SACxB;QACD,IAAI,IAAI,CAAC,gBAAgB,EAAE;YACzB,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YAC3C,IAAI;gBACF,MAAM,IAAI,CAAC,gBAAgB,CAAC;aAC7B;YAAC,MAAM,GAAE;SACX;QACD,IAAI,IAAI,CAAC,QAAQ,EAAE;YACjB,MAAM,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;SAC7C;IACH,CAAC;IACO,KAAK,CAAC,mBAAmB,CAAC,aAAqB;QACrD,MAAM,KAAK,GAAG,MAAM,IAAA,mBAAE,EAAC,OAAO,EAAE,EAAE,GAAG,EAAE,aAAa,EAAE,CAAC,CAAC;QACxD,OAAO,KAAK,CAAC,MAAM,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAClD,CAAC;IAEO,KAAK,CAAC,gBAAgB,CAAC,QAAgB;QAC7C,IAAI;YACF,MAAM,SAAS,GAAG,2BAAgB,CAAC,MAAM,CAAC,IAAI,CAAC,WAAW,EAAE;gBAC1D,0DAA0D;gBAC1D,OAAO,EAAE,KAAK;aACf,CAAC,CAAC;YACH,IAAI,CAAC,gBAAgB,GAAG,IAAA,qBAAU,EAAC,MAAM,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,CAAC,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;YAC5F,IAAA,gBAAM,EAAC,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC,MAAM,EAAE,yBAAyB,CAAC,CAAC;YACtE,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAY,EAAE,EAAE;gBAC7D,MAAM,KAAK,GAAG,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;gBAC9C,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE;oBACxB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;iBACxB;YACH,CAAC,CAAC,CAAC;YACH,MAAM,IAAI,CAAC,gBAAgB,CAAC;YAE5B,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,eAAe,EAAE,CAAC,CAAC;SAC/C;QAAC,OAAO,GAAQ,EAAE;YACjB,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE;gBAClB,IAAI,CAAC,WAAW,GAAG,GAAG,CAAC;aACxB;SACF;IACH,CAAC;IAEO,KAAK,CAAC,iBAAiB,CAAC,QAAgB;QAC9C,IAAI;YACF,MAAM,OAAO,GAAG,MAAM,kBAAE,CAAC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;YACrD,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CACzB,0KAA0K,CAC3K,CAAC;YACF,IAAI,KAAK,EAAE;gBACT,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;aAC5B;SACF;QAAC,OAAO,GAAG,EAAE;YACZ,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,EAAE,2BAA2B,CAAC,CAAC;SACzD;IACH,CAAC;CACF;AA7ED,4CA6EC","sourcesContent":["import assert from 'assert';\nimport path from 'path';\n\nimport fs from 'fs-extra';\nimport { bunyan } from '@expo/logger';\nimport { ExpoRunFormatter } from '@expo/xcpretty';\nimport spawnAsync, { SpawnPromise, SpawnResult } from '@expo/spawn-async';\nimport fg from 'fast-glob';\n\nconst CHECK_FILE_INTERVAL_MS = 1000;\n\nexport class XcodeBuildLogger {\n private loggerError?: Error;\n private flushing: boolean = false;\n private logReaderPromise?: SpawnPromise<SpawnResult>;\n private logsPath?: string;\n\n constructor(private readonly logger: bunyan, private readonly projectRoot: string) {}\n\n public async watchLogFiles(logsDirectory: string): Promise<void> {\n while (!this.flushing) {\n const logsFilename = await this.getBuildLogFilename(logsDirectory);\n if (logsFilename) {\n this.logsPath = path.join(logsDirectory, logsFilename);\n void this.startBuildLogger(this.logsPath);\n return;\n }\n await new Promise((res) => setTimeout(res, CHECK_FILE_INTERVAL_MS));\n }\n }\n\n public async flush(): Promise<void> {\n this.flushing = true;\n if (this.loggerError) {\n throw this.loggerError;\n }\n if (this.logReaderPromise) {\n this.logReaderPromise.child.kill('SIGINT');\n try {\n await this.logReaderPromise;\n } catch {}\n }\n if (this.logsPath) {\n await this.findBundlerErrors(this.logsPath);\n }\n }\n private async getBuildLogFilename(logsDirectory: string): Promise<string | undefined> {\n const paths = await fg('*.log', { cwd: logsDirectory });\n return paths.length >= 1 ? paths[0] : undefined;\n }\n\n private async startBuildLogger(logsPath: string): Promise<void> {\n try {\n const formatter = ExpoRunFormatter.create(this.projectRoot, {\n // TODO: Can provide xcode project name for better parsing\n isDebug: false,\n });\n this.logReaderPromise = spawnAsync('tail', ['-n', '+0', '-f', logsPath], { stdio: 'pipe' });\n assert(this.logReaderPromise.child.stdout, 'stdout is not available');\n this.logReaderPromise.child.stdout.on('data', (data: string) => {\n const lines = formatter.pipe(data.toString());\n for (const line of lines) {\n this.logger.info(line);\n }\n });\n await this.logReaderPromise;\n\n this.logger.info(formatter.getBuildSummary());\n } catch (err: any) {\n if (!this.flushing) {\n this.loggerError = err;\n }\n }\n }\n\n private async findBundlerErrors(logsPath: string): Promise<void> {\n try {\n const logFile = await fs.readFile(logsPath, 'utf-8');\n const match = logFile.match(\n /Welcome to Metro!\\s* Fast - Scalable - Integrated\\s*([\\s\\S]*)Run CLI with --verbose flag for more details.\\nCommand PhaseScriptExecution failed with a nonzero exit code/\n );\n if (match) {\n this.logger.info(match[1]);\n }\n } catch (err) {\n this.logger.error({ err }, 'Failed to read Xcode logs');\n }\n }\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@expo/build-tools",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.36",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"types": "dist/index.d.ts",
|
|
6
6
|
"files": [
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
"@expo/logger": "1.0.30",
|
|
29
29
|
"@expo/package-manager": "^1.0.2",
|
|
30
30
|
"@expo/plist": "^0.0.20",
|
|
31
|
-
"@expo/steps": "1.0.
|
|
31
|
+
"@expo/steps": "1.0.34",
|
|
32
32
|
"@expo/template-file": "1.0.30",
|
|
33
33
|
"@expo/turtle-spawn": "1.0.30",
|
|
34
34
|
"@expo/xcpretty": "^4.2.2",
|
|
@@ -65,5 +65,5 @@
|
|
|
65
65
|
"node": "18.13.0",
|
|
66
66
|
"yarn": "1.22.19"
|
|
67
67
|
},
|
|
68
|
-
"gitHead": "
|
|
68
|
+
"gitHead": "099bde714a075f1a5289511acc7dd626516f4011"
|
|
69
69
|
}
|