@qawolf/ci-sdk 2.1.0 → 2.5.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 +15 -0
- package/dist/index.cjs +401 -184
- package/dist/index.cjs.map +7 -1
- package/dist/index.d.ts +4 -534
- package/dist/index.js +376 -182
- package/dist/index.js.map +7 -1
- package/dist/lib/api/ci-greenlight-bug-data.d.ts +67 -0
- package/dist/lib/api/ci-greenlight.d.ts +76 -0
- package/dist/lib/api/generate-signed-url-for-run-inputs-executables.d.ts +4 -0
- package/dist/lib/api/generate-signed-url-for-team-storage.d.ts +4 -0
- package/dist/lib/api/index.d.ts +2 -0
- package/dist/lib/api/log.d.ts +6 -0
- package/dist/lib/api/signed-url.d.ts +11 -0
- package/dist/lib/api-types.d.ts +5 -0
- package/dist/lib/other.d.ts +5 -0
- package/dist/lib/sdk/defaults/fetch.d.ts +1 -0
- package/dist/lib/sdk/defaults/log.d.ts +2 -0
- package/dist/lib/sdk/defaults/serviceBase.d.ts +1 -0
- package/dist/lib/sdk/defaults/userAgent.d.ts +1 -0
- package/dist/lib/sdk/dependencies.d.ts +7 -0
- package/dist/lib/sdk/domain/attemptDeploy/deployConfig.d.ts +37 -0
- package/dist/lib/sdk/domain/attemptDeploy/deploySuccessWireResponse.d.ts +39 -0
- package/dist/lib/sdk/domain/attemptDeploy/handleSuccessResponse.d.ts +3 -0
- package/dist/lib/sdk/domain/attemptDeploy/index.d.ts +4 -0
- package/dist/lib/sdk/domain/attemptDeploy/mapDeploySuccessResponse.d.ts +3 -0
- package/dist/lib/sdk/domain/attemptDeploy/parseDeploySuccessWireResponse.d.ts +2 -0
- package/dist/lib/sdk/domain/attemptDeploy/types.d.ts +129 -0
- package/dist/lib/sdk/domain/generateSignedUrls/generate-signed-url-for-run-inputs-executables.d.ts +4 -0
- package/dist/lib/sdk/domain/generateSignedUrls/generate-signed-url-for-team-storage.d.ts +16 -0
- package/dist/lib/sdk/domain/generateSignedUrls/types.d.ts +28 -0
- package/dist/lib/sdk/domain/notifyTerminatedEphemeralEnvironment/index.d.ts +4 -0
- package/dist/lib/sdk/domain/notifyTerminatedEphemeralEnvironment/types.d.ts +48 -0
- package/dist/lib/sdk/domain/pollCiGreenlight/buildCompletedRunResult.d.ts +8 -0
- package/dist/lib/sdk/domain/pollCiGreenlight/consts.d.ts +7 -0
- package/dist/lib/sdk/domain/pollCiGreenlight/index.d.ts +4 -0
- package/dist/lib/sdk/domain/pollCiGreenlight/iterator.d.ts +43 -0
- package/dist/lib/sdk/domain/pollCiGreenlight/logging.d.ts +25 -0
- package/dist/lib/sdk/domain/pollCiGreenlight/mapIteratorAbortToGreenlightStatus.d.ts +7 -0
- package/dist/lib/sdk/domain/pollCiGreenlight/types.d.ts +145 -0
- package/dist/lib/sdk/index.d.ts +26 -0
- package/package.json +13 -12
- package/dist/index.d.cts +0 -534
package/dist/index.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
/* Built with @qawolf/platform-builder@1.2.2 */
|
|
1
2
|
var __defProp = Object.defineProperty;
|
|
2
3
|
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
3
4
|
|
|
@@ -12,10 +13,7 @@ function pluralize(count) {
|
|
|
12
13
|
__name(pluralize, "pluralize");
|
|
13
14
|
var buildFetchWithTimeout = /* @__PURE__ */ __name((fetch, defaultTimeoutMs) => async (...args) => {
|
|
14
15
|
const signal = args[1]?.signal ?? AbortSignal.timeout(defaultTimeoutMs);
|
|
15
|
-
return fetch(args[0], {
|
|
16
|
-
...args[1],
|
|
17
|
-
signal
|
|
18
|
-
});
|
|
16
|
+
return fetch(args[0], { ...args[1], signal });
|
|
19
17
|
}, "buildFetchWithTimeout");
|
|
20
18
|
|
|
21
19
|
// src/lib/sdk/defaults/fetch.ts
|
|
@@ -39,13 +37,61 @@ var defaultServiceBase = "https://app.qawolf.com/";
|
|
|
39
37
|
|
|
40
38
|
// package.json
|
|
41
39
|
var package_default = {
|
|
42
|
-
|
|
40
|
+
name: "@qawolf/ci-sdk",
|
|
41
|
+
version: "2.5.0",
|
|
42
|
+
private: false,
|
|
43
|
+
description: "A simple SDK for interacting with QAWolf in CI scripts.",
|
|
44
|
+
keywords: [],
|
|
45
|
+
license: "MIT",
|
|
46
|
+
author: "Jules Sam. Randolph<jules@qawolf.com>",
|
|
47
|
+
files: [
|
|
48
|
+
"/dist",
|
|
49
|
+
"/README.md"
|
|
50
|
+
],
|
|
51
|
+
type: "module",
|
|
52
|
+
sideEffects: false,
|
|
53
|
+
exports: {
|
|
54
|
+
".": {
|
|
55
|
+
types: "./dist/index.d.ts",
|
|
56
|
+
require: "./dist/index.cjs",
|
|
57
|
+
import: "./dist/index.js",
|
|
58
|
+
default: "./dist/index.js"
|
|
59
|
+
}
|
|
60
|
+
},
|
|
61
|
+
scripts: {
|
|
62
|
+
build: "platform-builder --config platformBuilder.config.ts --config platformBuilder.cjs.config.ts",
|
|
63
|
+
"lint:ci": "npm run lint:first-half; FIRST_HALF_EXIT=$?; npm run lint:second-half && exit $FIRST_HALF_EXIT",
|
|
64
|
+
"lint:dev": "npm run lint:first-half",
|
|
65
|
+
"lint:first-half": "eslint . --fix --quiet && oxfmt --write .",
|
|
66
|
+
"lint:second-half": "dpdm --exit-code circular:1 --no-tree --no-warning --transform --include='.*' --exclude='/(dist|node_modules)/' '**/*'",
|
|
67
|
+
prepublishOnly: "nx run ci-sdk:build",
|
|
68
|
+
test: 'NODE_OPTIONS="--experimental-vm-modules" NODE_NO_WARNINGS=1 jest',
|
|
69
|
+
"tsc:check": "tsc --noEmit"
|
|
70
|
+
},
|
|
71
|
+
dependencies: {
|
|
72
|
+
"@qawolf/ci-utils": "^1.1.2",
|
|
73
|
+
"@sinonjs/fake-timers": "^10.3.0",
|
|
74
|
+
tslib: "^2.6.2"
|
|
75
|
+
},
|
|
76
|
+
devDependencies: {
|
|
77
|
+
"@qawolf/platform-builder": "^1.2.2",
|
|
78
|
+
tsx: "^4.19.4",
|
|
79
|
+
typescript: "^5.9.3"
|
|
80
|
+
},
|
|
81
|
+
engines: {
|
|
82
|
+
node: ">=20"
|
|
83
|
+
}
|
|
84
|
+
};
|
|
43
85
|
|
|
44
86
|
// src/lib/sdk/defaults/userAgent.ts
|
|
45
87
|
var defaultUserAgent = `ci-sdk/${package_default.version}`;
|
|
46
88
|
|
|
47
89
|
// src/lib/api/log.ts
|
|
48
|
-
async function logFetchError({
|
|
90
|
+
async function logFetchError({
|
|
91
|
+
log,
|
|
92
|
+
methodName,
|
|
93
|
+
response
|
|
94
|
+
}) {
|
|
49
95
|
if (response.ok) return;
|
|
50
96
|
const { eventId, failureMessage } = await (async () => {
|
|
51
97
|
try {
|
|
@@ -70,7 +116,9 @@ async function logFetchError({ log, methodName, response }) {
|
|
|
70
116
|
const eventIdSuffix = eventId ? ` (Event ID: ${eventId})` : "";
|
|
71
117
|
const messageSuffix = failureMessage ? `: ${failureMessage}` : "";
|
|
72
118
|
const statusText = response.status >= 500 ? "Server Error" : response.statusText || "Unknown Error";
|
|
73
|
-
log.error(
|
|
119
|
+
log.error(
|
|
120
|
+
`\u274C [${methodName}] ${response.status} ${statusText}${eventIdSuffix}${messageSuffix}`
|
|
121
|
+
);
|
|
74
122
|
}
|
|
75
123
|
__name(logFetchError, "logFetchError");
|
|
76
124
|
|
|
@@ -80,6 +128,7 @@ async function handleSuccessResponse(data, log) {
|
|
|
80
128
|
const skippedTriggers = data.skippedTriggers ?? [];
|
|
81
129
|
const skippedDeployment = data.skippedDeployment;
|
|
82
130
|
const isPreviewDeployment = environment && !environment.isStatic;
|
|
131
|
+
if (data.warning) log.warn(`\u26A0\uFE0F ${data.warning}`);
|
|
83
132
|
if (environment) {
|
|
84
133
|
const logPrefix = environment.isStatic ? "Static environment" : "Preview environment";
|
|
85
134
|
log.info(`${logPrefix}: ${environment.alias} (id: ${environment.id})`);
|
|
@@ -87,13 +136,13 @@ async function handleSuccessResponse(data, log) {
|
|
|
87
136
|
if (results.length === 0) {
|
|
88
137
|
const skipMessages = [
|
|
89
138
|
...skippedTriggers.map((trigger) => trigger.message),
|
|
90
|
-
...skippedDeployment ? [
|
|
91
|
-
skippedDeployment.message
|
|
92
|
-
] : []
|
|
139
|
+
...skippedDeployment ? [skippedDeployment.message] : []
|
|
93
140
|
];
|
|
94
141
|
const skipDetail = skipMessages.length > 0 ? ` ${skipMessages.join(" ")}` : "";
|
|
95
142
|
if (isPreviewDeployment) {
|
|
96
|
-
log.info(
|
|
143
|
+
log.info(
|
|
144
|
+
`\u2705 Deployment notification was successful. No run was created for this deployment.${skipDetail}`
|
|
145
|
+
);
|
|
97
146
|
return {
|
|
98
147
|
environmentId: environment.id,
|
|
99
148
|
outcome: "success",
|
|
@@ -108,7 +157,9 @@ async function handleSuccessResponse(data, log) {
|
|
|
108
157
|
skippedTriggers
|
|
109
158
|
};
|
|
110
159
|
}
|
|
111
|
-
log.warn(
|
|
160
|
+
log.warn(
|
|
161
|
+
skippedDeployment ? `\u26A0\uFE0F No run was created for this deployment.${skipDetail}` : `\u26A0\uFE0F No trigger matched the request. Please make sure there is at least one active test in the QA Wolf environment, or contact support.`
|
|
162
|
+
);
|
|
112
163
|
return {
|
|
113
164
|
outcome: "skipped",
|
|
114
165
|
skippedDeployment
|
|
@@ -116,45 +167,43 @@ async function handleSuccessResponse(data, log) {
|
|
|
116
167
|
}
|
|
117
168
|
if (!environment) {
|
|
118
169
|
log.error(`\u{1F6AB} No environment matched the request. Please contact support.`);
|
|
119
|
-
return {
|
|
120
|
-
failReason: "no-environment",
|
|
121
|
-
outcome: "failed"
|
|
122
|
-
};
|
|
170
|
+
return { failReason: "no-environment", outcome: "failed" };
|
|
123
171
|
}
|
|
124
172
|
const unrecognizedResult = results.find((result) => "unrecognized" in result);
|
|
125
173
|
if (unrecognizedResult) {
|
|
126
|
-
log.error(
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
};
|
|
174
|
+
log.error(
|
|
175
|
+
`\u{1F6AB} The deployment response contained an unrecognized result. Please upgrade @qawolf/ci-sdk.`
|
|
176
|
+
);
|
|
177
|
+
return { failReason: "unknown-result", outcome: "failed" };
|
|
131
178
|
}
|
|
132
179
|
const failedTrigger = results.find((result) => "failureReason" in result);
|
|
133
180
|
if (failedTrigger) {
|
|
134
|
-
log.error(
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
};
|
|
181
|
+
log.error(
|
|
182
|
+
`\u{1F6AB} Run could not be created. Reason: "${failedTrigger.failureMessage ?? failedTrigger.failureReason}". Please contact support.`
|
|
183
|
+
);
|
|
184
|
+
return { failReason: "run-could-not-be-created", outcome: "failed" };
|
|
139
185
|
}
|
|
140
186
|
const duplicateSuite = results.find((result) => "duplicateSuiteId" in result);
|
|
141
187
|
if (duplicateSuite) {
|
|
142
|
-
log.info(
|
|
188
|
+
log.info(
|
|
189
|
+
`\u2705 Deployment notification was successful. Previous run ID: ${duplicateSuite.duplicateSuiteId} already exists for this deployment.`
|
|
190
|
+
);
|
|
143
191
|
return {
|
|
144
192
|
environmentId: environment.id,
|
|
145
193
|
outcome: "success",
|
|
146
194
|
runId: duplicateSuite.duplicateSuiteId
|
|
147
195
|
};
|
|
148
196
|
}
|
|
149
|
-
const successfulTrigger = results.find(
|
|
197
|
+
const successfulTrigger = results.find(
|
|
198
|
+
(result) => "createdSuiteId" in result
|
|
199
|
+
);
|
|
150
200
|
if (!successfulTrigger) {
|
|
151
201
|
log.error(`\u{1F6AB} Run could not be created. Please contact support.`);
|
|
152
|
-
return {
|
|
153
|
-
failReason: "run-could-not-be-created",
|
|
154
|
-
outcome: "failed"
|
|
155
|
-
};
|
|
202
|
+
return { failReason: "run-could-not-be-created", outcome: "failed" };
|
|
156
203
|
}
|
|
157
|
-
log.info(
|
|
204
|
+
log.info(
|
|
205
|
+
`\u2705 Deployment notification was successful. Run created with ID: ${successfulTrigger.createdSuiteId}`
|
|
206
|
+
);
|
|
158
207
|
return {
|
|
159
208
|
environmentId: environment.id,
|
|
160
209
|
outcome: "success",
|
|
@@ -165,29 +214,28 @@ __name(handleSuccessResponse, "handleSuccessResponse");
|
|
|
165
214
|
|
|
166
215
|
// src/lib/sdk/domain/attemptDeploy/mapDeploySuccessResponse.ts
|
|
167
216
|
function mapSuiteResult(result) {
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
217
|
+
switch (result.outcome) {
|
|
218
|
+
case "created":
|
|
219
|
+
return {
|
|
220
|
+
createdSuiteId: result.created_suite_id,
|
|
221
|
+
triggerId: result.trigger_id
|
|
222
|
+
};
|
|
223
|
+
case "failed":
|
|
224
|
+
return {
|
|
225
|
+
failureCode: result.failure_code,
|
|
226
|
+
failureMessage: result.failure_message,
|
|
227
|
+
failureReason: result.failure_reason,
|
|
228
|
+
triggerId: result.trigger_id
|
|
229
|
+
};
|
|
230
|
+
case "skipped":
|
|
231
|
+
return {
|
|
232
|
+
duplicateSuiteId: result.duplicate_suite_id,
|
|
233
|
+
skipReason: result.skip_reason,
|
|
234
|
+
triggerId: result.trigger_id
|
|
235
|
+
};
|
|
236
|
+
default:
|
|
237
|
+
return { triggerId: result.trigger_id, unrecognized: true };
|
|
186
238
|
}
|
|
187
|
-
return {
|
|
188
|
-
triggerId: result.trigger_id,
|
|
189
|
-
unrecognized: true
|
|
190
|
-
};
|
|
191
239
|
}
|
|
192
240
|
__name(mapSuiteResult, "mapSuiteResult");
|
|
193
241
|
function mapDeploySuccessResponse(wire) {
|
|
@@ -203,7 +251,8 @@ function mapDeploySuccessResponse(wire) {
|
|
|
203
251
|
message: trigger.message,
|
|
204
252
|
reason: trigger.reason,
|
|
205
253
|
triggerId: trigger.trigger_id
|
|
206
|
-
}))
|
|
254
|
+
})),
|
|
255
|
+
warning: wire.warning
|
|
207
256
|
};
|
|
208
257
|
}
|
|
209
258
|
__name(mapDeploySuccessResponse, "mapDeploySuccessResponse");
|
|
@@ -213,22 +262,32 @@ function isRecord(value) {
|
|
|
213
262
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
214
263
|
}
|
|
215
264
|
__name(isRecord, "isRecord");
|
|
265
|
+
function isOptionalString(value) {
|
|
266
|
+
return value === void 0 || typeof value === "string";
|
|
267
|
+
}
|
|
268
|
+
__name(isOptionalString, "isOptionalString");
|
|
216
269
|
function isWireSuiteResult(value) {
|
|
217
270
|
if (!isRecord(value)) return false;
|
|
218
271
|
if (typeof value.trigger_id !== "string") return false;
|
|
219
|
-
if (
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
272
|
+
if (!isOptionalString(value.outcome)) return false;
|
|
273
|
+
switch (value.outcome) {
|
|
274
|
+
case "created":
|
|
275
|
+
return typeof value.created_suite_id === "string";
|
|
276
|
+
case "failed":
|
|
277
|
+
return typeof value.failure_reason === "string" && isOptionalString(value.failure_code) && isOptionalString(value.failure_message);
|
|
278
|
+
case "skipped":
|
|
279
|
+
return typeof value.duplicate_suite_id === "string" && typeof value.skip_reason === "string";
|
|
280
|
+
default:
|
|
281
|
+
return true;
|
|
223
282
|
}
|
|
224
|
-
return true;
|
|
225
283
|
}
|
|
226
284
|
__name(isWireSuiteResult, "isWireSuiteResult");
|
|
227
285
|
function isEnvironment(value) {
|
|
228
286
|
if (!isRecord(value)) return false;
|
|
229
287
|
if (typeof value.id !== "string") return false;
|
|
230
288
|
if (typeof value.isStatic !== "boolean") return false;
|
|
231
|
-
if (value.alias !== void 0 && typeof value.alias !== "string")
|
|
289
|
+
if (value.alias !== void 0 && typeof value.alias !== "string")
|
|
290
|
+
return false;
|
|
232
291
|
return true;
|
|
233
292
|
}
|
|
234
293
|
__name(isEnvironment, "isEnvironment");
|
|
@@ -244,10 +303,15 @@ function isSkippedTrigger(value) {
|
|
|
244
303
|
__name(isSkippedTrigger, "isSkippedTrigger");
|
|
245
304
|
function isDeploySuccessWireResponse(value) {
|
|
246
305
|
if (!isRecord(value)) return false;
|
|
247
|
-
if (value.environment !== void 0 && !isEnvironment(value.environment))
|
|
248
|
-
|
|
249
|
-
if (value.
|
|
250
|
-
|
|
306
|
+
if (value.environment !== void 0 && !isEnvironment(value.environment))
|
|
307
|
+
return false;
|
|
308
|
+
if (!Array.isArray(value.results) || !value.results.every(isWireSuiteResult))
|
|
309
|
+
return false;
|
|
310
|
+
if (value.skipped_deployment !== void 0 && !isSkippedDeployment(value.skipped_deployment))
|
|
311
|
+
return false;
|
|
312
|
+
if (value.skipped_triggers !== void 0 && (!Array.isArray(value.skipped_triggers) || !value.skipped_triggers.every(isSkippedTrigger)))
|
|
313
|
+
return false;
|
|
314
|
+
if (!isOptionalString(value.warning)) return false;
|
|
251
315
|
return true;
|
|
252
316
|
}
|
|
253
317
|
__name(isDeploySuccessWireResponse, "isDeploySuccessWireResponse");
|
|
@@ -262,34 +326,38 @@ async function attemptNotifyDeploy(deps, apiConfig, config) {
|
|
|
262
326
|
let response;
|
|
263
327
|
let bodyText;
|
|
264
328
|
try {
|
|
265
|
-
response = await localFetch(
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
329
|
+
response = await localFetch(
|
|
330
|
+
new URL("/api/webhooks/deploy_success", apiConfig.serviceBase),
|
|
331
|
+
{
|
|
332
|
+
body: JSON.stringify({
|
|
333
|
+
branch: config.branch,
|
|
334
|
+
commit_url: config.commitUrl,
|
|
335
|
+
deduplication_key: config.deduplicationKey,
|
|
336
|
+
deployment_type: config.deploymentType,
|
|
337
|
+
deployment_url: config.deploymentUrl,
|
|
338
|
+
..."ephemeralEnvironment" in config ? {
|
|
339
|
+
ephemeral_environment: config.ephemeralEnvironment
|
|
340
|
+
} : "hostingService" in config && {
|
|
341
|
+
hosting_service: config.hostingService,
|
|
342
|
+
merge_request_number: config.hostingService === "GitLab" ? config.mergeRequestNumber : void 0,
|
|
343
|
+
pull_request_number: config.hostingService === "GitHub" ? config.pullRequestNumber : void 0,
|
|
344
|
+
repository: config.repository
|
|
345
|
+
},
|
|
346
|
+
sha: config.sha,
|
|
347
|
+
variables: config.variables,
|
|
348
|
+
workspaceId: config.workspaceId
|
|
349
|
+
}),
|
|
350
|
+
headers: {
|
|
351
|
+
Authorization: `Bearer ${apiConfig.apiKey}`,
|
|
352
|
+
"Content-Type": "application/json",
|
|
353
|
+
"User-Agent": apiConfig.userAgent
|
|
279
354
|
},
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
"User-Agent": apiConfig.userAgent
|
|
287
|
-
},
|
|
288
|
-
method: "POST",
|
|
289
|
-
// Override default timeout to 5 minutes. This gives extra room
|
|
290
|
-
// for both (1) waiting for reconciliation (2) creating the run.
|
|
291
|
-
signal: AbortSignal.timeout(5 * 60 * 1e3)
|
|
292
|
-
});
|
|
355
|
+
method: "POST",
|
|
356
|
+
// Override default timeout to 5 minutes. This gives extra room
|
|
357
|
+
// for both (1) waiting for reconciliation (2) creating the run.
|
|
358
|
+
signal: AbortSignal.timeout(5 * 60 * 1e3)
|
|
359
|
+
}
|
|
360
|
+
);
|
|
293
361
|
if (!response.ok) return handleErrorResponse(response, log);
|
|
294
362
|
bodyText = await response.text();
|
|
295
363
|
} catch {
|
|
@@ -308,7 +376,10 @@ async function attemptNotifyDeploy(deps, apiConfig, config) {
|
|
|
308
376
|
}
|
|
309
377
|
const wire = parseDeploySuccessWireResponse(rawBody);
|
|
310
378
|
if (wire === "invalid") {
|
|
311
|
-
return abortInvalidResponseBody(
|
|
379
|
+
return abortInvalidResponseBody(
|
|
380
|
+
log,
|
|
381
|
+
"the response body did not match the expected shape"
|
|
382
|
+
);
|
|
312
383
|
}
|
|
313
384
|
const data = mapDeploySuccessResponse(wire);
|
|
314
385
|
return handleSuccessResponse(data, log);
|
|
@@ -344,17 +415,45 @@ async function handleErrorResponse(response, log) {
|
|
|
344
415
|
}
|
|
345
416
|
__name(handleErrorResponse, "handleErrorResponse");
|
|
346
417
|
|
|
418
|
+
// src/lib/api/signed-url.ts
|
|
419
|
+
var signedUrlPaths = {
|
|
420
|
+
runInputsExecutables: "/api/v0/run-inputs-executables-signed-urls",
|
|
421
|
+
teamStorage: "/api/v0/team-storage-signed-url"
|
|
422
|
+
};
|
|
423
|
+
function buildSignedUrl({
|
|
424
|
+
destinationFilePath,
|
|
425
|
+
endpoint,
|
|
426
|
+
serviceBase,
|
|
427
|
+
workspaceId
|
|
428
|
+
}) {
|
|
429
|
+
const url = new URL(signedUrlPaths[endpoint], serviceBase);
|
|
430
|
+
if (destinationFilePath !== void 0)
|
|
431
|
+
url.searchParams.set("file", destinationFilePath);
|
|
432
|
+
if (workspaceId !== void 0)
|
|
433
|
+
url.searchParams.set("workspaceId", workspaceId);
|
|
434
|
+
return url;
|
|
435
|
+
}
|
|
436
|
+
__name(buildSignedUrl, "buildSignedUrl");
|
|
437
|
+
|
|
347
438
|
// src/lib/api/generate-signed-url-for-run-inputs-executables.ts
|
|
348
|
-
async function callGenerateSignedUrlForRunInputsExecutablesStorage({ apiKey, serviceBase, userAgent }, { destinationFilePath }, { fetch: localFetch, log }) {
|
|
439
|
+
async function callGenerateSignedUrlForRunInputsExecutablesStorage({ apiKey, serviceBase, userAgent }, { destinationFilePath, workspaceId }, { fetch: localFetch, log }) {
|
|
349
440
|
try {
|
|
350
|
-
const response = await localFetch(
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
441
|
+
const response = await localFetch(
|
|
442
|
+
buildSignedUrl({
|
|
443
|
+
destinationFilePath,
|
|
444
|
+
endpoint: "runInputsExecutables",
|
|
445
|
+
serviceBase,
|
|
446
|
+
workspaceId
|
|
447
|
+
}),
|
|
448
|
+
{
|
|
449
|
+
headers: {
|
|
450
|
+
Authorization: `Bearer ${apiKey}`,
|
|
451
|
+
"Content-Type": "application/json",
|
|
452
|
+
"User-Agent": userAgent
|
|
453
|
+
},
|
|
454
|
+
method: "GET"
|
|
455
|
+
}
|
|
456
|
+
);
|
|
358
457
|
if (response.status === 200) {
|
|
359
458
|
const json = await response.json();
|
|
360
459
|
return {
|
|
@@ -395,18 +494,28 @@ async function generateSignedUrlForRunInputsExecutablesStorage(deps, apiConfig,
|
|
|
395
494
|
success: false
|
|
396
495
|
};
|
|
397
496
|
}
|
|
398
|
-
const responseState = await callGenerateSignedUrlForRunInputsExecutablesStorage(
|
|
497
|
+
const responseState = await callGenerateSignedUrlForRunInputsExecutablesStorage(
|
|
498
|
+
apiConfig,
|
|
499
|
+
config,
|
|
500
|
+
deps
|
|
501
|
+
);
|
|
399
502
|
if (!responseState.success) {
|
|
400
503
|
let abortReason = "XXX-other-http-code";
|
|
401
504
|
if (responseState.httpStatus >= 500) {
|
|
402
505
|
abortReason = "5XX-server-error";
|
|
403
|
-
log.error(
|
|
506
|
+
log.error(
|
|
507
|
+
`\u{1F6AB} Unrecoverable error (status ${responseState.httpStatus}) when generating signed upload url: aborting.`
|
|
508
|
+
);
|
|
404
509
|
} else {
|
|
405
510
|
if (responseState.httpStatus === 400) abortReason = "400-invalid-request";
|
|
406
|
-
else if (responseState.httpStatus === 401)
|
|
511
|
+
else if (responseState.httpStatus === 401)
|
|
512
|
+
abortReason = "401-invalid-credentials";
|
|
407
513
|
else if (responseState.httpStatus === 403) abortReason = "403-forbidden";
|
|
408
|
-
else if (responseState.httpStatus === 0)
|
|
409
|
-
|
|
514
|
+
else if (responseState.httpStatus === 0)
|
|
515
|
+
abortReason = "client-network-error";
|
|
516
|
+
log.error(
|
|
517
|
+
`\u{1F6AB} Unrecoverable error (status ${responseState.httpStatus}) when generating signed upload url: ${responseState.errorMessage ? `${responseState.errorMessage}.` : ""} aborting.`
|
|
518
|
+
);
|
|
410
519
|
}
|
|
411
520
|
return {
|
|
412
521
|
abortReason,
|
|
@@ -425,16 +534,24 @@ async function generateSignedUrlForRunInputsExecutablesStorage(deps, apiConfig,
|
|
|
425
534
|
__name(generateSignedUrlForRunInputsExecutablesStorage, "generateSignedUrlForRunInputsExecutablesStorage");
|
|
426
535
|
|
|
427
536
|
// src/lib/api/generate-signed-url-for-team-storage.ts
|
|
428
|
-
async function callGenerateSignedUrlForTempTeamStorage({ apiKey, serviceBase, userAgent }, { destinationFilePath }, { fetch: localFetch, log }) {
|
|
537
|
+
async function callGenerateSignedUrlForTempTeamStorage({ apiKey, serviceBase, userAgent }, { destinationFilePath, workspaceId }, { fetch: localFetch, log }) {
|
|
429
538
|
try {
|
|
430
|
-
const response = await localFetch(
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
539
|
+
const response = await localFetch(
|
|
540
|
+
buildSignedUrl({
|
|
541
|
+
destinationFilePath,
|
|
542
|
+
endpoint: "teamStorage",
|
|
543
|
+
serviceBase,
|
|
544
|
+
workspaceId
|
|
545
|
+
}),
|
|
546
|
+
{
|
|
547
|
+
headers: {
|
|
548
|
+
Authorization: `Bearer ${apiKey}`,
|
|
549
|
+
"Content-Type": "application/json",
|
|
550
|
+
"User-Agent": userAgent
|
|
551
|
+
},
|
|
552
|
+
method: "GET"
|
|
553
|
+
}
|
|
554
|
+
);
|
|
438
555
|
if (response.status === 200) {
|
|
439
556
|
const json = await response.json();
|
|
440
557
|
return {
|
|
@@ -475,18 +592,28 @@ async function generateSignedUrlForTempTeamStorage(deps, apiConfig, config) {
|
|
|
475
592
|
success: false
|
|
476
593
|
};
|
|
477
594
|
}
|
|
478
|
-
const responseState = await callGenerateSignedUrlForTempTeamStorage(
|
|
595
|
+
const responseState = await callGenerateSignedUrlForTempTeamStorage(
|
|
596
|
+
apiConfig,
|
|
597
|
+
config,
|
|
598
|
+
deps
|
|
599
|
+
);
|
|
479
600
|
if (!responseState.success) {
|
|
480
601
|
let abortReason = "XXX-other-http-code";
|
|
481
602
|
if (responseState.httpStatus >= 500) {
|
|
482
603
|
abortReason = "5XX-server-error";
|
|
483
|
-
log.error(
|
|
604
|
+
log.error(
|
|
605
|
+
`\u{1F6AB} Unrecoverable error (status ${responseState.httpStatus}) when generating signed upload url: aborting.`
|
|
606
|
+
);
|
|
484
607
|
} else {
|
|
485
608
|
if (responseState.httpStatus === 400) abortReason = "400-invalid-request";
|
|
486
|
-
else if (responseState.httpStatus === 401)
|
|
609
|
+
else if (responseState.httpStatus === 401)
|
|
610
|
+
abortReason = "401-invalid-credentials";
|
|
487
611
|
else if (responseState.httpStatus === 403) abortReason = "403-forbidden";
|
|
488
|
-
else if (responseState.httpStatus === 0)
|
|
489
|
-
|
|
612
|
+
else if (responseState.httpStatus === 0)
|
|
613
|
+
abortReason = "client-network-error";
|
|
614
|
+
log.error(
|
|
615
|
+
`\u{1F6AB} Unrecoverable error (status ${responseState.httpStatus}) when generating signed upload url: ${responseState.errorMessage ? `${responseState.errorMessage}.` : ""} aborting.`
|
|
616
|
+
);
|
|
490
617
|
}
|
|
491
618
|
return {
|
|
492
619
|
abortReason,
|
|
@@ -508,21 +635,22 @@ __name(generateSignedUrlForTempTeamStorage, "generateSignedUrlForTempTeamStorage
|
|
|
508
635
|
var notifyTerminatedEphemeralEnvironment = /* @__PURE__ */ __name(async (deps, apiConfig, config) => {
|
|
509
636
|
const { fetch: localFetch, log } = deps;
|
|
510
637
|
try {
|
|
511
|
-
const response = await localFetch(
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
638
|
+
const response = await localFetch(
|
|
639
|
+
new URL("/api/webhooks/environment_terminated", apiConfig.serviceBase),
|
|
640
|
+
{
|
|
641
|
+
body: JSON.stringify(config),
|
|
642
|
+
headers: {
|
|
643
|
+
Authorization: `Bearer ${apiConfig.apiKey}`,
|
|
644
|
+
"Content-Type": "application/json",
|
|
645
|
+
"User-Agent": apiConfig.userAgent
|
|
646
|
+
},
|
|
647
|
+
method: "POST"
|
|
648
|
+
}
|
|
649
|
+
);
|
|
520
650
|
if (!response.ok) return handleErrorResponse2(response, log);
|
|
521
|
-
const { environmentId } = await response.json();
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
outcome: "success"
|
|
525
|
-
};
|
|
651
|
+
const { environmentId, warning } = await response.json();
|
|
652
|
+
if (warning) log.warn(`\u26A0\uFE0F ${warning}`);
|
|
653
|
+
return { environmentId, outcome: "success" };
|
|
526
654
|
} catch {
|
|
527
655
|
log.error(`\u{1F6AB} Network error from terminate_preview_environment, aborting.`);
|
|
528
656
|
return {
|
|
@@ -555,14 +683,9 @@ __name(handleErrorResponse2, "handleErrorResponse");
|
|
|
555
683
|
|
|
556
684
|
// src/lib/sdk/domain/pollCiGreenlight/buildCompletedRunResult.ts
|
|
557
685
|
function buildCompletedRunResult(status) {
|
|
558
|
-
if (status.greenlight)
|
|
559
|
-
greenlightStatus: status,
|
|
560
|
-
|
|
561
|
-
};
|
|
562
|
-
else return {
|
|
563
|
-
greenlightStatus: status,
|
|
564
|
-
outcome: "failed"
|
|
565
|
-
};
|
|
686
|
+
if (status.greenlight)
|
|
687
|
+
return { greenlightStatus: status, outcome: "success" };
|
|
688
|
+
else return { greenlightStatus: status, outcome: "failed" };
|
|
566
689
|
}
|
|
567
690
|
__name(buildCompletedRunResult, "buildCompletedRunResult");
|
|
568
691
|
|
|
@@ -571,20 +694,32 @@ var pollCiGreenlightDefaults = {
|
|
|
571
694
|
abortOnSuperseded: false,
|
|
572
695
|
maxRetries: 10,
|
|
573
696
|
pollTimeout: 120 * 60 * 1e3,
|
|
697
|
+
// 2 hours
|
|
574
698
|
retryInterval: 10 * 1e3,
|
|
699
|
+
// 10 seconds
|
|
575
700
|
runInProgressInterval: 30 * 1e3,
|
|
701
|
+
// 30 seconds
|
|
576
702
|
runUnderReviewInterval: 60 * 1e3
|
|
703
|
+
// 60 seconds
|
|
577
704
|
};
|
|
578
705
|
|
|
579
706
|
// src/lib/api/ci-greenlight.ts
|
|
580
|
-
async function fetchCiGreenlightStatus({ apiKey, serviceBase, userAgent }, {
|
|
707
|
+
async function fetchCiGreenlightStatus({ apiKey, serviceBase, userAgent }, {
|
|
708
|
+
runId
|
|
709
|
+
}, { fetch: localFetch, log }) {
|
|
581
710
|
try {
|
|
582
|
-
const resp = await localFetch(
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
711
|
+
const resp = await localFetch(
|
|
712
|
+
new URL(
|
|
713
|
+
`/api/v0/ci-greenlight/${encodeURIComponent(runId)}`,
|
|
714
|
+
serviceBase
|
|
715
|
+
),
|
|
716
|
+
{
|
|
717
|
+
headers: {
|
|
718
|
+
Authorization: `Bearer ${apiKey}`,
|
|
719
|
+
"User-Agent": userAgent
|
|
720
|
+
}
|
|
586
721
|
}
|
|
587
|
-
|
|
722
|
+
);
|
|
588
723
|
if (resp.ok) {
|
|
589
724
|
const greenlightStatus = await resp.json();
|
|
590
725
|
return {
|
|
@@ -634,14 +769,22 @@ __name(fetchCiGreenlightStatus, "fetchCiGreenlightStatus");
|
|
|
634
769
|
// src/lib/sdk/domain/pollCiGreenlight/iterator.ts
|
|
635
770
|
async function* makePollCiGreenlightStatusIterator(deps, apiConfig, { runId, ...pollConfig }) {
|
|
636
771
|
const { log } = deps;
|
|
637
|
-
const {
|
|
772
|
+
const {
|
|
773
|
+
maxRetries = pollCiGreenlightDefaults.maxRetries,
|
|
774
|
+
pollTimeout = pollCiGreenlightDefaults.pollTimeout,
|
|
775
|
+
retryInterval = pollCiGreenlightDefaults.retryInterval,
|
|
776
|
+
runInProgressInterval = pollCiGreenlightDefaults.runInProgressInterval,
|
|
777
|
+
runUnderReviewInterval = pollCiGreenlightDefaults.runUnderReviewInterval
|
|
778
|
+
} = pollConfig;
|
|
638
779
|
let retries = 0;
|
|
639
780
|
let previousStatus = void 0;
|
|
640
781
|
const startedAt = Date.now();
|
|
641
782
|
while (Date.now() - startedAt <= pollTimeout) {
|
|
642
|
-
const responseState = await fetchCiGreenlightStatus(
|
|
643
|
-
|
|
644
|
-
|
|
783
|
+
const responseState = await fetchCiGreenlightStatus(
|
|
784
|
+
apiConfig,
|
|
785
|
+
{ runId },
|
|
786
|
+
deps
|
|
787
|
+
);
|
|
645
788
|
const elapsedMs = Date.now() - startedAt;
|
|
646
789
|
if (!responseState.ok && !responseState.canRetry) {
|
|
647
790
|
yield {
|
|
@@ -688,7 +831,8 @@ async function* makePollCiGreenlightStatusIterator(deps, apiConfig, { runId, ...
|
|
|
688
831
|
}
|
|
689
832
|
const retryLabel = `${httpStatus ? ` (status ${httpStatus})` : ""}, will try again... (${retries}/${maxRetries})`;
|
|
690
833
|
if (errorType === "network") log.warn(`\u274C Network error${retryLabel}`);
|
|
691
|
-
else if (errorType === "not-found")
|
|
834
|
+
else if (errorType === "not-found")
|
|
835
|
+
log.info(`\u23F3 Run not found${retryLabel}`);
|
|
692
836
|
else if (errorType === "server") log.warn(`\u274C Server error${retryLabel}`);
|
|
693
837
|
await sleep(retryInterval);
|
|
694
838
|
continue;
|
|
@@ -725,7 +869,9 @@ async function* makePollCiGreenlightStatusIterator(deps, apiConfig, { runId, ...
|
|
|
725
869
|
await sleep(runUnderReviewInterval);
|
|
726
870
|
break;
|
|
727
871
|
default:
|
|
728
|
-
throw Error(
|
|
872
|
+
throw Error(
|
|
873
|
+
`Unexpected run stage: ${greenlightStatus}`
|
|
874
|
+
);
|
|
729
875
|
}
|
|
730
876
|
}
|
|
731
877
|
yield {
|
|
@@ -742,12 +888,19 @@ __name(makePollCiGreenlightStatusIterator, "makePollCiGreenlightStatusIterator")
|
|
|
742
888
|
function buildSuccessLogMessage(status) {
|
|
743
889
|
const { nonBlockingBugsCount, relevantRunUrl } = status;
|
|
744
890
|
const urlInfo = `See ${relevantRunUrl}`;
|
|
745
|
-
return `\u2705 Run passed and no blocking bugs found${nonBlockingBugsCount > 0 ? ` and ${nonBlockingBugsCount} non-blocking bug${pluralize(
|
|
891
|
+
return `\u2705 Run passed and no blocking bugs found${nonBlockingBugsCount > 0 ? ` and ${nonBlockingBugsCount} non-blocking bug${pluralize(
|
|
892
|
+
nonBlockingBugsCount
|
|
893
|
+
)} found` : ""}.
|
|
746
894
|
${urlInfo}`;
|
|
747
895
|
}
|
|
748
896
|
__name(buildSuccessLogMessage, "buildSuccessLogMessage");
|
|
749
897
|
function buildFailedLogMessage(status) {
|
|
750
|
-
const {
|
|
898
|
+
const {
|
|
899
|
+
blockingBugsCount,
|
|
900
|
+
nonBlockingBugsCount,
|
|
901
|
+
relevantRunWithBugsUrl,
|
|
902
|
+
reproducedBugs
|
|
903
|
+
} = status;
|
|
751
904
|
const blockingBugUrls = reproducedBugs.filter((bug) => bug.isBlocking).map((bug) => bug.applicationUrl);
|
|
752
905
|
const nonBlockingBugUrls = reproducedBugs.filter((bug) => !bug.isBlocking).map((bug) => bug.applicationUrl);
|
|
753
906
|
const blockingBugList = blockingBugUrls.map((url) => `
|
|
@@ -757,7 +910,11 @@ function buildFailedLogMessage(status) {
|
|
|
757
910
|
const bugsListInText = `${blockingBugUrls.length > 0 ? `
|
|
758
911
|
BLOCKING BUGS:${blockingBugList}` : ""}${nonBlockingBugUrls.length > 0 ? `
|
|
759
912
|
NON BLOCKING BUGS:${nonBlockingBugList}` : ""}`;
|
|
760
|
-
return `\u274C Run failed and ${blockingBugsCount} blocking bug${pluralize(
|
|
913
|
+
return `\u274C Run failed and ${blockingBugsCount} blocking bug${pluralize(
|
|
914
|
+
blockingBugsCount
|
|
915
|
+
)} found${nonBlockingBugsCount ? ` and ${nonBlockingBugsCount} non-blocking bug${pluralize(
|
|
916
|
+
nonBlockingBugsCount
|
|
917
|
+
)}` : ""}.
|
|
761
918
|
See ${relevantRunWithBugsUrl}
|
|
762
919
|
You may review the priority of certain bugs to mark these non-blocking and retry the job.
|
|
763
920
|
` + bugsListInText;
|
|
@@ -788,7 +945,9 @@ ${urlInfo}`;
|
|
|
788
945
|
case "underReview":
|
|
789
946
|
return `\u{1F575}\uFE0F Run is under review... ${urlInfo}`;
|
|
790
947
|
case "completed":
|
|
791
|
-
throw Error(
|
|
948
|
+
throw Error(
|
|
949
|
+
"buildRunStageLogMessage should not be called for completed stage"
|
|
950
|
+
);
|
|
792
951
|
default:
|
|
793
952
|
throw Error(`Unexpected run stage: ${runStage}`);
|
|
794
953
|
}
|
|
@@ -801,21 +960,27 @@ function mapIteratorAbortToGreenlightStatus(iteration, pollTimeout, deps) {
|
|
|
801
960
|
const { abortReason, httpStatus } = iteration;
|
|
802
961
|
switch (abortReason) {
|
|
803
962
|
case "4XX-client-error":
|
|
804
|
-
log.error(
|
|
963
|
+
log.error(
|
|
964
|
+
`\u{1F6AB} Unrecoverable error (status ${httpStatus}) from CI greenlight, aborting.`
|
|
965
|
+
);
|
|
805
966
|
return {
|
|
806
967
|
abortReason,
|
|
807
968
|
httpStatus,
|
|
808
969
|
outcome: "aborted"
|
|
809
970
|
};
|
|
810
971
|
case "5XX-server-error":
|
|
811
|
-
log.error(
|
|
972
|
+
log.error(
|
|
973
|
+
`\u{1F6AB} Unrecoverable error (status ${httpStatus}) from CI greenlight, aborting.`
|
|
974
|
+
);
|
|
812
975
|
return {
|
|
813
976
|
abortReason,
|
|
814
977
|
httpStatus,
|
|
815
978
|
outcome: "aborted"
|
|
816
979
|
};
|
|
817
980
|
case "404-run-not-found":
|
|
818
|
-
log.error(
|
|
981
|
+
log.error(
|
|
982
|
+
`\u{1F6AB} Unrecoverable error (status ${httpStatus}) from CI greenlight, aborting.`
|
|
983
|
+
);
|
|
819
984
|
return {
|
|
820
985
|
abortReason,
|
|
821
986
|
httpStatus,
|
|
@@ -843,7 +1008,9 @@ function mapIteratorAbortToGreenlightStatus(iteration, pollTimeout, deps) {
|
|
|
843
1008
|
outcome: "aborted"
|
|
844
1009
|
};
|
|
845
1010
|
case "XXX-other-http-code":
|
|
846
|
-
log.error(
|
|
1011
|
+
log.error(
|
|
1012
|
+
`\u{1F6AB} Unrecoverable error (status ${httpStatus}) from CI greenlight, aborting.`
|
|
1013
|
+
);
|
|
847
1014
|
return {
|
|
848
1015
|
abortReason,
|
|
849
1016
|
httpStatus,
|
|
@@ -856,15 +1023,23 @@ function mapIteratorAbortToGreenlightStatus(iteration, pollTimeout, deps) {
|
|
|
856
1023
|
__name(mapIteratorAbortToGreenlightStatus, "mapIteratorAbortToGreenlightStatus");
|
|
857
1024
|
|
|
858
1025
|
// src/lib/sdk/domain/pollCiGreenlight/index.ts
|
|
859
|
-
async function pollCiGreenlightStatus(deps, apiConfig, {
|
|
1026
|
+
async function pollCiGreenlightStatus(deps, apiConfig, {
|
|
1027
|
+
onRunStageChanged = /* @__PURE__ */ __name(() => void 0, "onRunStageChanged"),
|
|
1028
|
+
runId,
|
|
1029
|
+
...pollConfig
|
|
1030
|
+
}) {
|
|
860
1031
|
const { log } = deps;
|
|
861
|
-
const {
|
|
1032
|
+
const {
|
|
1033
|
+
abortOnSuperseded = pollCiGreenlightDefaults.abortOnSuperseded,
|
|
1034
|
+
pollTimeout = pollCiGreenlightDefaults.pollTimeout
|
|
1035
|
+
} = pollConfig;
|
|
862
1036
|
const iterator = makePollCiGreenlightStatusIterator(deps, apiConfig, {
|
|
863
1037
|
runId,
|
|
864
1038
|
...pollConfig
|
|
865
1039
|
});
|
|
866
1040
|
for await (const lastPoll of iterator) {
|
|
867
|
-
if (lastPoll.isAborted)
|
|
1041
|
+
if (lastPoll.isAborted)
|
|
1042
|
+
return mapIteratorAbortToGreenlightStatus(lastPoll, pollTimeout, deps);
|
|
868
1043
|
const { previousStatus, stageChanged, status } = lastPoll;
|
|
869
1044
|
if (stageChanged) {
|
|
870
1045
|
try {
|
|
@@ -877,7 +1052,10 @@ async function pollCiGreenlightStatus(deps, apiConfig, { onRunStageChanged = /*
|
|
|
877
1052
|
const isSuperseded = rootRunId !== relevantRunId;
|
|
878
1053
|
const shouldAbortOnSuperseded = isSuperseded && abortOnSuperseded;
|
|
879
1054
|
if (shouldAbortOnSuperseded) {
|
|
880
|
-
const message = buildSupersededAbortLogMessage(
|
|
1055
|
+
const message = buildSupersededAbortLogMessage(
|
|
1056
|
+
rootRunUrl,
|
|
1057
|
+
relevantRunUrl
|
|
1058
|
+
);
|
|
881
1059
|
log.warn(message);
|
|
882
1060
|
return {
|
|
883
1061
|
abortReason: "superseded-run",
|
|
@@ -886,7 +1064,10 @@ async function pollCiGreenlightStatus(deps, apiConfig, { onRunStageChanged = /*
|
|
|
886
1064
|
};
|
|
887
1065
|
}
|
|
888
1066
|
if (isSuperseded) {
|
|
889
|
-
const message = buildSupersededContinueLogMessage(
|
|
1067
|
+
const message = buildSupersededContinueLogMessage(
|
|
1068
|
+
rootRunUrl,
|
|
1069
|
+
relevantRunUrl
|
|
1070
|
+
);
|
|
890
1071
|
log.info(message);
|
|
891
1072
|
}
|
|
892
1073
|
switch (runStage) {
|
|
@@ -926,10 +1107,19 @@ async function pollCiGreenlightStatus(deps, apiConfig, { onRunStageChanged = /*
|
|
|
926
1107
|
__name(pollCiGreenlightStatus, "pollCiGreenlightStatus");
|
|
927
1108
|
|
|
928
1109
|
// src/lib/sdk/index.ts
|
|
929
|
-
function makeQaWolfSdk({
|
|
1110
|
+
function makeQaWolfSdk({
|
|
1111
|
+
apiKey,
|
|
1112
|
+
serviceBase = defaultServiceBase,
|
|
1113
|
+
userAgent = defaultUserAgent
|
|
1114
|
+
}, {
|
|
1115
|
+
fetch = defaultFetch,
|
|
1116
|
+
log = defaultLogDriver
|
|
1117
|
+
} = {}) {
|
|
930
1118
|
if (typeof fetch !== "function") {
|
|
931
|
-
throw Error(
|
|
932
|
-
|
|
1119
|
+
throw Error(
|
|
1120
|
+
`QA Wolf CI-SDK requires fetch to be defined. Make sure you are using NodeJS 18+, OR pass a fetch polyfill to the makeQaWolfSdk function.
|
|
1121
|
+
We recommend 'undici' package for that purpose. See the Requirement section of our README for more guidance.`
|
|
1122
|
+
);
|
|
933
1123
|
}
|
|
934
1124
|
const deps = {
|
|
935
1125
|
// Versions of fetch may have different default timeouts. For consistency, we explicitly set it to 2 minutes here.
|
|
@@ -938,22 +1128,26 @@ We recommend 'undici' package for that purpose. See the Requirement section of o
|
|
|
938
1128
|
fetch: buildFetchWithTimeout(fetch, 12e4),
|
|
939
1129
|
log
|
|
940
1130
|
};
|
|
941
|
-
const apiConfig = {
|
|
942
|
-
apiKey,
|
|
943
|
-
serviceBase,
|
|
944
|
-
userAgent
|
|
945
|
-
};
|
|
1131
|
+
const apiConfig = { apiKey, serviceBase, userAgent };
|
|
946
1132
|
return {
|
|
947
1133
|
attemptNotifyDeploy: attemptNotifyDeploy.bind(null, deps, apiConfig),
|
|
948
|
-
generateSignedUrlForRunInputsExecutablesStorage: generateSignedUrlForRunInputsExecutablesStorage.bind(
|
|
1134
|
+
generateSignedUrlForRunInputsExecutablesStorage: generateSignedUrlForRunInputsExecutablesStorage.bind(
|
|
1135
|
+
null,
|
|
1136
|
+
deps,
|
|
1137
|
+
apiConfig
|
|
1138
|
+
),
|
|
949
1139
|
generateSignedUrlForTempTeamStorage: generateSignedUrlForTempTeamStorage.bind(null, deps, apiConfig),
|
|
950
|
-
makePollCiGreenlightStatusIterator: makePollCiGreenlightStatusIterator.bind(
|
|
1140
|
+
makePollCiGreenlightStatusIterator: makePollCiGreenlightStatusIterator.bind(
|
|
1141
|
+
null,
|
|
1142
|
+
deps,
|
|
1143
|
+
apiConfig
|
|
1144
|
+
),
|
|
951
1145
|
notifyTerminatedEphemeralEnvironment: notifyTerminatedEphemeralEnvironment.bind(null, deps, apiConfig),
|
|
952
1146
|
pollCiGreenlightStatus: pollCiGreenlightStatus.bind(null, deps, apiConfig)
|
|
953
1147
|
};
|
|
954
1148
|
}
|
|
955
1149
|
__name(makeQaWolfSdk, "makeQaWolfSdk");
|
|
956
|
-
|
|
957
|
-
|
|
1150
|
+
export {
|
|
1151
|
+
makeQaWolfSdk
|
|
1152
|
+
};
|
|
958
1153
|
//# sourceMappingURL=index.js.map
|
|
959
|
-
//# sourceMappingURL=index.js.map
|