@qawolf/ci-sdk 2.2.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 +13 -0
- package/dist/index.cjs +389 -196
- package/dist/index.cjs.map +7 -1
- package/dist/index.d.ts +4 -557
- package/dist/index.js +364 -194
- 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 +8 -7
- package/dist/index.d.cts +0 -557
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,35 +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
|
-
"Content-Type": "application/json",
|
|
287
|
-
"User-Agent": apiConfig.userAgent
|
|
288
|
-
},
|
|
289
|
-
method: "POST",
|
|
290
|
-
// Override default timeout to 5 minutes. This gives extra room
|
|
291
|
-
// for both (1) waiting for reconciliation (2) creating the run.
|
|
292
|
-
signal: AbortSignal.timeout(5 * 60 * 1e3)
|
|
293
|
-
});
|
|
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
|
+
);
|
|
294
361
|
if (!response.ok) return handleErrorResponse(response, log);
|
|
295
362
|
bodyText = await response.text();
|
|
296
363
|
} catch {
|
|
@@ -309,7 +376,10 @@ async function attemptNotifyDeploy(deps, apiConfig, config) {
|
|
|
309
376
|
}
|
|
310
377
|
const wire = parseDeploySuccessWireResponse(rawBody);
|
|
311
378
|
if (wire === "invalid") {
|
|
312
|
-
return abortInvalidResponseBody(
|
|
379
|
+
return abortInvalidResponseBody(
|
|
380
|
+
log,
|
|
381
|
+
"the response body did not match the expected shape"
|
|
382
|
+
);
|
|
313
383
|
}
|
|
314
384
|
const data = mapDeploySuccessResponse(wire);
|
|
315
385
|
return handleSuccessResponse(data, log);
|
|
@@ -350,10 +420,17 @@ var signedUrlPaths = {
|
|
|
350
420
|
runInputsExecutables: "/api/v0/run-inputs-executables-signed-urls",
|
|
351
421
|
teamStorage: "/api/v0/team-storage-signed-url"
|
|
352
422
|
};
|
|
353
|
-
function buildSignedUrl({
|
|
423
|
+
function buildSignedUrl({
|
|
424
|
+
destinationFilePath,
|
|
425
|
+
endpoint,
|
|
426
|
+
serviceBase,
|
|
427
|
+
workspaceId
|
|
428
|
+
}) {
|
|
354
429
|
const url = new URL(signedUrlPaths[endpoint], serviceBase);
|
|
355
|
-
if (destinationFilePath !== void 0)
|
|
356
|
-
|
|
430
|
+
if (destinationFilePath !== void 0)
|
|
431
|
+
url.searchParams.set("file", destinationFilePath);
|
|
432
|
+
if (workspaceId !== void 0)
|
|
433
|
+
url.searchParams.set("workspaceId", workspaceId);
|
|
357
434
|
return url;
|
|
358
435
|
}
|
|
359
436
|
__name(buildSignedUrl, "buildSignedUrl");
|
|
@@ -361,19 +438,22 @@ __name(buildSignedUrl, "buildSignedUrl");
|
|
|
361
438
|
// src/lib/api/generate-signed-url-for-run-inputs-executables.ts
|
|
362
439
|
async function callGenerateSignedUrlForRunInputsExecutablesStorage({ apiKey, serviceBase, userAgent }, { destinationFilePath, workspaceId }, { fetch: localFetch, log }) {
|
|
363
440
|
try {
|
|
364
|
-
const response = await localFetch(
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
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
|
+
);
|
|
377
457
|
if (response.status === 200) {
|
|
378
458
|
const json = await response.json();
|
|
379
459
|
return {
|
|
@@ -414,18 +494,28 @@ async function generateSignedUrlForRunInputsExecutablesStorage(deps, apiConfig,
|
|
|
414
494
|
success: false
|
|
415
495
|
};
|
|
416
496
|
}
|
|
417
|
-
const responseState = await callGenerateSignedUrlForRunInputsExecutablesStorage(
|
|
497
|
+
const responseState = await callGenerateSignedUrlForRunInputsExecutablesStorage(
|
|
498
|
+
apiConfig,
|
|
499
|
+
config,
|
|
500
|
+
deps
|
|
501
|
+
);
|
|
418
502
|
if (!responseState.success) {
|
|
419
503
|
let abortReason = "XXX-other-http-code";
|
|
420
504
|
if (responseState.httpStatus >= 500) {
|
|
421
505
|
abortReason = "5XX-server-error";
|
|
422
|
-
log.error(
|
|
506
|
+
log.error(
|
|
507
|
+
`\u{1F6AB} Unrecoverable error (status ${responseState.httpStatus}) when generating signed upload url: aborting.`
|
|
508
|
+
);
|
|
423
509
|
} else {
|
|
424
510
|
if (responseState.httpStatus === 400) abortReason = "400-invalid-request";
|
|
425
|
-
else if (responseState.httpStatus === 401)
|
|
511
|
+
else if (responseState.httpStatus === 401)
|
|
512
|
+
abortReason = "401-invalid-credentials";
|
|
426
513
|
else if (responseState.httpStatus === 403) abortReason = "403-forbidden";
|
|
427
|
-
else if (responseState.httpStatus === 0)
|
|
428
|
-
|
|
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
|
+
);
|
|
429
519
|
}
|
|
430
520
|
return {
|
|
431
521
|
abortReason,
|
|
@@ -446,19 +536,22 @@ __name(generateSignedUrlForRunInputsExecutablesStorage, "generateSignedUrlForRun
|
|
|
446
536
|
// src/lib/api/generate-signed-url-for-team-storage.ts
|
|
447
537
|
async function callGenerateSignedUrlForTempTeamStorage({ apiKey, serviceBase, userAgent }, { destinationFilePath, workspaceId }, { fetch: localFetch, log }) {
|
|
448
538
|
try {
|
|
449
|
-
const response = await localFetch(
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
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
|
+
);
|
|
462
555
|
if (response.status === 200) {
|
|
463
556
|
const json = await response.json();
|
|
464
557
|
return {
|
|
@@ -499,18 +592,28 @@ async function generateSignedUrlForTempTeamStorage(deps, apiConfig, config) {
|
|
|
499
592
|
success: false
|
|
500
593
|
};
|
|
501
594
|
}
|
|
502
|
-
const responseState = await callGenerateSignedUrlForTempTeamStorage(
|
|
595
|
+
const responseState = await callGenerateSignedUrlForTempTeamStorage(
|
|
596
|
+
apiConfig,
|
|
597
|
+
config,
|
|
598
|
+
deps
|
|
599
|
+
);
|
|
503
600
|
if (!responseState.success) {
|
|
504
601
|
let abortReason = "XXX-other-http-code";
|
|
505
602
|
if (responseState.httpStatus >= 500) {
|
|
506
603
|
abortReason = "5XX-server-error";
|
|
507
|
-
log.error(
|
|
604
|
+
log.error(
|
|
605
|
+
`\u{1F6AB} Unrecoverable error (status ${responseState.httpStatus}) when generating signed upload url: aborting.`
|
|
606
|
+
);
|
|
508
607
|
} else {
|
|
509
608
|
if (responseState.httpStatus === 400) abortReason = "400-invalid-request";
|
|
510
|
-
else if (responseState.httpStatus === 401)
|
|
609
|
+
else if (responseState.httpStatus === 401)
|
|
610
|
+
abortReason = "401-invalid-credentials";
|
|
511
611
|
else if (responseState.httpStatus === 403) abortReason = "403-forbidden";
|
|
512
|
-
else if (responseState.httpStatus === 0)
|
|
513
|
-
|
|
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
|
+
);
|
|
514
617
|
}
|
|
515
618
|
return {
|
|
516
619
|
abortReason,
|
|
@@ -532,21 +635,22 @@ __name(generateSignedUrlForTempTeamStorage, "generateSignedUrlForTempTeamStorage
|
|
|
532
635
|
var notifyTerminatedEphemeralEnvironment = /* @__PURE__ */ __name(async (deps, apiConfig, config) => {
|
|
533
636
|
const { fetch: localFetch, log } = deps;
|
|
534
637
|
try {
|
|
535
|
-
const response = await localFetch(
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
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
|
+
);
|
|
544
650
|
if (!response.ok) return handleErrorResponse2(response, log);
|
|
545
|
-
const { environmentId } = await response.json();
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
outcome: "success"
|
|
549
|
-
};
|
|
651
|
+
const { environmentId, warning } = await response.json();
|
|
652
|
+
if (warning) log.warn(`\u26A0\uFE0F ${warning}`);
|
|
653
|
+
return { environmentId, outcome: "success" };
|
|
550
654
|
} catch {
|
|
551
655
|
log.error(`\u{1F6AB} Network error from terminate_preview_environment, aborting.`);
|
|
552
656
|
return {
|
|
@@ -579,14 +683,9 @@ __name(handleErrorResponse2, "handleErrorResponse");
|
|
|
579
683
|
|
|
580
684
|
// src/lib/sdk/domain/pollCiGreenlight/buildCompletedRunResult.ts
|
|
581
685
|
function buildCompletedRunResult(status) {
|
|
582
|
-
if (status.greenlight)
|
|
583
|
-
greenlightStatus: status,
|
|
584
|
-
|
|
585
|
-
};
|
|
586
|
-
else return {
|
|
587
|
-
greenlightStatus: status,
|
|
588
|
-
outcome: "failed"
|
|
589
|
-
};
|
|
686
|
+
if (status.greenlight)
|
|
687
|
+
return { greenlightStatus: status, outcome: "success" };
|
|
688
|
+
else return { greenlightStatus: status, outcome: "failed" };
|
|
590
689
|
}
|
|
591
690
|
__name(buildCompletedRunResult, "buildCompletedRunResult");
|
|
592
691
|
|
|
@@ -595,20 +694,32 @@ var pollCiGreenlightDefaults = {
|
|
|
595
694
|
abortOnSuperseded: false,
|
|
596
695
|
maxRetries: 10,
|
|
597
696
|
pollTimeout: 120 * 60 * 1e3,
|
|
697
|
+
// 2 hours
|
|
598
698
|
retryInterval: 10 * 1e3,
|
|
699
|
+
// 10 seconds
|
|
599
700
|
runInProgressInterval: 30 * 1e3,
|
|
701
|
+
// 30 seconds
|
|
600
702
|
runUnderReviewInterval: 60 * 1e3
|
|
703
|
+
// 60 seconds
|
|
601
704
|
};
|
|
602
705
|
|
|
603
706
|
// src/lib/api/ci-greenlight.ts
|
|
604
|
-
async function fetchCiGreenlightStatus({ apiKey, serviceBase, userAgent }, {
|
|
707
|
+
async function fetchCiGreenlightStatus({ apiKey, serviceBase, userAgent }, {
|
|
708
|
+
runId
|
|
709
|
+
}, { fetch: localFetch, log }) {
|
|
605
710
|
try {
|
|
606
|
-
const resp = await localFetch(
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
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
|
+
}
|
|
610
721
|
}
|
|
611
|
-
|
|
722
|
+
);
|
|
612
723
|
if (resp.ok) {
|
|
613
724
|
const greenlightStatus = await resp.json();
|
|
614
725
|
return {
|
|
@@ -658,14 +769,22 @@ __name(fetchCiGreenlightStatus, "fetchCiGreenlightStatus");
|
|
|
658
769
|
// src/lib/sdk/domain/pollCiGreenlight/iterator.ts
|
|
659
770
|
async function* makePollCiGreenlightStatusIterator(deps, apiConfig, { runId, ...pollConfig }) {
|
|
660
771
|
const { log } = deps;
|
|
661
|
-
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;
|
|
662
779
|
let retries = 0;
|
|
663
780
|
let previousStatus = void 0;
|
|
664
781
|
const startedAt = Date.now();
|
|
665
782
|
while (Date.now() - startedAt <= pollTimeout) {
|
|
666
|
-
const responseState = await fetchCiGreenlightStatus(
|
|
667
|
-
|
|
668
|
-
|
|
783
|
+
const responseState = await fetchCiGreenlightStatus(
|
|
784
|
+
apiConfig,
|
|
785
|
+
{ runId },
|
|
786
|
+
deps
|
|
787
|
+
);
|
|
669
788
|
const elapsedMs = Date.now() - startedAt;
|
|
670
789
|
if (!responseState.ok && !responseState.canRetry) {
|
|
671
790
|
yield {
|
|
@@ -712,7 +831,8 @@ async function* makePollCiGreenlightStatusIterator(deps, apiConfig, { runId, ...
|
|
|
712
831
|
}
|
|
713
832
|
const retryLabel = `${httpStatus ? ` (status ${httpStatus})` : ""}, will try again... (${retries}/${maxRetries})`;
|
|
714
833
|
if (errorType === "network") log.warn(`\u274C Network error${retryLabel}`);
|
|
715
|
-
else if (errorType === "not-found")
|
|
834
|
+
else if (errorType === "not-found")
|
|
835
|
+
log.info(`\u23F3 Run not found${retryLabel}`);
|
|
716
836
|
else if (errorType === "server") log.warn(`\u274C Server error${retryLabel}`);
|
|
717
837
|
await sleep(retryInterval);
|
|
718
838
|
continue;
|
|
@@ -749,7 +869,9 @@ async function* makePollCiGreenlightStatusIterator(deps, apiConfig, { runId, ...
|
|
|
749
869
|
await sleep(runUnderReviewInterval);
|
|
750
870
|
break;
|
|
751
871
|
default:
|
|
752
|
-
throw Error(
|
|
872
|
+
throw Error(
|
|
873
|
+
`Unexpected run stage: ${greenlightStatus}`
|
|
874
|
+
);
|
|
753
875
|
}
|
|
754
876
|
}
|
|
755
877
|
yield {
|
|
@@ -766,12 +888,19 @@ __name(makePollCiGreenlightStatusIterator, "makePollCiGreenlightStatusIterator")
|
|
|
766
888
|
function buildSuccessLogMessage(status) {
|
|
767
889
|
const { nonBlockingBugsCount, relevantRunUrl } = status;
|
|
768
890
|
const urlInfo = `See ${relevantRunUrl}`;
|
|
769
|
-
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` : ""}.
|
|
770
894
|
${urlInfo}`;
|
|
771
895
|
}
|
|
772
896
|
__name(buildSuccessLogMessage, "buildSuccessLogMessage");
|
|
773
897
|
function buildFailedLogMessage(status) {
|
|
774
|
-
const {
|
|
898
|
+
const {
|
|
899
|
+
blockingBugsCount,
|
|
900
|
+
nonBlockingBugsCount,
|
|
901
|
+
relevantRunWithBugsUrl,
|
|
902
|
+
reproducedBugs
|
|
903
|
+
} = status;
|
|
775
904
|
const blockingBugUrls = reproducedBugs.filter((bug) => bug.isBlocking).map((bug) => bug.applicationUrl);
|
|
776
905
|
const nonBlockingBugUrls = reproducedBugs.filter((bug) => !bug.isBlocking).map((bug) => bug.applicationUrl);
|
|
777
906
|
const blockingBugList = blockingBugUrls.map((url) => `
|
|
@@ -781,7 +910,11 @@ function buildFailedLogMessage(status) {
|
|
|
781
910
|
const bugsListInText = `${blockingBugUrls.length > 0 ? `
|
|
782
911
|
BLOCKING BUGS:${blockingBugList}` : ""}${nonBlockingBugUrls.length > 0 ? `
|
|
783
912
|
NON BLOCKING BUGS:${nonBlockingBugList}` : ""}`;
|
|
784
|
-
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
|
+
)}` : ""}.
|
|
785
918
|
See ${relevantRunWithBugsUrl}
|
|
786
919
|
You may review the priority of certain bugs to mark these non-blocking and retry the job.
|
|
787
920
|
` + bugsListInText;
|
|
@@ -812,7 +945,9 @@ ${urlInfo}`;
|
|
|
812
945
|
case "underReview":
|
|
813
946
|
return `\u{1F575}\uFE0F Run is under review... ${urlInfo}`;
|
|
814
947
|
case "completed":
|
|
815
|
-
throw Error(
|
|
948
|
+
throw Error(
|
|
949
|
+
"buildRunStageLogMessage should not be called for completed stage"
|
|
950
|
+
);
|
|
816
951
|
default:
|
|
817
952
|
throw Error(`Unexpected run stage: ${runStage}`);
|
|
818
953
|
}
|
|
@@ -825,21 +960,27 @@ function mapIteratorAbortToGreenlightStatus(iteration, pollTimeout, deps) {
|
|
|
825
960
|
const { abortReason, httpStatus } = iteration;
|
|
826
961
|
switch (abortReason) {
|
|
827
962
|
case "4XX-client-error":
|
|
828
|
-
log.error(
|
|
963
|
+
log.error(
|
|
964
|
+
`\u{1F6AB} Unrecoverable error (status ${httpStatus}) from CI greenlight, aborting.`
|
|
965
|
+
);
|
|
829
966
|
return {
|
|
830
967
|
abortReason,
|
|
831
968
|
httpStatus,
|
|
832
969
|
outcome: "aborted"
|
|
833
970
|
};
|
|
834
971
|
case "5XX-server-error":
|
|
835
|
-
log.error(
|
|
972
|
+
log.error(
|
|
973
|
+
`\u{1F6AB} Unrecoverable error (status ${httpStatus}) from CI greenlight, aborting.`
|
|
974
|
+
);
|
|
836
975
|
return {
|
|
837
976
|
abortReason,
|
|
838
977
|
httpStatus,
|
|
839
978
|
outcome: "aborted"
|
|
840
979
|
};
|
|
841
980
|
case "404-run-not-found":
|
|
842
|
-
log.error(
|
|
981
|
+
log.error(
|
|
982
|
+
`\u{1F6AB} Unrecoverable error (status ${httpStatus}) from CI greenlight, aborting.`
|
|
983
|
+
);
|
|
843
984
|
return {
|
|
844
985
|
abortReason,
|
|
845
986
|
httpStatus,
|
|
@@ -867,7 +1008,9 @@ function mapIteratorAbortToGreenlightStatus(iteration, pollTimeout, deps) {
|
|
|
867
1008
|
outcome: "aborted"
|
|
868
1009
|
};
|
|
869
1010
|
case "XXX-other-http-code":
|
|
870
|
-
log.error(
|
|
1011
|
+
log.error(
|
|
1012
|
+
`\u{1F6AB} Unrecoverable error (status ${httpStatus}) from CI greenlight, aborting.`
|
|
1013
|
+
);
|
|
871
1014
|
return {
|
|
872
1015
|
abortReason,
|
|
873
1016
|
httpStatus,
|
|
@@ -880,15 +1023,23 @@ function mapIteratorAbortToGreenlightStatus(iteration, pollTimeout, deps) {
|
|
|
880
1023
|
__name(mapIteratorAbortToGreenlightStatus, "mapIteratorAbortToGreenlightStatus");
|
|
881
1024
|
|
|
882
1025
|
// src/lib/sdk/domain/pollCiGreenlight/index.ts
|
|
883
|
-
async function pollCiGreenlightStatus(deps, apiConfig, {
|
|
1026
|
+
async function pollCiGreenlightStatus(deps, apiConfig, {
|
|
1027
|
+
onRunStageChanged = /* @__PURE__ */ __name(() => void 0, "onRunStageChanged"),
|
|
1028
|
+
runId,
|
|
1029
|
+
...pollConfig
|
|
1030
|
+
}) {
|
|
884
1031
|
const { log } = deps;
|
|
885
|
-
const {
|
|
1032
|
+
const {
|
|
1033
|
+
abortOnSuperseded = pollCiGreenlightDefaults.abortOnSuperseded,
|
|
1034
|
+
pollTimeout = pollCiGreenlightDefaults.pollTimeout
|
|
1035
|
+
} = pollConfig;
|
|
886
1036
|
const iterator = makePollCiGreenlightStatusIterator(deps, apiConfig, {
|
|
887
1037
|
runId,
|
|
888
1038
|
...pollConfig
|
|
889
1039
|
});
|
|
890
1040
|
for await (const lastPoll of iterator) {
|
|
891
|
-
if (lastPoll.isAborted)
|
|
1041
|
+
if (lastPoll.isAborted)
|
|
1042
|
+
return mapIteratorAbortToGreenlightStatus(lastPoll, pollTimeout, deps);
|
|
892
1043
|
const { previousStatus, stageChanged, status } = lastPoll;
|
|
893
1044
|
if (stageChanged) {
|
|
894
1045
|
try {
|
|
@@ -901,7 +1052,10 @@ async function pollCiGreenlightStatus(deps, apiConfig, { onRunStageChanged = /*
|
|
|
901
1052
|
const isSuperseded = rootRunId !== relevantRunId;
|
|
902
1053
|
const shouldAbortOnSuperseded = isSuperseded && abortOnSuperseded;
|
|
903
1054
|
if (shouldAbortOnSuperseded) {
|
|
904
|
-
const message = buildSupersededAbortLogMessage(
|
|
1055
|
+
const message = buildSupersededAbortLogMessage(
|
|
1056
|
+
rootRunUrl,
|
|
1057
|
+
relevantRunUrl
|
|
1058
|
+
);
|
|
905
1059
|
log.warn(message);
|
|
906
1060
|
return {
|
|
907
1061
|
abortReason: "superseded-run",
|
|
@@ -910,7 +1064,10 @@ async function pollCiGreenlightStatus(deps, apiConfig, { onRunStageChanged = /*
|
|
|
910
1064
|
};
|
|
911
1065
|
}
|
|
912
1066
|
if (isSuperseded) {
|
|
913
|
-
const message = buildSupersededContinueLogMessage(
|
|
1067
|
+
const message = buildSupersededContinueLogMessage(
|
|
1068
|
+
rootRunUrl,
|
|
1069
|
+
relevantRunUrl
|
|
1070
|
+
);
|
|
914
1071
|
log.info(message);
|
|
915
1072
|
}
|
|
916
1073
|
switch (runStage) {
|
|
@@ -950,10 +1107,19 @@ async function pollCiGreenlightStatus(deps, apiConfig, { onRunStageChanged = /*
|
|
|
950
1107
|
__name(pollCiGreenlightStatus, "pollCiGreenlightStatus");
|
|
951
1108
|
|
|
952
1109
|
// src/lib/sdk/index.ts
|
|
953
|
-
function makeQaWolfSdk({
|
|
1110
|
+
function makeQaWolfSdk({
|
|
1111
|
+
apiKey,
|
|
1112
|
+
serviceBase = defaultServiceBase,
|
|
1113
|
+
userAgent = defaultUserAgent
|
|
1114
|
+
}, {
|
|
1115
|
+
fetch = defaultFetch,
|
|
1116
|
+
log = defaultLogDriver
|
|
1117
|
+
} = {}) {
|
|
954
1118
|
if (typeof fetch !== "function") {
|
|
955
|
-
throw Error(
|
|
956
|
-
|
|
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
|
+
);
|
|
957
1123
|
}
|
|
958
1124
|
const deps = {
|
|
959
1125
|
// Versions of fetch may have different default timeouts. For consistency, we explicitly set it to 2 minutes here.
|
|
@@ -962,22 +1128,26 @@ We recommend 'undici' package for that purpose. See the Requirement section of o
|
|
|
962
1128
|
fetch: buildFetchWithTimeout(fetch, 12e4),
|
|
963
1129
|
log
|
|
964
1130
|
};
|
|
965
|
-
const apiConfig = {
|
|
966
|
-
apiKey,
|
|
967
|
-
serviceBase,
|
|
968
|
-
userAgent
|
|
969
|
-
};
|
|
1131
|
+
const apiConfig = { apiKey, serviceBase, userAgent };
|
|
970
1132
|
return {
|
|
971
1133
|
attemptNotifyDeploy: attemptNotifyDeploy.bind(null, deps, apiConfig),
|
|
972
|
-
generateSignedUrlForRunInputsExecutablesStorage: generateSignedUrlForRunInputsExecutablesStorage.bind(
|
|
1134
|
+
generateSignedUrlForRunInputsExecutablesStorage: generateSignedUrlForRunInputsExecutablesStorage.bind(
|
|
1135
|
+
null,
|
|
1136
|
+
deps,
|
|
1137
|
+
apiConfig
|
|
1138
|
+
),
|
|
973
1139
|
generateSignedUrlForTempTeamStorage: generateSignedUrlForTempTeamStorage.bind(null, deps, apiConfig),
|
|
974
|
-
makePollCiGreenlightStatusIterator: makePollCiGreenlightStatusIterator.bind(
|
|
1140
|
+
makePollCiGreenlightStatusIterator: makePollCiGreenlightStatusIterator.bind(
|
|
1141
|
+
null,
|
|
1142
|
+
deps,
|
|
1143
|
+
apiConfig
|
|
1144
|
+
),
|
|
975
1145
|
notifyTerminatedEphemeralEnvironment: notifyTerminatedEphemeralEnvironment.bind(null, deps, apiConfig),
|
|
976
1146
|
pollCiGreenlightStatus: pollCiGreenlightStatus.bind(null, deps, apiConfig)
|
|
977
1147
|
};
|
|
978
1148
|
}
|
|
979
1149
|
__name(makeQaWolfSdk, "makeQaWolfSdk");
|
|
980
|
-
|
|
981
|
-
|
|
1150
|
+
export {
|
|
1151
|
+
makeQaWolfSdk
|
|
1152
|
+
};
|
|
982
1153
|
//# sourceMappingURL=index.js.map
|
|
983
|
-
//# sourceMappingURL=index.js.map
|