eas-cli 16.20.3 → 16.21.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/README.md +96 -88
- package/build/build/utils/environment.js +1 -1
- package/build/commands/deploy/index.js +8 -1
- package/build/commands/env/exec.js +1 -1
- package/build/commands/env/pull.js +1 -1
- package/build/commands/workflow/run.d.ts +1 -0
- package/build/commands/workflow/run.js +121 -63
- package/build/graphql/generated.d.ts +38 -0
- package/build/graphql/mutations/WorkflowRevisionMutation.d.ts +6 -0
- package/build/graphql/mutations/WorkflowRevisionMutation.js +35 -0
- package/build/graphql/mutations/WorkflowRunMutation.d.ts +7 -0
- package/build/graphql/mutations/WorkflowRunMutation.js +27 -0
- package/build/worker/assets.d.ts +5 -0
- package/build/worker/assets.js +24 -1
- package/oclif.manifest.json +9 -2
- package/package.json +2 -2
|
@@ -14,7 +14,7 @@ const BuildProfileEnvironmentToEnvironment = {
|
|
|
14
14
|
development: EnvironmentVariableEnvironment.Development,
|
|
15
15
|
};
|
|
16
16
|
function isEnvironment(env) {
|
|
17
|
-
return Object.values(EnvironmentVariableEnvironment).includes(env);
|
|
17
|
+
return Object.values(EnvironmentVariableEnvironment).includes(env.toLowerCase());
|
|
18
18
|
}
|
|
19
19
|
exports.isEnvironment = isEnvironment;
|
|
20
20
|
function buildProfileEnvironmentToEnvironment(environment) {
|
|
@@ -81,6 +81,9 @@ class WorkerDeploy extends EasCommand_1.default {
|
|
|
81
81
|
yield [`server/${workerFile.normalizedPath}`, workerFile.data];
|
|
82
82
|
}
|
|
83
83
|
}
|
|
84
|
+
else if (projectDist.type === 'static' && params.routesConfig) {
|
|
85
|
+
yield ['routes.json', JSON.stringify(params.routesConfig)];
|
|
86
|
+
}
|
|
84
87
|
}
|
|
85
88
|
async function finalizeDeployAsync(deployParams) {
|
|
86
89
|
const finalizeDeployUrl = new URL('/deploy/finalize', deployParams.baseURL);
|
|
@@ -187,8 +190,12 @@ class WorkerDeploy extends EasCommand_1.default {
|
|
|
187
190
|
'In case of conflict, the EAS environment variable values will be used: ' +
|
|
188
191
|
manifestResult.conflictingVariableNames.join(' '));
|
|
189
192
|
}
|
|
190
|
-
|
|
193
|
+
const assetPath = projectDist.type === 'server' ? projectDist.clientPath : projectDist.path;
|
|
194
|
+
assetFiles = await WorkerAssets.collectAssetsAsync(assetPath, {
|
|
195
|
+
maxFileSize: MAX_UPLOAD_SIZE,
|
|
196
|
+
});
|
|
191
197
|
tarPath = await WorkerAssets.packFilesIterableAsync(emitWorkerTarballAsync({
|
|
198
|
+
routesConfig: await WorkerAssets.getRoutesConfigAsync(assetPath),
|
|
192
199
|
assetMap: WorkerAssets.assetsToAssetsMap(assetFiles),
|
|
193
200
|
manifest: manifestResult.manifest,
|
|
194
201
|
}));
|
|
@@ -63,7 +63,7 @@ class EnvExec extends EasCommand_1.default {
|
|
|
63
63
|
if (rawFlags['non-interactive'] && (!bash_command || !environment)) {
|
|
64
64
|
throw new Error("You must specify both environment and bash command when running in non-interactive mode. Run command as `eas env:exec ENVIRONMENT 'bash command'`.");
|
|
65
65
|
}
|
|
66
|
-
environment = environment?.
|
|
66
|
+
environment = environment?.toLowerCase();
|
|
67
67
|
if (!(0, variableUtils_1.isEnvironment)(environment)) {
|
|
68
68
|
throw new Error("Invalid environment. Use one of 'production', 'preview', or 'development'.");
|
|
69
69
|
}
|
|
@@ -37,7 +37,7 @@ class EnvPull extends EasCommand_1.default {
|
|
|
37
37
|
};
|
|
38
38
|
async runAsync() {
|
|
39
39
|
let { args: { environment: argEnvironment }, flags: { environment: flagEnvironment, path: targetPath, 'non-interactive': nonInteractive }, } = await this.parse(EnvPull);
|
|
40
|
-
let environment = flagEnvironment?.
|
|
40
|
+
let environment = flagEnvironment?.toLowerCase() ?? argEnvironment?.toLowerCase();
|
|
41
41
|
if (!environment) {
|
|
42
42
|
environment = await (0, prompts_2.promptVariableEnvironmentAsync)({ nonInteractive });
|
|
43
43
|
}
|
|
@@ -51,6 +51,7 @@ export default class WorkflowRun extends EasCommand {
|
|
|
51
51
|
json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
52
52
|
wait: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
53
53
|
input: import("@oclif/core/lib/interfaces").OptionFlag<string[] | undefined>;
|
|
54
|
+
ref: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined>;
|
|
54
55
|
'non-interactive': import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
55
56
|
};
|
|
56
57
|
static contextDefinition: {
|
|
@@ -43,6 +43,7 @@
|
|
|
43
43
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
44
44
|
exports.parseWorkflowInputsFromYaml = exports.WorkflowDispatchInputZ = exports.parseJsonInputs = exports.maybeReadStdinAsync = exports.parseInputs = void 0;
|
|
45
45
|
const tslib_1 = require("tslib");
|
|
46
|
+
const spawn_async_1 = tslib_1.__importDefault(require("@expo/spawn-async"));
|
|
46
47
|
const core_1 = require("@oclif/core");
|
|
47
48
|
const core_2 = require("@urql/core");
|
|
48
49
|
const chalk_1 = tslib_1.__importDefault(require("chalk"));
|
|
@@ -73,7 +74,7 @@ const EXIT_CODES = {
|
|
|
73
74
|
WAIT_ABORTED: 13,
|
|
74
75
|
};
|
|
75
76
|
class WorkflowRun extends EasCommand_1.default {
|
|
76
|
-
static description = 'run an EAS workflow';
|
|
77
|
+
static description = 'run an EAS workflow. The entire local project directory will be packaged and uploaded to EAS servers for the workflow run, unless the --ref flag is used.';
|
|
77
78
|
static args = [{ name: 'file', description: 'Path to the workflow file to run' }];
|
|
78
79
|
static flags = {
|
|
79
80
|
...flags_1.EASNonInteractiveFlag,
|
|
@@ -90,6 +91,10 @@ class WorkflowRun extends EasCommand_1.default {
|
|
|
90
91
|
description: 'Add a parameter in key=value format. Use multiple instances of this flag to set multiple inputs.',
|
|
91
92
|
summary: 'Set workflow inputs',
|
|
92
93
|
}),
|
|
94
|
+
ref: core_1.Flags.string({
|
|
95
|
+
description: "The git reference must exist in the project's git repository, and the workflow file must exist at that reference. When this flag is used, the local project is not uploaded; instead, the workflow is run from the exact state of the project at the chosen reference.",
|
|
96
|
+
summary: 'Git reference to run the workflow on',
|
|
97
|
+
}),
|
|
93
98
|
...flags_1.EasJsonOnlyFlag,
|
|
94
99
|
};
|
|
95
100
|
static contextDefinition = {
|
|
@@ -107,21 +112,57 @@ class WorkflowRun extends EasCommand_1.default {
|
|
|
107
112
|
nonInteractive: flags['non-interactive'],
|
|
108
113
|
withServerSideEnvironment: null,
|
|
109
114
|
});
|
|
115
|
+
const { projectId, exp: { slug: projectName }, } = await getDynamicPrivateProjectConfigAsync();
|
|
116
|
+
const account = await (0, projectUtils_1.getOwnerAccountForProjectIdAsync)(graphqlClient, projectId);
|
|
110
117
|
let yamlConfig;
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
+
let workflowRunId;
|
|
119
|
+
let workflowRevisionId;
|
|
120
|
+
let gitRef;
|
|
121
|
+
if (flags.ref) {
|
|
122
|
+
// Run from git ref
|
|
123
|
+
const fileName = path.basename(args.file);
|
|
124
|
+
// Find the real commit, make sure the ref is valid
|
|
125
|
+
gitRef = (await (0, spawn_async_1.default)('git', ['rev-parse', flags.ref], {
|
|
126
|
+
cwd: projectDir,
|
|
127
|
+
})).output[0].trim();
|
|
128
|
+
if (!gitRef) {
|
|
129
|
+
throw new Error('Failed to resolve git reference');
|
|
130
|
+
}
|
|
131
|
+
log_1.default.log(`Using workflow file ${fileName} at ${gitRef}`);
|
|
132
|
+
let revisionResult;
|
|
133
|
+
try {
|
|
134
|
+
revisionResult = await WorkflowRevisionMutation_1.WorkflowRevisionMutation.getOrCreateWorkflowRevisionFromGitRefAsync(graphqlClient, {
|
|
135
|
+
appId: projectId,
|
|
136
|
+
fileName,
|
|
137
|
+
gitRef,
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
catch (err) {
|
|
141
|
+
throw new Error(`Failed to find or create workflow revision for ${fileName} at ${flags.ref}: ${err}`);
|
|
142
|
+
}
|
|
143
|
+
log_1.default.debug(`Workflow revision: ${JSON.stringify(revisionResult, null, 2)}`);
|
|
144
|
+
if (!revisionResult) {
|
|
145
|
+
throw new Error(`Failed to find or create workflow revision for ${fileName} at ${flags.ref}`);
|
|
146
|
+
}
|
|
147
|
+
yamlConfig = revisionResult.yamlConfig;
|
|
148
|
+
workflowRevisionId = revisionResult.id;
|
|
118
149
|
}
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
150
|
+
else {
|
|
151
|
+
// Run from local file
|
|
152
|
+
try {
|
|
153
|
+
const workflowFileContents = await workflowFile_1.WorkflowFile.readWorkflowFileContentsAsync({
|
|
154
|
+
projectDir,
|
|
155
|
+
filePath: args.file,
|
|
156
|
+
});
|
|
157
|
+
log_1.default.log(`Using workflow file from ${workflowFileContents.filePath}`);
|
|
158
|
+
yamlConfig = workflowFileContents.yamlConfig;
|
|
159
|
+
}
|
|
160
|
+
catch (err) {
|
|
161
|
+
log_1.default.error('Failed to read workflow file.');
|
|
162
|
+
throw err;
|
|
163
|
+
}
|
|
122
164
|
}
|
|
123
|
-
|
|
124
|
-
const account = await (0, projectUtils_1.getOwnerAccountForProjectIdAsync)(graphqlClient, projectId);
|
|
165
|
+
// Validate workflow YAML
|
|
125
166
|
try {
|
|
126
167
|
await WorkflowRevisionMutation_1.WorkflowRevisionMutation.validateWorkflowYamlConfigAsync(graphqlClient, {
|
|
127
168
|
appId: projectId,
|
|
@@ -169,65 +210,82 @@ class WorkflowRun extends EasCommand_1.default {
|
|
|
169
210
|
const easJsonPath = path.join(projectDir, 'eas.json');
|
|
170
211
|
const packageJsonPath = path.join(projectDir, 'package.json');
|
|
171
212
|
const projectRootDirectory = (0, slash_1.default)(path.relative(await vcsClient.getRootPathAsync(), projectDir) || '.');
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
accountId: account.id,
|
|
182
|
-
filePath: easJsonPath,
|
|
183
|
-
maxSizeBytes: 1024 * 1024,
|
|
184
|
-
}));
|
|
213
|
+
if (gitRef) {
|
|
214
|
+
// Run from git ref
|
|
215
|
+
let runResult;
|
|
216
|
+
try {
|
|
217
|
+
runResult = await WorkflowRunMutation_1.WorkflowRunMutation.createWorkflowRunFromGitRefAsync(graphqlClient, {
|
|
218
|
+
workflowRevisionId: workflowRevisionId ?? '',
|
|
219
|
+
gitRef,
|
|
220
|
+
inputs,
|
|
221
|
+
});
|
|
185
222
|
}
|
|
186
|
-
|
|
187
|
-
|
|
223
|
+
catch (err) {
|
|
224
|
+
throw new Error(`Failed to create workflow run: ${err}`);
|
|
188
225
|
}
|
|
189
|
-
|
|
190
|
-
|
|
226
|
+
workflowRunId = runResult.id;
|
|
227
|
+
}
|
|
228
|
+
else {
|
|
229
|
+
// Run from local file
|
|
230
|
+
try {
|
|
231
|
+
({ projectArchiveBucketKey } = await (0, uploadAccountScopedProjectSourceAsync_1.uploadAccountScopedProjectSourceAsync)({
|
|
191
232
|
graphqlClient,
|
|
233
|
+
vcsClient,
|
|
192
234
|
accountId: account.id,
|
|
193
|
-
filePath: packageJsonPath,
|
|
194
|
-
maxSizeBytes: 1024 * 1024,
|
|
195
235
|
}));
|
|
236
|
+
if (await fileExistsAsync(easJsonPath)) {
|
|
237
|
+
({ fileBucketKey: easJsonBucketKey } = await (0, uploadAccountScopedFileAsync_1.uploadAccountScopedFileAsync)({
|
|
238
|
+
graphqlClient,
|
|
239
|
+
accountId: account.id,
|
|
240
|
+
filePath: easJsonPath,
|
|
241
|
+
maxSizeBytes: 1024 * 1024,
|
|
242
|
+
}));
|
|
243
|
+
}
|
|
244
|
+
else {
|
|
245
|
+
log_1.default.warn(`⚠ No ${chalk_1.default.bold('eas.json')} found in the project directory. Running ${chalk_1.default.bold('type: build')} jobs will not work. Run ${chalk_1.default.bold('eas build:configure')} to configure your project for builds.`);
|
|
246
|
+
}
|
|
247
|
+
if (await fileExistsAsync(packageJsonPath)) {
|
|
248
|
+
({ fileBucketKey: packageJsonBucketKey } = await (0, uploadAccountScopedFileAsync_1.uploadAccountScopedFileAsync)({
|
|
249
|
+
graphqlClient,
|
|
250
|
+
accountId: account.id,
|
|
251
|
+
filePath: packageJsonPath,
|
|
252
|
+
maxSizeBytes: 1024 * 1024,
|
|
253
|
+
}));
|
|
254
|
+
}
|
|
255
|
+
else {
|
|
256
|
+
log_1.default.warn(`⚠ No ${chalk_1.default.bold('package.json')} found in the project directory. It is used to automatically infer best job configuration for your project. You may want to define ${chalk_1.default.bold('image')} property in your workflow to specify the image to use.`);
|
|
257
|
+
}
|
|
196
258
|
}
|
|
197
|
-
|
|
198
|
-
log_1.default.
|
|
259
|
+
catch (err) {
|
|
260
|
+
log_1.default.error('Failed to upload project sources.');
|
|
261
|
+
throw err;
|
|
199
262
|
}
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
try {
|
|
207
|
-
({ id: workflowRunId } = await WorkflowRunMutation_1.WorkflowRunMutation.createWorkflowRunAsync(graphqlClient, {
|
|
208
|
-
appId: projectId,
|
|
209
|
-
workflowRevisionInput: {
|
|
210
|
-
fileName: path.basename(args.file),
|
|
211
|
-
yamlConfig,
|
|
212
|
-
},
|
|
213
|
-
workflowRunInput: {
|
|
214
|
-
inputs,
|
|
215
|
-
projectSource: {
|
|
216
|
-
type: generated_1.WorkflowProjectSourceType.Gcs,
|
|
217
|
-
projectArchiveBucketKey,
|
|
218
|
-
easJsonBucketKey,
|
|
219
|
-
packageJsonBucketKey,
|
|
220
|
-
projectRootDirectory,
|
|
263
|
+
try {
|
|
264
|
+
({ id: workflowRunId } = await WorkflowRunMutation_1.WorkflowRunMutation.createWorkflowRunAsync(graphqlClient, {
|
|
265
|
+
appId: projectId,
|
|
266
|
+
workflowRevisionInput: {
|
|
267
|
+
fileName: path.basename(args.file),
|
|
268
|
+
yamlConfig,
|
|
221
269
|
},
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
270
|
+
workflowRunInput: {
|
|
271
|
+
inputs,
|
|
272
|
+
projectSource: {
|
|
273
|
+
type: generated_1.WorkflowProjectSourceType.Gcs,
|
|
274
|
+
projectArchiveBucketKey,
|
|
275
|
+
easJsonBucketKey,
|
|
276
|
+
packageJsonBucketKey,
|
|
277
|
+
projectRootDirectory,
|
|
278
|
+
},
|
|
279
|
+
},
|
|
280
|
+
}));
|
|
281
|
+
}
|
|
282
|
+
catch (err) {
|
|
283
|
+
log_1.default.error('Failed to start the workflow with the API.');
|
|
284
|
+
throw err;
|
|
285
|
+
}
|
|
230
286
|
}
|
|
287
|
+
log_1.default.newLine();
|
|
288
|
+
log_1.default.log(`See logs: ${(0, log_1.link)((0, url_1.getWorkflowRunUrl)(account.name, projectName, workflowRunId))}`);
|
|
231
289
|
if (!flags.wait) {
|
|
232
290
|
if (flags.json) {
|
|
233
291
|
(0, json_1.printJsonOnlyOutput)({
|
|
@@ -12504,6 +12504,29 @@ export type DeleteWebhookMutation = {
|
|
|
12504
12504
|
};
|
|
12505
12505
|
};
|
|
12506
12506
|
};
|
|
12507
|
+
export type GetOrCreateWorkflowRevisionFromGitRefMutationVariables = Exact<{
|
|
12508
|
+
appId: Scalars['ID']['input'];
|
|
12509
|
+
fileName: Scalars['String']['input'];
|
|
12510
|
+
gitRef: Scalars['String']['input'];
|
|
12511
|
+
}>;
|
|
12512
|
+
export type GetOrCreateWorkflowRevisionFromGitRefMutation = {
|
|
12513
|
+
__typename?: 'RootMutation';
|
|
12514
|
+
workflowRevision: {
|
|
12515
|
+
__typename?: 'WorkflowRevisionMutation';
|
|
12516
|
+
getOrCreateWorkflowRevisionFromGitRef: {
|
|
12517
|
+
__typename?: 'WorkflowRevision';
|
|
12518
|
+
id: string;
|
|
12519
|
+
yamlConfig: string;
|
|
12520
|
+
blobSha: string;
|
|
12521
|
+
commitSha?: string | null;
|
|
12522
|
+
createdAt: any;
|
|
12523
|
+
workflow: {
|
|
12524
|
+
__typename?: 'Workflow';
|
|
12525
|
+
id: string;
|
|
12526
|
+
};
|
|
12527
|
+
};
|
|
12528
|
+
};
|
|
12529
|
+
};
|
|
12507
12530
|
export type ValidateWorkflowYamlConfigMutationVariables = Exact<{
|
|
12508
12531
|
appId: Scalars['ID']['input'];
|
|
12509
12532
|
yamlConfig: Scalars['String']['input'];
|
|
@@ -12530,6 +12553,21 @@ export type CreateWorkflowRunMutation = {
|
|
|
12530
12553
|
};
|
|
12531
12554
|
};
|
|
12532
12555
|
};
|
|
12556
|
+
export type CreateWorkflowRunFromGitRefMutationVariables = Exact<{
|
|
12557
|
+
workflowRevisionId: Scalars['ID']['input'];
|
|
12558
|
+
gitRef: Scalars['String']['input'];
|
|
12559
|
+
inputs?: InputMaybe<Scalars['JSONObject']['input']>;
|
|
12560
|
+
}>;
|
|
12561
|
+
export type CreateWorkflowRunFromGitRefMutation = {
|
|
12562
|
+
__typename?: 'RootMutation';
|
|
12563
|
+
workflowRun: {
|
|
12564
|
+
__typename?: 'WorkflowRunMutation';
|
|
12565
|
+
createWorkflowRunFromGitRef: {
|
|
12566
|
+
__typename?: 'WorkflowRun';
|
|
12567
|
+
id: string;
|
|
12568
|
+
};
|
|
12569
|
+
};
|
|
12570
|
+
};
|
|
12533
12571
|
export type CancelWorkflowRunMutationVariables = Exact<{
|
|
12534
12572
|
workflowRunId: Scalars['ID']['input'];
|
|
12535
12573
|
}>;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
import { ExpoGraphqlClient } from '../../commandUtils/context/contextUtils/createGraphqlClient';
|
|
3
|
+
import { WorkflowRevision } from '../generated';
|
|
3
4
|
export declare namespace WorkflowRevisionMutation {
|
|
4
5
|
const ValidationErrorExtensionZ: z.ZodObject<{
|
|
5
6
|
errorCode: z.ZodLiteral<"VALIDATION_ERROR">;
|
|
@@ -8,6 +9,11 @@ export declare namespace WorkflowRevisionMutation {
|
|
|
8
9
|
fieldErrors: z.ZodRecord<z.ZodString, z.ZodArray<z.ZodString>>;
|
|
9
10
|
}, z.core.$strip>;
|
|
10
11
|
}, z.core.$strip>;
|
|
12
|
+
function getOrCreateWorkflowRevisionFromGitRefAsync(graphqlClient: ExpoGraphqlClient, { appId, fileName, gitRef, }: {
|
|
13
|
+
appId: string;
|
|
14
|
+
fileName: string;
|
|
15
|
+
gitRef: string;
|
|
16
|
+
}): Promise<WorkflowRevision | undefined>;
|
|
11
17
|
function validateWorkflowYamlConfigAsync(graphqlClient: ExpoGraphqlClient, { appId, yamlConfig, }: {
|
|
12
18
|
appId: string;
|
|
13
19
|
yamlConfig: string;
|
|
@@ -14,6 +14,41 @@ var WorkflowRevisionMutation;
|
|
|
14
14
|
fieldErrors: zod_1.z.record(zod_1.z.string(), zod_1.z.array(zod_1.z.string())),
|
|
15
15
|
}),
|
|
16
16
|
});
|
|
17
|
+
async function getOrCreateWorkflowRevisionFromGitRefAsync(graphqlClient, { appId, fileName, gitRef, }) {
|
|
18
|
+
const data = await (0, client_1.withErrorHandlingAsync)(graphqlClient
|
|
19
|
+
.mutation((0, graphql_tag_1.default) `
|
|
20
|
+
mutation GetOrCreateWorkflowRevisionFromGitRef(
|
|
21
|
+
$appId: ID!
|
|
22
|
+
$fileName: String!
|
|
23
|
+
$gitRef: String!
|
|
24
|
+
) {
|
|
25
|
+
workflowRevision {
|
|
26
|
+
getOrCreateWorkflowRevisionFromGitRef(
|
|
27
|
+
appId: $appId
|
|
28
|
+
fileName: $fileName
|
|
29
|
+
gitRef: $gitRef
|
|
30
|
+
) {
|
|
31
|
+
id
|
|
32
|
+
yamlConfig
|
|
33
|
+
blobSha
|
|
34
|
+
commitSha
|
|
35
|
+
createdAt
|
|
36
|
+
workflow {
|
|
37
|
+
id
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
`, {
|
|
43
|
+
appId,
|
|
44
|
+
fileName,
|
|
45
|
+
gitRef,
|
|
46
|
+
})
|
|
47
|
+
.toPromise());
|
|
48
|
+
return (data.workflowRevision?.getOrCreateWorkflowRevisionFromGitRef ??
|
|
49
|
+
undefined);
|
|
50
|
+
}
|
|
51
|
+
WorkflowRevisionMutation.getOrCreateWorkflowRevisionFromGitRefAsync = getOrCreateWorkflowRevisionFromGitRefAsync;
|
|
17
52
|
async function validateWorkflowYamlConfigAsync(graphqlClient, { appId, yamlConfig, }) {
|
|
18
53
|
await (0, client_1.withErrorHandlingAsync)(graphqlClient
|
|
19
54
|
.mutation((0, graphql_tag_1.default) `
|
|
@@ -8,6 +8,13 @@ export declare namespace WorkflowRunMutation {
|
|
|
8
8
|
}): Promise<{
|
|
9
9
|
id: string;
|
|
10
10
|
}>;
|
|
11
|
+
function createWorkflowRunFromGitRefAsync(graphqlClient: ExpoGraphqlClient, { workflowRevisionId, gitRef, inputs, }: {
|
|
12
|
+
workflowRevisionId: string;
|
|
13
|
+
gitRef: string;
|
|
14
|
+
inputs?: Record<string, any>;
|
|
15
|
+
}): Promise<{
|
|
16
|
+
id: string;
|
|
17
|
+
}>;
|
|
11
18
|
function cancelWorkflowRunAsync(graphqlClient: ExpoGraphqlClient, { workflowRunId, }: {
|
|
12
19
|
workflowRunId: string;
|
|
13
20
|
}): Promise<void>;
|
|
@@ -33,6 +33,33 @@ var WorkflowRunMutation;
|
|
|
33
33
|
return { id: data.workflowRun.createWorkflowRun.id };
|
|
34
34
|
}
|
|
35
35
|
WorkflowRunMutation.createWorkflowRunAsync = createWorkflowRunAsync;
|
|
36
|
+
async function createWorkflowRunFromGitRefAsync(graphqlClient, { workflowRevisionId, gitRef, inputs, }) {
|
|
37
|
+
const data = await (0, client_1.withErrorHandlingAsync)(graphqlClient
|
|
38
|
+
.mutation((0, graphql_tag_1.default) `
|
|
39
|
+
mutation CreateWorkflowRunFromGitRef(
|
|
40
|
+
$workflowRevisionId: ID!
|
|
41
|
+
$gitRef: String!
|
|
42
|
+
$inputs: JSONObject
|
|
43
|
+
) {
|
|
44
|
+
workflowRun {
|
|
45
|
+
createWorkflowRunFromGitRef(
|
|
46
|
+
workflowRevisionId: $workflowRevisionId
|
|
47
|
+
gitRef: $gitRef
|
|
48
|
+
inputs: $inputs
|
|
49
|
+
) {
|
|
50
|
+
id
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
`, {
|
|
55
|
+
workflowRevisionId,
|
|
56
|
+
gitRef,
|
|
57
|
+
inputs,
|
|
58
|
+
})
|
|
59
|
+
.toPromise());
|
|
60
|
+
return { id: data.workflowRun.createWorkflowRunFromGitRef.id };
|
|
61
|
+
}
|
|
62
|
+
WorkflowRunMutation.createWorkflowRunFromGitRefAsync = createWorkflowRunFromGitRefAsync;
|
|
36
63
|
async function cancelWorkflowRunAsync(graphqlClient, { workflowRunId, }) {
|
|
37
64
|
await (0, client_1.withErrorHandlingAsync)(graphqlClient
|
|
38
65
|
.mutation((0, graphql_tag_1.default) `
|
package/build/worker/assets.d.ts
CHANGED
|
@@ -14,6 +14,11 @@ export interface AssetFileEntry {
|
|
|
14
14
|
}
|
|
15
15
|
/** Collects assets from a given target path */
|
|
16
16
|
export declare function collectAssetsAsync(assetPath: string | undefined, options: AssetMapOptions): Promise<AssetFileEntry[]>;
|
|
17
|
+
export interface RoutesConfigEntry {
|
|
18
|
+
headers?: Record<string, unknown>;
|
|
19
|
+
redirects?: Record<string, unknown>[];
|
|
20
|
+
}
|
|
21
|
+
export declare function getRoutesConfigAsync(assetPath: string | undefined): Promise<RoutesConfigEntry | null>;
|
|
17
22
|
/** Mapping of normalized file paths to a SHA512 hash */
|
|
18
23
|
export type AssetMap = Record<string, string | {
|
|
19
24
|
sha512: string;
|
package/build/worker/assets.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.packFilesIterableAsync = exports.listWorkerFilesAsync = exports.createManifestAsync = exports.assetsToAssetsMap = exports.collectAssetsAsync = void 0;
|
|
3
|
+
exports.packFilesIterableAsync = exports.listWorkerFilesAsync = exports.createManifestAsync = exports.assetsToAssetsMap = exports.getRoutesConfigAsync = exports.collectAssetsAsync = void 0;
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
5
|
const env_1 = require("@expo/env");
|
|
6
6
|
const mime_1 = tslib_1.__importDefault(require("mime"));
|
|
@@ -12,6 +12,7 @@ const node_path_1 = tslib_1.__importDefault(require("node:path"));
|
|
|
12
12
|
const promises_1 = require("node:stream/promises");
|
|
13
13
|
const tar_stream_1 = require("tar-stream");
|
|
14
14
|
const EnvironmentVariablesQuery_1 = require("../graphql/queries/EnvironmentVariablesQuery");
|
|
15
|
+
const EXPO_ROUTES_PATHS = new Set(['_expo/routes.json', '_expo/.routes.json', '.expo-routes.json']);
|
|
15
16
|
/** Returns whether a file or folder is ignored */
|
|
16
17
|
function isIgnoredName(name) {
|
|
17
18
|
switch (name) {
|
|
@@ -89,6 +90,9 @@ async function collectAssetsAsync(assetPath, options) {
|
|
|
89
90
|
if (file.size > options.maxFileSize) {
|
|
90
91
|
throw new Error(`Upload of "${file.normalizedPath}" aborted: File size is greater than the upload limit (>500MB)`);
|
|
91
92
|
}
|
|
93
|
+
else if (EXPO_ROUTES_PATHS.has(file.normalizedPath)) {
|
|
94
|
+
continue;
|
|
95
|
+
}
|
|
92
96
|
const sha512$ = computeSha512HashAsync(file.path);
|
|
93
97
|
const contentType$ = determineMimeTypeAsync(file.path);
|
|
94
98
|
assets.push({
|
|
@@ -103,6 +107,25 @@ async function collectAssetsAsync(assetPath, options) {
|
|
|
103
107
|
return assets;
|
|
104
108
|
}
|
|
105
109
|
exports.collectAssetsAsync = collectAssetsAsync;
|
|
110
|
+
async function getRoutesConfigAsync(assetPath) {
|
|
111
|
+
if (assetPath) {
|
|
112
|
+
for (const candidatePath of EXPO_ROUTES_PATHS) {
|
|
113
|
+
const targetPath = node_path_1.default.resolve(assetPath, candidatePath);
|
|
114
|
+
let json;
|
|
115
|
+
try {
|
|
116
|
+
json = JSON.parse(await node_fs_1.default.promises.readFile(targetPath, 'utf8'));
|
|
117
|
+
}
|
|
118
|
+
catch {
|
|
119
|
+
continue;
|
|
120
|
+
}
|
|
121
|
+
if (typeof json === 'object' && json) {
|
|
122
|
+
return json;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
return null;
|
|
127
|
+
}
|
|
128
|
+
exports.getRoutesConfigAsync = getRoutesConfigAsync;
|
|
106
129
|
/** Converts array of asset entries into AssetMap (as sent to deployment-api) */
|
|
107
130
|
function assetsToAssetsMap(assets) {
|
|
108
131
|
return assets.reduce((map, entry) => {
|
package/oclif.manifest.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "16.
|
|
2
|
+
"version": "16.21.0",
|
|
3
3
|
"commands": {
|
|
4
4
|
"analytics": {
|
|
5
5
|
"id": "analytics",
|
|
@@ -4235,7 +4235,7 @@
|
|
|
4235
4235
|
},
|
|
4236
4236
|
"workflow:run": {
|
|
4237
4237
|
"id": "workflow:run",
|
|
4238
|
-
"description": "run an EAS workflow",
|
|
4238
|
+
"description": "run an EAS workflow. The entire local project directory will be packaged and uploaded to EAS servers for the workflow run, unless the --ref flag is used.",
|
|
4239
4239
|
"strict": true,
|
|
4240
4240
|
"pluginName": "eas-cli",
|
|
4241
4241
|
"pluginAlias": "eas-cli",
|
|
@@ -4267,6 +4267,13 @@
|
|
|
4267
4267
|
"field"
|
|
4268
4268
|
]
|
|
4269
4269
|
},
|
|
4270
|
+
"ref": {
|
|
4271
|
+
"name": "ref",
|
|
4272
|
+
"type": "option",
|
|
4273
|
+
"summary": "Git reference to run the workflow on",
|
|
4274
|
+
"description": "The git reference must exist in the project's git repository, and the workflow file must exist at that reference. When this flag is used, the local project is not uploaded; instead, the workflow is run from the exact state of the project at the chosen reference.",
|
|
4275
|
+
"multiple": false
|
|
4276
|
+
},
|
|
4270
4277
|
"json": {
|
|
4271
4278
|
"name": "json",
|
|
4272
4279
|
"type": "boolean",
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "eas-cli",
|
|
3
3
|
"description": "EAS command line tool",
|
|
4
|
-
"version": "16.
|
|
4
|
+
"version": "16.21.0",
|
|
5
5
|
"author": "Expo <support@expo.dev>",
|
|
6
6
|
"bin": {
|
|
7
7
|
"eas": "./bin/run"
|
|
@@ -241,5 +241,5 @@
|
|
|
241
241
|
"node": "20.11.0",
|
|
242
242
|
"yarn": "1.22.21"
|
|
243
243
|
},
|
|
244
|
-
"gitHead": "
|
|
244
|
+
"gitHead": "5ba16dbc6754febcef28a66ba3e93174b844bc45"
|
|
245
245
|
}
|