@expo/build-tools 20.4.0 → 21.0.0
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/android/gradle.d.ts +5 -0
- package/dist/android/gradle.js +13 -33
- package/dist/common/installDependencies.js +21 -18
- package/dist/common/projectSources.js +1 -1
- package/dist/context.d.ts +2 -2
- package/dist/context.js +31 -1
- package/dist/ios/fastlane.d.ts +1 -1
- package/dist/steps/easFunctions.js +18 -0
- package/dist/steps/functions/capturePosthogEvent.d.ts +2 -0
- package/dist/steps/functions/capturePosthogEvent.js +79 -0
- package/dist/steps/functions/createPosthogAnnotation.d.ts +2 -0
- package/dist/steps/functions/createPosthogAnnotation.js +75 -0
- package/dist/steps/functions/createSubmissionEntity.js +25 -1
- package/dist/steps/functions/downloadArtifact.js +13 -3
- package/dist/steps/functions/finishIosSimulatorRecordings.d.ts +2 -0
- package/dist/steps/functions/finishIosSimulatorRecordings.js +24 -0
- package/dist/steps/functions/repack.js +12 -7
- package/dist/steps/functions/restoreCache.js +2 -1
- package/dist/steps/functions/rolloutPosthogFlag.d.ts +2 -0
- package/dist/steps/functions/rolloutPosthogFlag.js +208 -0
- package/dist/steps/functions/saveCache.js +3 -2
- package/dist/steps/functions/startAgentDeviceRemoteSession.js +21 -8
- package/dist/steps/functions/startArgentRemoteSession.d.ts +14 -0
- package/dist/steps/functions/startArgentRemoteSession.js +105 -44
- package/dist/steps/functions/startIosSimulator.js +19 -0
- package/dist/steps/functions/startIosSimulatorRecordings.d.ts +2 -0
- package/dist/steps/functions/startIosSimulatorRecordings.js +20 -0
- package/dist/steps/functions/startServeSimRemoteSession.js +7 -5
- package/dist/steps/functions/uploadDeviceRunSessionScreenRecordings.d.ts +3 -0
- package/dist/steps/functions/uploadDeviceRunSessionScreenRecordings.js +91 -0
- package/dist/steps/functions/uploadPosthogSourcemaps.d.ts +2 -0
- package/dist/steps/functions/uploadPosthogSourcemaps.js +83 -0
- package/dist/steps/functions/waitForPosthogMetric.d.ts +2 -0
- package/dist/steps/functions/waitForPosthogMetric.js +135 -0
- package/dist/steps/functions/waitForPosthogQuery.d.ts +2 -0
- package/dist/steps/functions/waitForPosthogQuery.js +95 -0
- package/dist/steps/utils/IosSimulatorRecordingUtils.d.ts +17 -0
- package/dist/steps/utils/IosSimulatorRecordingUtils.js +218 -0
- package/dist/steps/utils/PosthogClient.d.ts +46 -0
- package/dist/steps/utils/PosthogClient.js +156 -0
- package/dist/steps/utils/PosthogUtils.d.ts +41 -0
- package/dist/steps/utils/PosthogUtils.js +65 -0
- package/dist/steps/utils/agentDeviceArtifacts.d.ts +27 -0
- package/dist/steps/utils/agentDeviceArtifacts.js +133 -0
- package/dist/steps/utils/android/gradle.d.ts +5 -0
- package/dist/steps/utils/android/gradle.js +13 -62
- package/dist/steps/utils/argentArtifacts.d.ts +5 -3
- package/dist/steps/utils/argentArtifacts.js +95 -23
- package/dist/steps/utils/deviceRunSessionArtifacts.d.ts +3 -1
- package/dist/steps/utils/deviceRunSessionArtifacts.js +6 -2
- package/dist/steps/utils/remoteDeviceRunSession.d.ts +8 -0
- package/dist/steps/utils/remoteDeviceRunSession.js +62 -1
- package/dist/utils/AndroidEmulatorUtils.js +3 -0
- package/dist/utils/IosSimulatorUtils.d.ts +5 -0
- package/dist/utils/IosSimulatorUtils.js +81 -2
- package/dist/utils/expoUpdates.js +6 -1
- package/dist/utils/expoUpdatesEmbedded.js +4 -0
- package/dist/utils/processes.d.ts +1 -0
- package/dist/utils/processes.js +23 -0
- package/package.json +9 -8
- package/resources/record-sim/Package.swift +28 -0
- package/resources/record-sim/README.md +79 -0
- package/resources/record-sim/Sources/RecordSim/FramebufferDisplaySource.swift +192 -0
- package/resources/record-sim/Sources/RecordSim/PrivateSimulatorServices.swift +96 -0
- package/resources/record-sim/Sources/RecordSim/RecordingModels.swift +70 -0
- package/resources/record-sim/Sources/RecordSim/RecordingOutputWriter.swift +136 -0
- package/resources/record-sim/Sources/RecordSim/SimulatorRecorder.swift +632 -0
- package/resources/record-sim/Sources/RecordSim/Utilities.swift +60 -0
- package/resources/record-sim/Sources/record-sim/main.swift +143 -0
package/dist/android/gradle.d.ts
CHANGED
|
@@ -8,4 +8,9 @@ export declare function runGradleCommand(ctx: BuildContext<Job>, { logger, gradl
|
|
|
8
8
|
androidDir: string;
|
|
9
9
|
extraEnv?: Env;
|
|
10
10
|
}): Promise<void>;
|
|
11
|
+
export declare function getGradleShellCommand({ gradleCommand, oomScoreAdj, verboseFlag, }: {
|
|
12
|
+
gradleCommand: string;
|
|
13
|
+
oomScoreAdj?: number;
|
|
14
|
+
verboseFlag: string;
|
|
15
|
+
}): string;
|
|
11
16
|
export declare function resolveGradleCommand(job: Android.Job): string;
|
package/dist/android/gradle.js
CHANGED
|
@@ -5,13 +5,12 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.ensureLFLineEndingsInGradlewScript = ensureLFLineEndingsInGradlewScript;
|
|
7
7
|
exports.runGradleCommand = runGradleCommand;
|
|
8
|
+
exports.getGradleShellCommand = getGradleShellCommand;
|
|
8
9
|
exports.resolveGradleCommand = resolveGradleCommand;
|
|
9
10
|
const eas_build_job_1 = require("@expo/eas-build-job");
|
|
10
11
|
const turtle_spawn_1 = __importDefault(require("@expo/turtle-spawn"));
|
|
11
|
-
const assert_1 = __importDefault(require("assert"));
|
|
12
12
|
const fs_extra_1 = __importDefault(require("fs-extra"));
|
|
13
13
|
const path_1 = __importDefault(require("path"));
|
|
14
|
-
const processes_1 = require("../utils/processes");
|
|
15
14
|
async function ensureLFLineEndingsInGradlewScript(ctx) {
|
|
16
15
|
const gradlewPath = path_1.default.join(ctx.getReactNativeProjectDirectory(), 'android', 'gradlew');
|
|
17
16
|
const gradlewContent = await fs_extra_1.default.readFile(gradlewPath, 'utf8');
|
|
@@ -24,7 +23,15 @@ async function runGradleCommand(ctx, { logger, gradleCommand, androidDir, extraE
|
|
|
24
23
|
logger.info(`Running 'gradlew ${gradleCommand}' in ${androidDir}`);
|
|
25
24
|
await fs_extra_1.default.chmod(path_1.default.join(androidDir, 'gradlew'), 0o755);
|
|
26
25
|
const verboseFlag = ctx.env['EAS_VERBOSE'] === '1' ? '--info' : '';
|
|
27
|
-
const
|
|
26
|
+
const shouldResetOOMScore = ctx.env.EAS_BUILD_RUNNER === 'eas-build' && process.platform === 'linux';
|
|
27
|
+
await (0, turtle_spawn_1.default)('bash', [
|
|
28
|
+
'-c',
|
|
29
|
+
getGradleShellCommand({
|
|
30
|
+
gradleCommand,
|
|
31
|
+
oomScoreAdj: shouldResetOOMScore ? 0 : undefined,
|
|
32
|
+
verboseFlag,
|
|
33
|
+
}),
|
|
34
|
+
], {
|
|
28
35
|
cwd: androidDir,
|
|
29
36
|
logger,
|
|
30
37
|
lineTransformer: (line) => {
|
|
@@ -42,37 +49,10 @@ async function runGradleCommand(ctx, { logger, gradleCommand, androidDir, extraE
|
|
|
42
49
|
LC_ALL: 'C.UTF-8',
|
|
43
50
|
},
|
|
44
51
|
});
|
|
45
|
-
if (ctx.env.EAS_BUILD_RUNNER === 'eas-build' && process.platform === 'linux') {
|
|
46
|
-
adjustOOMScore(spawnPromise, logger);
|
|
47
|
-
}
|
|
48
|
-
await spawnPromise;
|
|
49
52
|
}
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
* It defines which process is more likely to get killed (higher value more likely).
|
|
54
|
-
*
|
|
55
|
-
* This function sets oom_score_adj for Gradle process and all its child processes.
|
|
56
|
-
*/
|
|
57
|
-
function adjustOOMScore(spawnPromise, logger) {
|
|
58
|
-
setTimeout(async () => {
|
|
59
|
-
try {
|
|
60
|
-
(0, assert_1.default)(spawnPromise.child.pid);
|
|
61
|
-
const pids = await (0, processes_1.getParentAndDescendantProcessPidsAsync)(spawnPromise.child.pid);
|
|
62
|
-
await Promise.all(pids.map(async (pid) => {
|
|
63
|
-
// Value 800 is just a guess here. It's probably higher than most other
|
|
64
|
-
// process. I didn't want to set it any higher, because I'm not sure if OOM Killer
|
|
65
|
-
// can start killing processes when there is still enough memory left.
|
|
66
|
-
const oomScoreOverride = 800;
|
|
67
|
-
await fs_extra_1.default.writeFile(`/proc/${pid}/oom_score_adj`, `${oomScoreOverride}\n`);
|
|
68
|
-
}));
|
|
69
|
-
}
|
|
70
|
-
catch (err) {
|
|
71
|
-
logger.debug({ err, stderr: err?.stderr }, 'Failed to override oom_score_adj');
|
|
72
|
-
}
|
|
73
|
-
},
|
|
74
|
-
// Wait 20 seconds to make sure all child processes are started
|
|
75
|
-
20000);
|
|
53
|
+
function getGradleShellCommand({ gradleCommand, oomScoreAdj, verboseFlag, }) {
|
|
54
|
+
const oomScoreAdjPrefix = oomScoreAdj === undefined ? '' : `echo ${oomScoreAdj} > /proc/$$/oom_score_adj || true; `;
|
|
55
|
+
return `${oomScoreAdjPrefix}exec ./gradlew ${gradleCommand} --profile ${verboseFlag}`;
|
|
76
56
|
}
|
|
77
57
|
// Version envs should be set at the beginning of the build, but when building
|
|
78
58
|
// from github those values are resolved later.
|
|
@@ -69,17 +69,29 @@ async function installDependenciesAsync({ packageManager, env, logger, infoCallb
|
|
|
69
69
|
};
|
|
70
70
|
}
|
|
71
71
|
async function installDependenciesWithNpmCacheFallbackAsync({ packageManager, env, logger, infoCallbackFn, cwd, useFrozenLockfile, }) {
|
|
72
|
-
const npmCacheUrl = env.
|
|
72
|
+
const npmCacheUrl = env.EAS_BUILD_NPM_CACHE_URL;
|
|
73
|
+
if (!npmCacheUrl) {
|
|
74
|
+
await (await installDependenciesAsync({
|
|
75
|
+
packageManager,
|
|
76
|
+
env,
|
|
77
|
+
logger,
|
|
78
|
+
infoCallbackFn,
|
|
79
|
+
cwd,
|
|
80
|
+
useFrozenLockfile,
|
|
81
|
+
})).spawnPromise;
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
logger.info(`Installing dependencies using the npm cache registry (${npmCacheUrl}).`);
|
|
73
85
|
let firstErrorLine;
|
|
74
86
|
let errorLineCount = 0;
|
|
75
87
|
try {
|
|
76
88
|
await (await installDependenciesAsync({
|
|
77
89
|
packageManager,
|
|
78
|
-
env,
|
|
90
|
+
env: { ...env, NPM_CONFIG_REGISTRY: npmCacheUrl },
|
|
79
91
|
logger,
|
|
80
92
|
infoCallbackFn,
|
|
81
93
|
lineTransformer: (line) => {
|
|
82
|
-
if (isNpmCacheRegistryErrorLine(line,
|
|
94
|
+
if (isNpmCacheRegistryErrorLine(line, npmCacheUrl)) {
|
|
83
95
|
firstErrorLine ??= line;
|
|
84
96
|
errorLineCount += 1;
|
|
85
97
|
}
|
|
@@ -97,7 +109,7 @@ async function installDependenciesWithNpmCacheFallbackAsync({ packageManager, en
|
|
|
97
109
|
}
|
|
98
110
|
}
|
|
99
111
|
catch (err) {
|
|
100
|
-
if (!isNpmCacheInstallFailure(err,
|
|
112
|
+
if (!isNpmCacheInstallFailure(err, npmCacheUrl)) {
|
|
101
113
|
throw err;
|
|
102
114
|
}
|
|
103
115
|
logger.warn(`Failed to install dependencies using the npm cache registry (${npmCacheUrl}). Retrying without the npm cache registry.`);
|
|
@@ -113,10 +125,9 @@ async function installDependenciesWithNpmCacheFallbackAsync({ packageManager, en
|
|
|
113
125
|
signal: err instanceof Error ? err.signal : undefined,
|
|
114
126
|
},
|
|
115
127
|
});
|
|
116
|
-
const { NPM_CONFIG_REGISTRY: _NPM_CONFIG_REGISTRY, ...fallbackEnv } = env;
|
|
117
128
|
await (await installDependenciesAsync({
|
|
118
129
|
packageManager,
|
|
119
|
-
env
|
|
130
|
+
env,
|
|
120
131
|
logger,
|
|
121
132
|
infoCallbackFn,
|
|
122
133
|
cwd,
|
|
@@ -132,21 +143,13 @@ function resolvePackagerDir(ctx) {
|
|
|
132
143
|
}
|
|
133
144
|
return packagerRunDir;
|
|
134
145
|
}
|
|
135
|
-
function isNpmCacheInstallFailure(err,
|
|
136
|
-
|
|
137
|
-
return false;
|
|
138
|
-
}
|
|
139
|
-
const errorOutput = getErrorOutput(err);
|
|
140
|
-
return errorOutput.includes(npmCacheUrl);
|
|
146
|
+
function isNpmCacheInstallFailure(err, npmCacheUrl) {
|
|
147
|
+
return getErrorOutput(err).includes(npmCacheUrl);
|
|
141
148
|
}
|
|
142
|
-
function isNpmCacheRegistryErrorLine(line,
|
|
143
|
-
return (
|
|
144
|
-
line.includes(npmCacheUrl) &&
|
|
149
|
+
function isNpmCacheRegistryErrorLine(line, npmCacheUrl) {
|
|
150
|
+
return (line.includes(npmCacheUrl) &&
|
|
145
151
|
/(?:error|failed|ENOTFOUND|ECONN|ETIMEDOUT|EAI_AGAIN|FetchError)/i.test(line));
|
|
146
152
|
}
|
|
147
|
-
function isNpmCacheRegistryEnabled(env, npmCacheUrl) {
|
|
148
|
-
return env.EAS_USE_NPM_CACHE === '1' && !!npmCacheUrl;
|
|
149
|
-
}
|
|
150
153
|
function getErrorOutput(err) {
|
|
151
154
|
if (!(err instanceof Error)) {
|
|
152
155
|
return '';
|
|
@@ -169,7 +169,7 @@ async function uploadProjectMetadataAsync(ctx, { projectDirectory }) {
|
|
|
169
169
|
}
|
|
170
170
|
}
|
|
171
171
|
`), {
|
|
172
|
-
buildId: ctx.env.EAS_BUILD_ID,
|
|
172
|
+
buildId: (0, nullthrows_1.default)(ctx.env.EAS_BUILD_ID, 'EAS_BUILD_ID is not set'),
|
|
173
173
|
projectMetadataFile: {
|
|
174
174
|
type: 'GCS',
|
|
175
175
|
bucketKey: uploadSession.bucketKey,
|
package/dist/context.d.ts
CHANGED
|
@@ -43,7 +43,7 @@ export interface BuildContextOptions {
|
|
|
43
43
|
}>;
|
|
44
44
|
reportError?: (msg: string, err?: Error, options?: {
|
|
45
45
|
tags?: Record<string, string>;
|
|
46
|
-
extras?: Record<string, string>;
|
|
46
|
+
extras?: Record<string, string | undefined>;
|
|
47
47
|
}) => void;
|
|
48
48
|
skipNativeBuild?: boolean;
|
|
49
49
|
metadata?: Metadata;
|
|
@@ -58,7 +58,7 @@ export declare class BuildContext<TJob extends Job = Job> {
|
|
|
58
58
|
readonly cacheManager?: CacheManager;
|
|
59
59
|
readonly reportError?: (msg: string, err?: Error, options?: {
|
|
60
60
|
tags?: Record<string, string>;
|
|
61
|
-
extras?: Record<string, string>;
|
|
61
|
+
extras?: Record<string, string | undefined>;
|
|
62
62
|
}) => void;
|
|
63
63
|
readonly skipNativeBuild?: boolean;
|
|
64
64
|
readonly expoApiV2BaseUrl?: string;
|
package/dist/context.js
CHANGED
|
@@ -17,6 +17,26 @@ const packageManager_1 = require("./utils/packageManager");
|
|
|
17
17
|
class SkipNativeBuildError extends Error {
|
|
18
18
|
}
|
|
19
19
|
exports.SkipNativeBuildError = SkipNativeBuildError;
|
|
20
|
+
function logEnvComparison({ oldMergeOrderEnv, newMergeOrderEnv, }) {
|
|
21
|
+
const envNames = new Set([...Object.keys(oldMergeOrderEnv), ...Object.keys(newMergeOrderEnv)]);
|
|
22
|
+
const sameEnvNames = [];
|
|
23
|
+
const differentEnvNames = [];
|
|
24
|
+
for (const key of envNames) {
|
|
25
|
+
const hasOldValue = key in oldMergeOrderEnv;
|
|
26
|
+
const hasNewValue = key in newMergeOrderEnv;
|
|
27
|
+
if (hasOldValue === hasNewValue && oldMergeOrderEnv[key] === newMergeOrderEnv[key]) {
|
|
28
|
+
sameEnvNames.push(key);
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
differentEnvNames.push(key);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
if (differentEnvNames.length === 0) {
|
|
35
|
+
datadog_1.Datadog.log('BuildContext.updateEnv merge order produced same env');
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
datadog_1.Datadog.log(`BuildContext.updateEnv merge order produced different env: compared_env_count=${envNames.size} different_env_count=${differentEnvNames.length} different_env_names=${differentEnvNames.join(',')} same_env_count=${sameEnvNames.length} same_env_names=${sameEnvNames.join(',')}`);
|
|
39
|
+
}
|
|
20
40
|
class BuildContext {
|
|
21
41
|
workingdir;
|
|
22
42
|
logger;
|
|
@@ -157,11 +177,21 @@ class BuildContext {
|
|
|
157
177
|
if (this._job.triggeredBy !== common_1.BuildTrigger.GIT_BASED_INTEGRATION) {
|
|
158
178
|
throw new Error('Updating environment variables is only allowed when build was triggered by a git-based integration.');
|
|
159
179
|
}
|
|
160
|
-
|
|
180
|
+
const oldMergeOrderEnv = {
|
|
161
181
|
...env,
|
|
162
182
|
...this._env,
|
|
163
183
|
__EAS_BUILD_ENVS_DIR: this.buildEnvsDirectory,
|
|
164
184
|
};
|
|
185
|
+
const newMergeOrderEnv = {
|
|
186
|
+
...this._env,
|
|
187
|
+
...env,
|
|
188
|
+
__EAS_BUILD_ENVS_DIR: this.buildEnvsDirectory,
|
|
189
|
+
};
|
|
190
|
+
logEnvComparison({
|
|
191
|
+
oldMergeOrderEnv,
|
|
192
|
+
newMergeOrderEnv,
|
|
193
|
+
});
|
|
194
|
+
this._env = newMergeOrderEnv;
|
|
165
195
|
this._env.PATH = this._env.PATH
|
|
166
196
|
? [this.buildExecutablesDirectory, this._env.PATH].join(':')
|
|
167
197
|
: this.buildExecutablesDirectory;
|
package/dist/ios/fastlane.d.ts
CHANGED
|
@@ -19,6 +19,6 @@ export declare function runFastlaneResign<TJob extends Ios.Job>(ctx: BuildContex
|
|
|
19
19
|
}): Promise<void>;
|
|
20
20
|
export declare function runFastlane(fastlaneArgs: string[], { logger, env, cwd, }?: {
|
|
21
21
|
logger?: bunyan;
|
|
22
|
-
env?:
|
|
22
|
+
env?: Env;
|
|
23
23
|
cwd?: string;
|
|
24
24
|
}): Promise<SpawnResult>;
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.getEasFunctions = getEasFunctions;
|
|
4
4
|
const calculateEASUpdateRuntimeVersion_1 = require("./functions/calculateEASUpdateRuntimeVersion");
|
|
5
|
+
const capturePosthogEvent_1 = require("./functions/capturePosthogEvent");
|
|
5
6
|
const checkout_1 = require("./functions/checkout");
|
|
6
7
|
const configureAndroidVersion_1 = require("./functions/configureAndroidVersion");
|
|
7
8
|
const configureEASUpdateIfInstalled_1 = require("./functions/configureEASUpdateIfInstalled");
|
|
@@ -14,6 +15,7 @@ const deploy_1 = require("./functions/deploy");
|
|
|
14
15
|
const export_1 = require("./functions/export");
|
|
15
16
|
const eagerBundle_1 = require("./functions/eagerBundle");
|
|
16
17
|
const findAndUploadBuildArtifacts_1 = require("./functions/findAndUploadBuildArtifacts");
|
|
18
|
+
const finishIosSimulatorRecordings_1 = require("./functions/finishIosSimulatorRecordings");
|
|
17
19
|
const generateGymfileFromTemplate_1 = require("./functions/generateGymfileFromTemplate");
|
|
18
20
|
const getCredentialsForBuildTriggeredByGitHubIntegration_1 = require("./functions/getCredentialsForBuildTriggeredByGitHubIntegration");
|
|
19
21
|
const injectAndroidCredentials_1 = require("./functions/injectAndroidCredentials");
|
|
@@ -35,6 +37,7 @@ const runFastlane_1 = require("./functions/runFastlane");
|
|
|
35
37
|
const runGradle_1 = require("./functions/runGradle");
|
|
36
38
|
const maestroTests_1 = require("./functions/maestroTests");
|
|
37
39
|
const saveBuildCache_1 = require("./functions/saveBuildCache");
|
|
40
|
+
const rolloutPosthogFlag_1 = require("./functions/rolloutPosthogFlag");
|
|
38
41
|
const saveCache_1 = require("./functions/saveCache");
|
|
39
42
|
const sendSlackMessage_1 = require("./functions/sendSlackMessage");
|
|
40
43
|
const startAgentDeviceRemoteSession_1 = require("./functions/startAgentDeviceRemoteSession");
|
|
@@ -42,10 +45,16 @@ const startAndroidEmulator_1 = require("./functions/startAndroidEmulator");
|
|
|
42
45
|
const startArgentRemoteSession_1 = require("./functions/startArgentRemoteSession");
|
|
43
46
|
const startCuttlefishDevice_1 = require("./functions/startCuttlefishDevice");
|
|
44
47
|
const startIosSimulator_1 = require("./functions/startIosSimulator");
|
|
48
|
+
const startIosSimulatorRecordings_1 = require("./functions/startIosSimulatorRecordings");
|
|
45
49
|
const startServeSimRemoteSession_1 = require("./functions/startServeSimRemoteSession");
|
|
46
50
|
const uploadArtifact_1 = require("./functions/uploadArtifact");
|
|
51
|
+
const uploadDeviceRunSessionScreenRecordings_1 = require("./functions/uploadDeviceRunSessionScreenRecordings");
|
|
47
52
|
const uploadToAsc_1 = require("./functions/uploadToAsc");
|
|
48
53
|
const useNpmToken_1 = require("./functions/useNpmToken");
|
|
54
|
+
const waitForPosthogMetric_1 = require("./functions/waitForPosthogMetric");
|
|
55
|
+
const uploadPosthogSourcemaps_1 = require("./functions/uploadPosthogSourcemaps");
|
|
56
|
+
const createPosthogAnnotation_1 = require("./functions/createPosthogAnnotation");
|
|
57
|
+
const waitForPosthogQuery_1 = require("./functions/waitForPosthogQuery");
|
|
49
58
|
function getEasFunctions(ctx) {
|
|
50
59
|
const functions = [
|
|
51
60
|
(0, checkout_1.createCheckoutBuildFunction)(),
|
|
@@ -82,10 +91,19 @@ function getEasFunctions(ctx) {
|
|
|
82
91
|
(0, startAndroidEmulator_1.createStartAndroidEmulatorBuildFunction)(),
|
|
83
92
|
(0, startCuttlefishDevice_1.createStartCuttlefishDeviceBuildFunction)(),
|
|
84
93
|
(0, startIosSimulator_1.createStartIosSimulatorBuildFunction)(),
|
|
94
|
+
(0, startIosSimulatorRecordings_1.createStartIosSimulatorRecordingsBuildFunction)(),
|
|
95
|
+
(0, finishIosSimulatorRecordings_1.createFinishIosSimulatorRecordingsBuildFunction)(),
|
|
96
|
+
(0, uploadDeviceRunSessionScreenRecordings_1.createUploadDeviceRunSessionScreenRecordingsBuildFunction)(ctx),
|
|
85
97
|
(0, startServeSimRemoteSession_1.createStartServeSimRemoteSessionBuildFunction)(ctx),
|
|
86
98
|
(0, installMaestro_1.createInstallMaestroBuildFunction)(),
|
|
87
99
|
(0, installPods_1.createInstallPodsBuildFunction)(),
|
|
88
100
|
(0, sendSlackMessage_1.createSendSlackMessageFunction)(),
|
|
101
|
+
(0, capturePosthogEvent_1.createCapturePosthogEventFunction)(),
|
|
102
|
+
(0, rolloutPosthogFlag_1.createRolloutPosthogFlagFunction)(),
|
|
103
|
+
(0, waitForPosthogMetric_1.createWaitForPosthogMetricFunction)(),
|
|
104
|
+
(0, uploadPosthogSourcemaps_1.createUploadPosthogSourcemapsFunction)(),
|
|
105
|
+
(0, createPosthogAnnotation_1.createPosthogAnnotationFunction)(),
|
|
106
|
+
(0, waitForPosthogQuery_1.createWaitForPosthogQueryFunction)(),
|
|
89
107
|
(0, calculateEASUpdateRuntimeVersion_1.calculateEASUpdateRuntimeVersionFunction)(),
|
|
90
108
|
(0, createSubmissionEntity_1.createSubmissionEntityFunction)(),
|
|
91
109
|
(0, uploadToAsc_1.createUploadToAscBuildFunction)(),
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createCapturePosthogEventFunction = createCapturePosthogEventFunction;
|
|
4
|
+
const eas_build_job_1 = require("@expo/eas-build-job");
|
|
5
|
+
const steps_1 = require("@expo/steps");
|
|
6
|
+
const PosthogClient_1 = require("../utils/PosthogClient");
|
|
7
|
+
const PosthogUtils_1 = require("../utils/PosthogUtils");
|
|
8
|
+
function createCapturePosthogEventFunction() {
|
|
9
|
+
return new steps_1.BuildFunction({
|
|
10
|
+
namespace: 'eas',
|
|
11
|
+
id: 'posthog_capture_event',
|
|
12
|
+
name: 'Capture PostHog event',
|
|
13
|
+
__metricsId: 'eas/posthog_capture_event',
|
|
14
|
+
inputProviders: [
|
|
15
|
+
steps_1.BuildStepInput.createProvider({
|
|
16
|
+
id: 'event',
|
|
17
|
+
allowedValueTypeName: steps_1.BuildStepInputValueTypeName.STRING,
|
|
18
|
+
required: true,
|
|
19
|
+
}),
|
|
20
|
+
steps_1.BuildStepInput.createProvider({
|
|
21
|
+
id: 'distinct_id',
|
|
22
|
+
allowedValueTypeName: steps_1.BuildStepInputValueTypeName.STRING,
|
|
23
|
+
required: false,
|
|
24
|
+
}),
|
|
25
|
+
steps_1.BuildStepInput.createProvider({
|
|
26
|
+
id: 'properties',
|
|
27
|
+
allowedValueTypeName: steps_1.BuildStepInputValueTypeName.JSON,
|
|
28
|
+
required: false,
|
|
29
|
+
}),
|
|
30
|
+
steps_1.BuildStepInput.createProvider({
|
|
31
|
+
id: 'api_key',
|
|
32
|
+
allowedValueTypeName: steps_1.BuildStepInputValueTypeName.STRING,
|
|
33
|
+
required: false,
|
|
34
|
+
}),
|
|
35
|
+
steps_1.BuildStepInput.createProvider({
|
|
36
|
+
id: 'host',
|
|
37
|
+
allowedValueTypeName: steps_1.BuildStepInputValueTypeName.STRING,
|
|
38
|
+
required: false,
|
|
39
|
+
}),
|
|
40
|
+
steps_1.BuildStepInput.createProvider({
|
|
41
|
+
id: 'ignore_error',
|
|
42
|
+
allowedValueTypeName: steps_1.BuildStepInputValueTypeName.BOOLEAN,
|
|
43
|
+
required: false,
|
|
44
|
+
}),
|
|
45
|
+
],
|
|
46
|
+
fn: async (stepCtx, { inputs, env, signal }) => {
|
|
47
|
+
const { logger } = stepCtx;
|
|
48
|
+
const ignoreError = Boolean(inputs.ignore_error.value);
|
|
49
|
+
const event = inputs.event.value;
|
|
50
|
+
const client = PosthogClient_1.PosthogClient.forIngestion({
|
|
51
|
+
apiKeyOverride: inputs.api_key.value,
|
|
52
|
+
hostOverride: inputs.host.value,
|
|
53
|
+
env,
|
|
54
|
+
});
|
|
55
|
+
if (!client) {
|
|
56
|
+
PosthogUtils_1.PosthogUtils.failOrLogError({
|
|
57
|
+
logger,
|
|
58
|
+
ignoreError,
|
|
59
|
+
error: new eas_build_job_1.UserError('EAS_POSTHOG_MISSING_API_KEY', 'PostHog API key not provided. Set the "api_key" input or the EXPO_PUBLIC_POSTHOG_API_KEY environment variable.'),
|
|
60
|
+
});
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
logger.info(`Sending PostHog event "${event}"`);
|
|
64
|
+
try {
|
|
65
|
+
await client.captureEventAsync({
|
|
66
|
+
event,
|
|
67
|
+
distinctId: inputs.distinct_id.value,
|
|
68
|
+
properties: inputs.properties.value,
|
|
69
|
+
signal,
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
catch (error) {
|
|
73
|
+
PosthogUtils_1.PosthogUtils.failOrLogError({ logger, ignoreError, error });
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
logger.info(`Sent PostHog event "${event}"`);
|
|
77
|
+
},
|
|
78
|
+
});
|
|
79
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createPosthogAnnotationFunction = createPosthogAnnotationFunction;
|
|
4
|
+
const steps_1 = require("@expo/steps");
|
|
5
|
+
const PosthogClient_1 = require("../utils/PosthogClient");
|
|
6
|
+
const PosthogUtils_1 = require("../utils/PosthogUtils");
|
|
7
|
+
function createPosthogAnnotationFunction() {
|
|
8
|
+
return new steps_1.BuildFunction({
|
|
9
|
+
namespace: 'eas',
|
|
10
|
+
id: 'posthog_annotation',
|
|
11
|
+
name: 'Create a PostHog annotation',
|
|
12
|
+
__metricsId: 'eas/posthog_annotation',
|
|
13
|
+
inputProviders: [
|
|
14
|
+
steps_1.BuildStepInput.createProvider({
|
|
15
|
+
id: 'content',
|
|
16
|
+
allowedValueTypeName: steps_1.BuildStepInputValueTypeName.STRING,
|
|
17
|
+
required: true,
|
|
18
|
+
}),
|
|
19
|
+
steps_1.BuildStepInput.createProvider({
|
|
20
|
+
id: 'date_marker',
|
|
21
|
+
allowedValueTypeName: steps_1.BuildStepInputValueTypeName.STRING,
|
|
22
|
+
required: false,
|
|
23
|
+
}),
|
|
24
|
+
steps_1.BuildStepInput.createProvider({
|
|
25
|
+
id: 'api_key',
|
|
26
|
+
allowedValueTypeName: steps_1.BuildStepInputValueTypeName.STRING,
|
|
27
|
+
required: false,
|
|
28
|
+
}),
|
|
29
|
+
steps_1.BuildStepInput.createProvider({
|
|
30
|
+
id: 'project_id',
|
|
31
|
+
allowedValueTypeName: steps_1.BuildStepInputValueTypeName.STRING,
|
|
32
|
+
required: false,
|
|
33
|
+
}),
|
|
34
|
+
steps_1.BuildStepInput.createProvider({
|
|
35
|
+
id: 'ignore_error',
|
|
36
|
+
allowedValueTypeName: steps_1.BuildStepInputValueTypeName.BOOLEAN,
|
|
37
|
+
required: false,
|
|
38
|
+
}),
|
|
39
|
+
],
|
|
40
|
+
fn: async (stepCtx, { inputs, env, signal }) => {
|
|
41
|
+
const { logger } = stepCtx;
|
|
42
|
+
const ignoreError = Boolean(inputs.ignore_error.value);
|
|
43
|
+
const result = PosthogClient_1.PosthogClient.fromEnv({
|
|
44
|
+
apiKeyOverride: inputs.api_key.value,
|
|
45
|
+
projectIdOverride: inputs.project_id.value,
|
|
46
|
+
env,
|
|
47
|
+
});
|
|
48
|
+
if (!result.client) {
|
|
49
|
+
PosthogUtils_1.PosthogUtils.failOrLogError({
|
|
50
|
+
logger,
|
|
51
|
+
ignoreError,
|
|
52
|
+
error: PosthogUtils_1.PosthogUtils.missingCredentialsError(result.missing),
|
|
53
|
+
});
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
const client = result.client;
|
|
57
|
+
const content = inputs.content.value;
|
|
58
|
+
const dateMarker = inputs.date_marker.value ?? new Date().toISOString();
|
|
59
|
+
logger.info(`Creating PostHog annotation "${content}"`);
|
|
60
|
+
try {
|
|
61
|
+
await client.requestAsync('POST', '/annotations/', {
|
|
62
|
+
action: 'Creating the PostHog annotation',
|
|
63
|
+
forbiddenScope: 'annotation:write',
|
|
64
|
+
body: { content, date_marker: dateMarker },
|
|
65
|
+
signal,
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
catch (error) {
|
|
69
|
+
PosthogUtils_1.PosthogUtils.failOrLogError({ logger, ignoreError, error });
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
logger.info('Created PostHog annotation');
|
|
73
|
+
},
|
|
74
|
+
});
|
|
75
|
+
}
|
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.createSubmissionEntityFunction = createSubmissionEntityFunction;
|
|
4
4
|
const results_1 = require("@expo/results");
|
|
5
5
|
const steps_1 = require("@expo/steps");
|
|
6
|
+
const sentry_1 = require("../../sentry");
|
|
6
7
|
const retryOnDNSFailure_1 = require("../../utils/retryOnDNSFailure");
|
|
7
8
|
function createSubmissionEntityFunction() {
|
|
8
9
|
return new steps_1.BuildFunction({
|
|
@@ -53,16 +54,39 @@ function createSubmissionEntityFunction() {
|
|
|
53
54
|
const robotAccessToken = stepsCtx.global.staticContext.job.secrets?.robotAccessToken;
|
|
54
55
|
if (!robotAccessToken) {
|
|
55
56
|
stepsCtx.logger.error('Failed to create submission entity: no robot access token found');
|
|
57
|
+
sentry_1.Sentry.capture('Failed to create submission entity: missing robot access token');
|
|
56
58
|
return;
|
|
57
59
|
}
|
|
58
60
|
const buildId = inputs.build_id.value;
|
|
59
61
|
if (!buildId) {
|
|
60
62
|
stepsCtx.logger.error('Failed to create submission entity: no build ID provided');
|
|
63
|
+
sentry_1.Sentry.capture('Failed to create submission entity: missing build ID', {
|
|
64
|
+
extras: {
|
|
65
|
+
buildId,
|
|
66
|
+
},
|
|
67
|
+
});
|
|
61
68
|
return;
|
|
62
69
|
}
|
|
63
70
|
const workflowJobId = stepsCtx.global.env.__WORKFLOW_JOB_ID;
|
|
64
71
|
if (!workflowJobId) {
|
|
65
72
|
stepsCtx.logger.error('Failed to create submission entity: no workflow job ID found');
|
|
73
|
+
sentry_1.Sentry.capture('Failed to create submission entity: missing workflow job ID', {
|
|
74
|
+
extras: {
|
|
75
|
+
buildId,
|
|
76
|
+
workflowJobId,
|
|
77
|
+
},
|
|
78
|
+
});
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
const expoApiServerURL = stepsCtx.global.staticContext.expoApiServerURL;
|
|
82
|
+
if (!expoApiServerURL) {
|
|
83
|
+
stepsCtx.logger.error('Failed to create submission entity: no Expo API server URL found');
|
|
84
|
+
sentry_1.Sentry.capture('Failed to create submission entity: missing Expo API server URL', {
|
|
85
|
+
extras: {
|
|
86
|
+
buildId,
|
|
87
|
+
workflowJobId,
|
|
88
|
+
},
|
|
89
|
+
});
|
|
66
90
|
return;
|
|
67
91
|
}
|
|
68
92
|
// This is supposed to provide fallback for `''` -> `undefined`.
|
|
@@ -76,7 +100,7 @@ function createSubmissionEntityFunction() {
|
|
|
76
100
|
const ascAppIdentifier = inputs.asc_app_identifier.value || undefined;
|
|
77
101
|
/* eslint-enable @typescript-eslint/prefer-nullish-coalescing */
|
|
78
102
|
try {
|
|
79
|
-
const response = await (0, retryOnDNSFailure_1.retryOnDNSFailure)(fetch)(new URL('/v2/app-store-submissions/',
|
|
103
|
+
const response = await (0, retryOnDNSFailure_1.retryOnDNSFailure)(fetch)(new URL('/v2/app-store-submissions/', expoApiServerURL), {
|
|
80
104
|
method: 'POST',
|
|
81
105
|
headers: {
|
|
82
106
|
Authorization: `Bearer ${robotAccessToken}`,
|
|
@@ -52,11 +52,21 @@ function createDownloadArtifactFunction() {
|
|
|
52
52
|
});
|
|
53
53
|
const interpolationContext = stepsCtx.global.getInterpolationContext();
|
|
54
54
|
if (!('workflow' in interpolationContext)) {
|
|
55
|
-
throw new eas_build_job_1.
|
|
55
|
+
throw new eas_build_job_1.SystemError('No workflow found in the interpolation context.', {
|
|
56
|
+
trackingCode: 'EAS_DOWNLOAD_ARTIFACT_NO_WORKFLOW',
|
|
57
|
+
});
|
|
56
58
|
}
|
|
57
59
|
const robotAccessToken = stepsCtx.global.staticContext.job.secrets?.robotAccessToken;
|
|
58
60
|
if (!robotAccessToken) {
|
|
59
|
-
throw new eas_build_job_1.
|
|
61
|
+
throw new eas_build_job_1.SystemError('No robot access token found in the job secrets.', {
|
|
62
|
+
trackingCode: 'EAS_DOWNLOAD_ARTIFACT_NO_ROBOT_ACCESS_TOKEN',
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
const expoApiServerURL = stepsCtx.global.staticContext.expoApiServerURL;
|
|
66
|
+
if (!expoApiServerURL) {
|
|
67
|
+
throw new eas_build_job_1.SystemError('Missing Expo API server URL.', {
|
|
68
|
+
trackingCode: 'EAS_DOWNLOAD_ARTIFACT_NO_EXPO_API_SERVER_URL',
|
|
69
|
+
});
|
|
60
70
|
}
|
|
61
71
|
const workflowRunId = interpolationContext.workflow.id;
|
|
62
72
|
const { logger } = stepsCtx;
|
|
@@ -69,7 +79,7 @@ function createDownloadArtifactFunction() {
|
|
|
69
79
|
const { artifactPath } = await downloadArtifactAsync({
|
|
70
80
|
logger,
|
|
71
81
|
workflowRunId,
|
|
72
|
-
expoApiServerURL
|
|
82
|
+
expoApiServerURL,
|
|
73
83
|
robotAccessToken,
|
|
74
84
|
params,
|
|
75
85
|
});
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createFinishIosSimulatorRecordingsBuildFunction = createFinishIosSimulatorRecordingsBuildFunction;
|
|
4
|
+
const steps_1 = require("@expo/steps");
|
|
5
|
+
const IosSimulatorRecordingUtils_1 = require("../utils/IosSimulatorRecordingUtils");
|
|
6
|
+
function createFinishIosSimulatorRecordingsBuildFunction() {
|
|
7
|
+
return new steps_1.BuildFunction({
|
|
8
|
+
namespace: 'eas',
|
|
9
|
+
id: 'finish_ios_simulator_recordings',
|
|
10
|
+
name: 'Finish iOS Simulator recordings',
|
|
11
|
+
__metricsId: 'eas/finish_ios_simulator_recordings',
|
|
12
|
+
supportedRuntimePlatforms: [steps_1.BuildRuntimePlatform.DARWIN],
|
|
13
|
+
outputProviders: [
|
|
14
|
+
steps_1.BuildStepOutput.createProvider({
|
|
15
|
+
id: 'recordings_json',
|
|
16
|
+
required: true,
|
|
17
|
+
}),
|
|
18
|
+
],
|
|
19
|
+
fn: async ({ logger }, { outputs }) => {
|
|
20
|
+
const recordings = await IosSimulatorRecordingUtils_1.IosSimulatorRecordingUtils.finishAsync({ logger });
|
|
21
|
+
outputs.recordings_json.set(JSON.stringify(recordings));
|
|
22
|
+
},
|
|
23
|
+
});
|
|
24
|
+
}
|
|
@@ -33,11 +33,6 @@ function createRepackBuildFunction() {
|
|
|
33
33
|
required: false,
|
|
34
34
|
allowedValueTypeName: steps_1.BuildStepInputValueTypeName.STRING,
|
|
35
35
|
}),
|
|
36
|
-
steps_1.BuildStepInput.createProvider({
|
|
37
|
-
id: 'output_path',
|
|
38
|
-
allowedValueTypeName: steps_1.BuildStepInputValueTypeName.STRING,
|
|
39
|
-
required: false,
|
|
40
|
-
}),
|
|
41
36
|
steps_1.BuildStepInput.createProvider({
|
|
42
37
|
id: 'embed_bundle_assets',
|
|
43
38
|
allowedValueTypeName: steps_1.BuildStepInputValueTypeName.BOOLEAN,
|
|
@@ -93,8 +88,10 @@ function createRepackBuildFunction() {
|
|
|
93
88
|
await node_fs_1.default.promises.mkdir(workingDirectory);
|
|
94
89
|
stepsCtx.logger.info(`Created temporary working directory: ${workingDirectory}`);
|
|
95
90
|
const sourceAppPath = inputs.source_app_path.value;
|
|
96
|
-
const outputPath =
|
|
97
|
-
|
|
91
|
+
const outputPath = createOutputPath({
|
|
92
|
+
sourceAppPath,
|
|
93
|
+
tmpDir,
|
|
94
|
+
});
|
|
98
95
|
const exportEmbedOptions = inputs.embed_bundle_assets.value
|
|
99
96
|
? {
|
|
100
97
|
sourcemapOutput: undefined,
|
|
@@ -174,6 +171,14 @@ function createRepackBuildFunction() {
|
|
|
174
171
|
},
|
|
175
172
|
});
|
|
176
173
|
}
|
|
174
|
+
function createOutputPath({ sourceAppPath, tmpDir, }) {
|
|
175
|
+
const outputPath = node_path_1.default.join(tmpDir, `repacked-${(0, node_crypto_1.randomUUID)()}${node_path_1.default.extname(sourceAppPath)}`);
|
|
176
|
+
const extension = node_path_1.default.extname(outputPath);
|
|
177
|
+
if (extension.toLowerCase() !== '.aab') {
|
|
178
|
+
return outputPath;
|
|
179
|
+
}
|
|
180
|
+
return `${outputPath.slice(0, -extension.length)}.apk`;
|
|
181
|
+
}
|
|
177
182
|
/**
|
|
178
183
|
* Install `@expo/repack-app` in a sandbox directory and import it.
|
|
179
184
|
*/
|
|
@@ -99,11 +99,12 @@ function createRestoreCacheFunction() {
|
|
|
99
99
|
.parse((inputs.restore_keys.value ?? '').split(/[\r\n]+/))
|
|
100
100
|
.filter(key => key !== '');
|
|
101
101
|
const jobId = (0, nullthrows_1.default)(env.EAS_BUILD_ID, 'EAS_BUILD_ID is not set');
|
|
102
|
+
const expoApiServerURL = (0, nullthrows_1.default)(stepsCtx.global.staticContext.expoApiServerURL, 'expoApiServerURL is not set');
|
|
102
103
|
const robotAccessToken = (0, nullthrows_1.default)(stepsCtx.global.staticContext.job.secrets?.robotAccessToken, 'robotAccessToken is not set');
|
|
103
104
|
const { archivePath, matchedKey } = await downloadCacheAsync({
|
|
104
105
|
logger,
|
|
105
106
|
jobId,
|
|
106
|
-
expoApiServerURL
|
|
107
|
+
expoApiServerURL,
|
|
107
108
|
robotAccessToken,
|
|
108
109
|
paths,
|
|
109
110
|
key,
|