squally-reporter 0.13.1 → 0.14.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 +38 -4
- package/dist/ci-identity.d.ts +35 -0
- package/dist/ci-identity.d.ts.map +1 -0
- package/dist/ci-identity.js +206 -0
- package/dist/ci-identity.js.map +1 -0
- package/dist/cli.d.ts +35 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +240 -0
- package/dist/cli.js.map +1 -0
- package/dist/http-config.d.ts +5 -0
- package/dist/http-config.d.ts.map +1 -0
- package/dist/http-config.js +34 -0
- package/dist/http-config.js.map +1 -0
- package/dist/index.d.ts +2 -17
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +116 -324
- package/dist/index.js.map +1 -1
- package/dist/text.d.ts +3 -0
- package/dist/text.d.ts.map +1 -0
- package/dist/text.js +23 -0
- package/dist/text.js.map +1 -0
- package/package.json +6 -2
package/README.md
CHANGED
|
@@ -229,14 +229,48 @@ as **Cancelled**: the reporter sends what finished and tells Squally the run
|
|
|
229
229
|
was interrupted. Your exit code stays Playwright's own (130). This needs
|
|
230
230
|
Playwright itself to receive the signal.
|
|
231
231
|
|
|
232
|
-
**On GitHub Actions
|
|
232
|
+
**On GitHub Actions** a cancelled workflow sends the signal to the step's
|
|
233
|
+
shell, not to Playwright, so the reporter never reports the end. Add one step
|
|
234
|
+
after the tests (0.14.0) that marks the run cancelled in Squally:
|
|
233
235
|
|
|
234
236
|
```yaml
|
|
235
|
-
|
|
236
|
-
|
|
237
|
+
jobs:
|
|
238
|
+
test:
|
|
239
|
+
runs-on: ubuntu-latest
|
|
240
|
+
env:
|
|
241
|
+
SQUALLY_INGEST_KEY: ${{ secrets.SQUALLY_INGEST_KEY }}
|
|
242
|
+
steps:
|
|
243
|
+
# ...checkout, setup-node, npm ci, playwright install
|
|
244
|
+
- name: Run Playwright tests
|
|
245
|
+
run: npx playwright test
|
|
246
|
+
- name: Mark Squally run cancelled
|
|
247
|
+
if: ${{ cancelled() }}
|
|
248
|
+
run: npx squally-reporter cancel
|
|
237
249
|
```
|
|
238
250
|
|
|
239
|
-
|
|
251
|
+
`npx squally-reporter cancel` finds the run by the same CI run id the reporter
|
|
252
|
+
sent from this job, marks every shard of it that is still running as
|
|
253
|
+
cancelled, and prints one line: "Marked run #N as cancelled in Squally
|
|
254
|
+
(X shards)", "Nothing to cancel: no run recorded for <id>" when the job was
|
|
255
|
+
cancelled before its first test, or "Run already finished". It never fails the
|
|
256
|
+
step: a missing key, an unreachable Squally, a 401 or a 5xx is one warning and
|
|
257
|
+
exit code 0. It needs the key in the step's environment - set it at job
|
|
258
|
+
level, as above, or on the step too. A Squally without the cancel endpoint
|
|
259
|
+
answers 404, which is a warning as well.
|
|
260
|
+
|
|
261
|
+
Two things to know:
|
|
262
|
+
|
|
263
|
+
- **Set `SQUALLY_CI_JOB_KEY` at job level**, not only on the test step. The
|
|
264
|
+
cancel step builds the id the same way the reporter did; without the key it
|
|
265
|
+
names another run - or none. `npx squally-reporter cancel --job-key <key>`
|
|
266
|
+
passes it explicitly.
|
|
267
|
+
- **A fail-fast matrix marks the whole group cancelled.** With GitHub's
|
|
268
|
+
default `fail-fast: true`, one failing shard cancels the others, their
|
|
269
|
+
cancel steps run, and the whole run shows as **Cancelled** instead of
|
|
270
|
+
**Failed**. Set `fail-fast: false` on a sharded job so a
|
|
271
|
+
real failure stays a failure.
|
|
272
|
+
|
|
273
|
+
Without the step, a cancelled workflow shows as **incomplete** in Squally.
|
|
240
274
|
|
|
241
275
|
Without that - or after any hard kill (SIGKILL) - the reporter never gets to
|
|
242
276
|
report the end: the run stays *running* until Squally's hourly check marks it
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/** squally-app's V2_FIELD_LIMITS.ciJobKey. */
|
|
2
|
+
export declare const CI_JOB_KEY_MAX = 64;
|
|
3
|
+
/** squally-app's V2_FIELD_LIMITS.ciRunId - the reporter truncates the id to this before sending. */
|
|
4
|
+
export declare const CI_RUN_ID_MAX = 200;
|
|
5
|
+
/**
|
|
6
|
+
* SQUALLY_CI_JOB_KEY's alphabet - the server's CI_JOB_KEY_PATTERN, exactly. It
|
|
7
|
+
* becomes part of the CI run id and of a GitHub check name, which is why it is
|
|
8
|
+
* this narrow.
|
|
9
|
+
*/
|
|
10
|
+
export declare const CI_JOB_KEY_PATTERN: RegExp;
|
|
11
|
+
export declare function detectCiRunIdFromEnv(env: NodeJS.ProcessEnv, jobKey?: string | null): string | null;
|
|
12
|
+
export declare function detectCiRunId(env: NodeJS.ProcessEnv, generateFallback: () => string, jobKey?: string | null): string;
|
|
13
|
+
/**
|
|
14
|
+
* SQUALLY_CI_JOB_KEY, checked by squally-app's own rule (letters, digits,
|
|
15
|
+
* '.', '_' and '-', at most 64). An invalid key is a warning, never a failed
|
|
16
|
+
* test run: the reporter continues WITHOUT a key - the id it would have built
|
|
17
|
+
* without one, and no ciJobKey - rather than send a value the server refuses
|
|
18
|
+
* or guess a cleaned-up one. Unset or empty: no key, no warning.
|
|
19
|
+
*/
|
|
20
|
+
export declare function resolveCiJobKey(env: NodeJS.ProcessEnv): {
|
|
21
|
+
key: string | null;
|
|
22
|
+
warning: string | null;
|
|
23
|
+
};
|
|
24
|
+
export declare const DEFAULT_INGEST_URL = "https://app.squally.dev";
|
|
25
|
+
export declare const READ_KEY_PREFIX = "sqly_ro_";
|
|
26
|
+
export declare function envValue(env: NodeJS.ProcessEnv, name: string): string | undefined;
|
|
27
|
+
export interface ConnectionOptions {
|
|
28
|
+
apiUrl?: string;
|
|
29
|
+
apiKey?: string;
|
|
30
|
+
}
|
|
31
|
+
export declare function resolveConnection(options: ConnectionOptions, env: NodeJS.ProcessEnv, warned?: Set<string>, usage?: "reporter" | "cli"): {
|
|
32
|
+
apiUrl?: string;
|
|
33
|
+
apiKey?: string;
|
|
34
|
+
};
|
|
35
|
+
//# sourceMappingURL=ci-identity.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ci-identity.d.ts","sourceRoot":"","sources":["../src/ci-identity.ts"],"names":[],"mappings":"AAYA,8CAA8C;AAC9C,eAAO,MAAM,cAAc,KAAK,CAAC;AACjC,oGAAoG;AACpG,eAAO,MAAM,aAAa,MAAM,CAAC;AAEjC;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,QAAsB,CAAC;AAuBtD,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,CAAC,UAAU,EAAE,MAAM,GAAE,MAAM,GAAG,IAAW,GAAG,MAAM,GAAG,IAAI,CAqBxG;AAED,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,CAAC,UAAU,EAAE,gBAAgB,EAAE,MAAM,MAAM,EAAE,MAAM,GAAE,MAAM,GAAG,IAAW,GAAG,MAAM,CAE1H;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,CAAC,UAAU,GAAG;IAAE,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CActG;AAoCD,eAAO,MAAM,kBAAkB,4BAA4B,CAAC;AAC5D,eAAO,MAAM,eAAe,aAAa,CAAC;AAe1C,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC,UAAU,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAGjF;AAED,MAAM,WAAW,iBAAiB;IAChC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAID,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,iBAAiB,EAC1B,GAAG,EAAE,MAAM,CAAC,UAAU,EACtB,MAAM,GAAE,GAAG,CAAC,MAAM,CAAsB,EACxC,KAAK,GAAE,UAAU,GAAG,KAAkB,GACrC;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAyDtC"}
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// The CI identity of a run (0.14.0): which CI run it belongs to, under which
|
|
3
|
+
// job key, and where it is sent with which key.
|
|
4
|
+
//
|
|
5
|
+
// ITS OWN MODULE because two entry points need exactly these rules: the
|
|
6
|
+
// reporter (index.ts) and `npx squally-reporter cancel` (cli.ts). The cancel
|
|
7
|
+
// names its run by the ciRunId the reporter sent, so the two must compute it
|
|
8
|
+
// the same way - one function, not a copy that can drift. cli.ts must not
|
|
9
|
+
// import index.ts (that would load the whole reporter, and Playwright's types
|
|
10
|
+
// with it, for one POST), so everything both need lives here.
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.READ_KEY_PREFIX = exports.DEFAULT_INGEST_URL = exports.CI_JOB_KEY_PATTERN = exports.CI_RUN_ID_MAX = exports.CI_JOB_KEY_MAX = void 0;
|
|
13
|
+
exports.detectCiRunIdFromEnv = detectCiRunIdFromEnv;
|
|
14
|
+
exports.detectCiRunId = detectCiRunId;
|
|
15
|
+
exports.resolveCiJobKey = resolveCiJobKey;
|
|
16
|
+
exports.envValue = envValue;
|
|
17
|
+
exports.resolveConnection = resolveConnection;
|
|
18
|
+
const text_1 = require("./text");
|
|
19
|
+
/** squally-app's V2_FIELD_LIMITS.ciJobKey. */
|
|
20
|
+
exports.CI_JOB_KEY_MAX = 64;
|
|
21
|
+
/** squally-app's V2_FIELD_LIMITS.ciRunId - the reporter truncates the id to this before sending. */
|
|
22
|
+
exports.CI_RUN_ID_MAX = 200;
|
|
23
|
+
/**
|
|
24
|
+
* SQUALLY_CI_JOB_KEY's alphabet - the server's CI_JOB_KEY_PATTERN, exactly. It
|
|
25
|
+
* becomes part of the CI run id and of a GitHub check name, which is why it is
|
|
26
|
+
* this narrow.
|
|
27
|
+
*/
|
|
28
|
+
exports.CI_JOB_KEY_PATTERN = /^[A-Za-z0-9._-]+$/;
|
|
29
|
+
// env and generateFallback are parameters, not process.env/randomUUID read
|
|
30
|
+
// directly, so this is unit-testable without mocking global state.
|
|
31
|
+
//
|
|
32
|
+
// TWO CALLERS, ONE RULE (0.14.0). The reporter needs an id for every run and
|
|
33
|
+
// falls back to a random one, unique to its own process. The CLI's cancel
|
|
34
|
+
// needs the id the reporter USED - a random one would name no run at all - so
|
|
35
|
+
// it calls detectCiRunIdFromEnv, which is this same rule with null in place of
|
|
36
|
+
// the fallback.
|
|
37
|
+
//
|
|
38
|
+
// THE JOB KEY (0.11.0, SQUALLY_CI_JOB_KEY). Several jobs of one CI run that are
|
|
39
|
+
// not shards of each other - a browser matrix, an "api" and a "ui" suite -
|
|
40
|
+
// share the provider's id, and squally-app grouped them into one run: the
|
|
41
|
+
// second job was handed the first one's run, and its results were refused once
|
|
42
|
+
// that run completed. With a key each job gets an id of its own, shared only
|
|
43
|
+
// by its own shards: the key goes right after the provider's id and BEFORE
|
|
44
|
+
// GitHub's attempt suffix - "<run_id>-<key>-<attempt>" - so squally-app still
|
|
45
|
+
// reads the attempt off the end and links a re-run to the job's own earlier
|
|
46
|
+
// attempt. Without a key every id is byte-identical to 0.10.2. An explicit
|
|
47
|
+
// SQUALLY_CI_RUN_ID still wins outright; the key is then only sent on its own
|
|
48
|
+
// (ciJobKey). The random fallback is already unique to this process and stays
|
|
49
|
+
// as it was.
|
|
50
|
+
function detectCiRunIdFromEnv(env, jobKey = null) {
|
|
51
|
+
if (env.SQUALLY_CI_RUN_ID)
|
|
52
|
+
return env.SQUALLY_CI_RUN_ID;
|
|
53
|
+
const key = jobKey ? `-${jobKey}` : "";
|
|
54
|
+
if (env.GITHUB_RUN_ID) {
|
|
55
|
+
return env.GITHUB_RUN_ATTEMPT
|
|
56
|
+
? `${env.GITHUB_RUN_ID}${key}-${env.GITHUB_RUN_ATTEMPT}`
|
|
57
|
+
: `${env.GITHUB_RUN_ID}${key}`;
|
|
58
|
+
}
|
|
59
|
+
if (env.CI_PIPELINE_ID)
|
|
60
|
+
return `${env.CI_PIPELINE_ID}${key}`;
|
|
61
|
+
if (env.CIRCLE_WORKFLOW_ID)
|
|
62
|
+
return `${env.CIRCLE_WORKFLOW_ID}${key}`;
|
|
63
|
+
// 0.10.0 - the same shape as the three above: the provider's own variable,
|
|
64
|
+
// read directly. BUILD_TAG only in Jenkins' own format, since the name is
|
|
65
|
+
// generic enough for something else to have set it.
|
|
66
|
+
if (env.BUILD_TAG?.startsWith("jenkins-"))
|
|
67
|
+
return `${env.BUILD_TAG}${key}`;
|
|
68
|
+
if (env.BUILD_BUILDID)
|
|
69
|
+
return `${env.BUILD_BUILDID}${key}`;
|
|
70
|
+
if (env.BITBUCKET_BUILD_NUMBER)
|
|
71
|
+
return `${env.BITBUCKET_BUILD_NUMBER}${key}`;
|
|
72
|
+
if (env.BUILDKITE_BUILD_ID)
|
|
73
|
+
return `${env.BUILDKITE_BUILD_ID}${key}`;
|
|
74
|
+
if (env.CODEBUILD_BUILD_ID)
|
|
75
|
+
return `${env.CODEBUILD_BUILD_ID}${key}`;
|
|
76
|
+
if (env.TRAVIS_BUILD_ID)
|
|
77
|
+
return `${env.TRAVIS_BUILD_ID}${key}`;
|
|
78
|
+
if (env.DRONE_BUILD_NUMBER)
|
|
79
|
+
return `${env.DRONE_BUILD_NUMBER}${key}`;
|
|
80
|
+
return null;
|
|
81
|
+
}
|
|
82
|
+
function detectCiRunId(env, generateFallback, jobKey = null) {
|
|
83
|
+
return detectCiRunIdFromEnv(env, jobKey) ?? generateFallback();
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* SQUALLY_CI_JOB_KEY, checked by squally-app's own rule (letters, digits,
|
|
87
|
+
* '.', '_' and '-', at most 64). An invalid key is a warning, never a failed
|
|
88
|
+
* test run: the reporter continues WITHOUT a key - the id it would have built
|
|
89
|
+
* without one, and no ciJobKey - rather than send a value the server refuses
|
|
90
|
+
* or guess a cleaned-up one. Unset or empty: no key, no warning.
|
|
91
|
+
*/
|
|
92
|
+
function resolveCiJobKey(env) {
|
|
93
|
+
const raw = env.SQUALLY_CI_JOB_KEY;
|
|
94
|
+
if (raw === undefined || raw.trim() === "")
|
|
95
|
+
return { key: null, warning: null };
|
|
96
|
+
const key = raw.trim();
|
|
97
|
+
if (key.length > exports.CI_JOB_KEY_MAX || !exports.CI_JOB_KEY_PATTERN.test(key)) {
|
|
98
|
+
return {
|
|
99
|
+
key: null,
|
|
100
|
+
warning: `[squally-reporter] SQUALLY_CI_JOB_KEY ${JSON.stringify((0, text_1.truncate)(raw, 80))} is not used: it may hold only ` +
|
|
101
|
+
`letters, digits, '.', '_' and '-', at most ${exports.CI_JOB_KEY_MAX} characters. This job reports ` +
|
|
102
|
+
"without a key - like before - so jobs sharing this CI run's id may still be refused as a collision.",
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
return { key, warning: null };
|
|
106
|
+
}
|
|
107
|
+
// ---------------------------------------------------------------------------
|
|
108
|
+
// Where the ingest URL and key come from (0.9.0)
|
|
109
|
+
// ---------------------------------------------------------------------------
|
|
110
|
+
//
|
|
111
|
+
// RENAMED, WITH A FALLBACK. Up to 0.8.x the reporter read SQUALLY_API_URL and
|
|
112
|
+
// SQUALLY_API_KEY. Those names now belong to Squally's read API (a read key,
|
|
113
|
+
// "sqly_ro_...", for scripts and agents), so the reporter reads
|
|
114
|
+
// SQUALLY_INGEST_URL / SQUALLY_INGEST_KEY - and still accepts the old pair,
|
|
115
|
+
// with a deprecation warning, so an existing CI setup keeps reporting.
|
|
116
|
+
//
|
|
117
|
+
// Because the old names now MEAN something else, the fallback is guarded:
|
|
118
|
+
// - a read key in SQUALLY_API_KEY is never sent to ingest. It could only
|
|
119
|
+
// ever fail authentication, and it is the one mix-up the new naming
|
|
120
|
+
// invites: the read key set for an agent, the reporter in the same shell.
|
|
121
|
+
// - SQUALLY_API_URL is taken only together with SQUALLY_API_KEY. Set on its
|
|
122
|
+
// own it is the read API's base override now, and pointing ingest at it
|
|
123
|
+
// would 404 with a message blaming the app.
|
|
124
|
+
// Explicit options win over all of it, as before.
|
|
125
|
+
//
|
|
126
|
+
// Every warning names variables, never a value.
|
|
127
|
+
//
|
|
128
|
+
// THE DEFAULT URL (0.12.0): a key without a URL used to send nothing. Now it
|
|
129
|
+
// reports to https://app.squally.dev - the only Squally there is - so the
|
|
130
|
+
// setup is one secret, not two. NOT when SQUALLY_API_URL is set but unused
|
|
131
|
+
// (a key from the new name or the options): that variable says someone meant
|
|
132
|
+
// another target, and replacing it silently with production would be the
|
|
133
|
+
// worst reading of it. That case still skips, with the warning it had.
|
|
134
|
+
//
|
|
135
|
+
// A READ KEY IS REFUSED FROM EVERY SOURCE (0.12.0, squally-app #23): the
|
|
136
|
+
// option and SQUALLY_INGEST_KEY too, not only the legacy variable. The app
|
|
137
|
+
// refuses it as well (401 read_api_key), but saying so here costs no request
|
|
138
|
+
// and names the variable to fix.
|
|
139
|
+
exports.DEFAULT_INGEST_URL = "https://app.squally.dev";
|
|
140
|
+
exports.READ_KEY_PREFIX = "sqly_ro_";
|
|
141
|
+
// One deprecation warning per variable per run: the reporter is constructed
|
|
142
|
+
// once per run, but a config that builds it twice must not say it twice.
|
|
143
|
+
const deprecationsWarned = new Set();
|
|
144
|
+
function warnDeprecated(oldName, newName, warned) {
|
|
145
|
+
if (warned.has(oldName))
|
|
146
|
+
return;
|
|
147
|
+
warned.add(oldName);
|
|
148
|
+
console.warn(`[squally-reporter] ${oldName} is deprecated - rename it to ${newName}. ` +
|
|
149
|
+
`It still works for now, but the name now belongs to Squally's read API.`);
|
|
150
|
+
}
|
|
151
|
+
function envValue(env, name) {
|
|
152
|
+
const value = env[name];
|
|
153
|
+
return value ? value : undefined;
|
|
154
|
+
}
|
|
155
|
+
// `usage` (0.14.0) only changes the words of the no-key warning: the CLI has
|
|
156
|
+
// no playwright.config.ts option to point to and skips a cancel, not a report.
|
|
157
|
+
function resolveConnection(options, env, warned = deprecationsWarned, usage = "reporter") {
|
|
158
|
+
let apiKey = options.apiKey;
|
|
159
|
+
let keyFromLegacy = false;
|
|
160
|
+
if (apiKey === undefined) {
|
|
161
|
+
apiKey = envValue(env, "SQUALLY_INGEST_KEY");
|
|
162
|
+
if (apiKey === undefined) {
|
|
163
|
+
const legacy = envValue(env, "SQUALLY_API_KEY");
|
|
164
|
+
if (legacy?.startsWith(exports.READ_KEY_PREFIX)) {
|
|
165
|
+
console.warn("[squally-reporter] SQUALLY_API_KEY holds a read key; set SQUALLY_INGEST_KEY to the " +
|
|
166
|
+
"project's ingest key. Nothing from this run will be sent.");
|
|
167
|
+
return {};
|
|
168
|
+
}
|
|
169
|
+
if (legacy !== undefined) {
|
|
170
|
+
warnDeprecated("SQUALLY_API_KEY", "SQUALLY_INGEST_KEY", warned);
|
|
171
|
+
apiKey = legacy;
|
|
172
|
+
keyFromLegacy = true;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
// A read key from the option or SQUALLY_INGEST_KEY (0.12.0) - the legacy
|
|
177
|
+
// variable said so above already.
|
|
178
|
+
if (apiKey?.startsWith(exports.READ_KEY_PREFIX)) {
|
|
179
|
+
const source = options.apiKey !== undefined ? "The apiKey option" : "SQUALLY_INGEST_KEY";
|
|
180
|
+
console.warn(`[squally-reporter] ${source} holds a read key (sqly_ro_…); reporting needs the project's ` +
|
|
181
|
+
"ingest key (Settings › Project › Ingest key). Nothing from this run will be sent.");
|
|
182
|
+
return {};
|
|
183
|
+
}
|
|
184
|
+
let apiUrl = options.apiUrl ?? envValue(env, "SQUALLY_INGEST_URL");
|
|
185
|
+
const legacyUrl = envValue(env, "SQUALLY_API_URL");
|
|
186
|
+
if (apiUrl === undefined && keyFromLegacy && legacyUrl !== undefined) {
|
|
187
|
+
warnDeprecated("SQUALLY_API_URL", "SQUALLY_INGEST_URL", warned);
|
|
188
|
+
apiUrl = legacyUrl;
|
|
189
|
+
}
|
|
190
|
+
// Set but not taken (see above): someone meant another target - never
|
|
191
|
+
// fall back to production in its place.
|
|
192
|
+
const ignoredUrl = apiUrl === undefined && legacyUrl !== undefined;
|
|
193
|
+
if (!apiKey || ignoredUrl) {
|
|
194
|
+
console.warn(`[squally-reporter] no ingest key configured, skipping ${usage === "cli" ? "cancel" : "report"} - ` +
|
|
195
|
+
"set SQUALLY_INGEST_KEY " +
|
|
196
|
+
`(and SQUALLY_INGEST_URL only for a Squally other than ${exports.DEFAULT_INGEST_URL})` +
|
|
197
|
+
(usage === "cli" ? "" : ", or pass apiKey in playwright.config.ts") +
|
|
198
|
+
(ignoredUrl
|
|
199
|
+
? ". SQUALLY_API_URL is set but not used for ingest unless the key comes from " +
|
|
200
|
+
"SQUALLY_API_KEY too - set SQUALLY_INGEST_URL."
|
|
201
|
+
: ""));
|
|
202
|
+
return {};
|
|
203
|
+
}
|
|
204
|
+
return { apiUrl: apiUrl ?? exports.DEFAULT_INGEST_URL, apiKey };
|
|
205
|
+
}
|
|
206
|
+
//# sourceMappingURL=ci-identity.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ci-identity.js","sourceRoot":"","sources":["../src/ci-identity.ts"],"names":[],"mappings":";AAAA,6EAA6E;AAC7E,gDAAgD;AAChD,EAAE;AACF,wEAAwE;AACxE,6EAA6E;AAC7E,6EAA6E;AAC7E,0EAA0E;AAC1E,8EAA8E;AAC9E,8DAA8D;;;AAqC9D,oDAqBC;AAED,sCAEC;AASD,0CAcC;AAoDD,4BAGC;AASD,8CA8DC;AAjND,iCAAkC;AAElC,8CAA8C;AACjC,QAAA,cAAc,GAAG,EAAE,CAAC;AACjC,oGAAoG;AACvF,QAAA,aAAa,GAAG,GAAG,CAAC;AAEjC;;;;GAIG;AACU,QAAA,kBAAkB,GAAG,mBAAmB,CAAC;AAEtD,2EAA2E;AAC3E,mEAAmE;AACnE,EAAE;AACF,6EAA6E;AAC7E,0EAA0E;AAC1E,8EAA8E;AAC9E,+EAA+E;AAC/E,gBAAgB;AAChB,EAAE;AACF,gFAAgF;AAChF,2EAA2E;AAC3E,0EAA0E;AAC1E,+EAA+E;AAC/E,6EAA6E;AAC7E,2EAA2E;AAC3E,8EAA8E;AAC9E,4EAA4E;AAC5E,2EAA2E;AAC3E,8EAA8E;AAC9E,8EAA8E;AAC9E,aAAa;AACb,SAAgB,oBAAoB,CAAC,GAAsB,EAAE,SAAwB,IAAI;IACvF,IAAI,GAAG,CAAC,iBAAiB;QAAE,OAAO,GAAG,CAAC,iBAAiB,CAAC;IACxD,MAAM,GAAG,GAAG,MAAM,CAAC,CAAC,CAAC,IAAI,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IACvC,IAAI,GAAG,CAAC,aAAa,EAAE,CAAC;QACtB,OAAO,GAAG,CAAC,kBAAkB;YAC3B,CAAC,CAAC,GAAG,GAAG,CAAC,aAAa,GAAG,GAAG,IAAI,GAAG,CAAC,kBAAkB,EAAE;YACxD,CAAC,CAAC,GAAG,GAAG,CAAC,aAAa,GAAG,GAAG,EAAE,CAAC;IACnC,CAAC;IACD,IAAI,GAAG,CAAC,cAAc;QAAE,OAAO,GAAG,GAAG,CAAC,cAAc,GAAG,GAAG,EAAE,CAAC;IAC7D,IAAI,GAAG,CAAC,kBAAkB;QAAE,OAAO,GAAG,GAAG,CAAC,kBAAkB,GAAG,GAAG,EAAE,CAAC;IACrE,2EAA2E;IAC3E,0EAA0E;IAC1E,oDAAoD;IACpD,IAAI,GAAG,CAAC,SAAS,EAAE,UAAU,CAAC,UAAU,CAAC;QAAE,OAAO,GAAG,GAAG,CAAC,SAAS,GAAG,GAAG,EAAE,CAAC;IAC3E,IAAI,GAAG,CAAC,aAAa;QAAE,OAAO,GAAG,GAAG,CAAC,aAAa,GAAG,GAAG,EAAE,CAAC;IAC3D,IAAI,GAAG,CAAC,sBAAsB;QAAE,OAAO,GAAG,GAAG,CAAC,sBAAsB,GAAG,GAAG,EAAE,CAAC;IAC7E,IAAI,GAAG,CAAC,kBAAkB;QAAE,OAAO,GAAG,GAAG,CAAC,kBAAkB,GAAG,GAAG,EAAE,CAAC;IACrE,IAAI,GAAG,CAAC,kBAAkB;QAAE,OAAO,GAAG,GAAG,CAAC,kBAAkB,GAAG,GAAG,EAAE,CAAC;IACrE,IAAI,GAAG,CAAC,eAAe;QAAE,OAAO,GAAG,GAAG,CAAC,eAAe,GAAG,GAAG,EAAE,CAAC;IAC/D,IAAI,GAAG,CAAC,kBAAkB;QAAE,OAAO,GAAG,GAAG,CAAC,kBAAkB,GAAG,GAAG,EAAE,CAAC;IACrE,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAgB,aAAa,CAAC,GAAsB,EAAE,gBAA8B,EAAE,SAAwB,IAAI;IAChH,OAAO,oBAAoB,CAAC,GAAG,EAAE,MAAM,CAAC,IAAI,gBAAgB,EAAE,CAAC;AACjE,CAAC;AAED;;;;;;GAMG;AACH,SAAgB,eAAe,CAAC,GAAsB;IACpD,MAAM,GAAG,GAAG,GAAG,CAAC,kBAAkB,CAAC;IACnC,IAAI,GAAG,KAAK,SAAS,IAAI,GAAG,CAAC,IAAI,EAAE,KAAK,EAAE;QAAE,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IAChF,MAAM,GAAG,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC;IACvB,IAAI,GAAG,CAAC,MAAM,GAAG,sBAAc,IAAI,CAAC,0BAAkB,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;QACjE,OAAO;YACL,GAAG,EAAE,IAAI;YACT,OAAO,EACL,yCAAyC,IAAI,CAAC,SAAS,CAAC,IAAA,eAAQ,EAAC,GAAG,EAAE,EAAE,CAAC,CAAC,iCAAiC;gBAC3G,8CAA8C,sBAAc,gCAAgC;gBAC5F,qGAAqG;SACxG,CAAC;IACJ,CAAC;IACD,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;AAChC,CAAC;AAGD,8EAA8E;AAC9E,iDAAiD;AACjD,8EAA8E;AAC9E,EAAE;AACF,8EAA8E;AAC9E,6EAA6E;AAC7E,gEAAgE;AAChE,4EAA4E;AAC5E,uEAAuE;AACvE,EAAE;AACF,0EAA0E;AAC1E,2EAA2E;AAC3E,wEAAwE;AACxE,8EAA8E;AAC9E,8EAA8E;AAC9E,4EAA4E;AAC5E,gDAAgD;AAChD,kDAAkD;AAClD,EAAE;AACF,gDAAgD;AAChD,EAAE;AACF,6EAA6E;AAC7E,0EAA0E;AAC1E,2EAA2E;AAC3E,6EAA6E;AAC7E,yEAAyE;AACzE,uEAAuE;AACvE,EAAE;AACF,yEAAyE;AACzE,2EAA2E;AAC3E,6EAA6E;AAC7E,iCAAiC;AAEpB,QAAA,kBAAkB,GAAG,yBAAyB,CAAC;AAC/C,QAAA,eAAe,GAAG,UAAU,CAAC;AAE1C,4EAA4E;AAC5E,yEAAyE;AACzE,MAAM,kBAAkB,GAAG,IAAI,GAAG,EAAU,CAAC;AAE7C,SAAS,cAAc,CAAC,OAAe,EAAE,OAAe,EAAE,MAAmB;IAC3E,IAAI,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC;QAAE,OAAO;IAChC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IACpB,OAAO,CAAC,IAAI,CACV,sBAAsB,OAAO,iCAAiC,OAAO,IAAI;QACvE,yEAAyE,CAC5E,CAAC;AACJ,CAAC;AAED,SAAgB,QAAQ,CAAC,GAAsB,EAAE,IAAY;IAC3D,MAAM,KAAK,GAAG,GAAG,CAAC,IAAI,CAAC,CAAC;IACxB,OAAO,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;AACnC,CAAC;AAOD,6EAA6E;AAC7E,+EAA+E;AAC/E,SAAgB,iBAAiB,CAC/B,OAA0B,EAC1B,GAAsB,EACtB,SAAsB,kBAAkB,EACxC,QAA4B,UAAU;IAEtC,IAAI,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAC5B,IAAI,aAAa,GAAG,KAAK,CAAC;IAC1B,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;QACzB,MAAM,GAAG,QAAQ,CAAC,GAAG,EAAE,oBAAoB,CAAC,CAAC;QAC7C,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;YACzB,MAAM,MAAM,GAAG,QAAQ,CAAC,GAAG,EAAE,iBAAiB,CAAC,CAAC;YAChD,IAAI,MAAM,EAAE,UAAU,CAAC,uBAAe,CAAC,EAAE,CAAC;gBACxC,OAAO,CAAC,IAAI,CACV,qFAAqF;oBACnF,2DAA2D,CAC9D,CAAC;gBACF,OAAO,EAAE,CAAC;YACZ,CAAC;YACD,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;gBACzB,cAAc,CAAC,iBAAiB,EAAE,oBAAoB,EAAE,MAAM,CAAC,CAAC;gBAChE,MAAM,GAAG,MAAM,CAAC;gBAChB,aAAa,GAAG,IAAI,CAAC;YACvB,CAAC;QACH,CAAC;IACH,CAAC;IAED,yEAAyE;IACzE,kCAAkC;IAClC,IAAI,MAAM,EAAE,UAAU,CAAC,uBAAe,CAAC,EAAE,CAAC;QACxC,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC,oBAAoB,CAAC;QACzF,OAAO,CAAC,IAAI,CACV,sBAAsB,MAAM,+DAA+D;YACzF,mFAAmF,CACtF,CAAC;QACF,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,IAAI,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,QAAQ,CAAC,GAAG,EAAE,oBAAoB,CAAC,CAAC;IACnE,MAAM,SAAS,GAAG,QAAQ,CAAC,GAAG,EAAE,iBAAiB,CAAC,CAAC;IACnD,IAAI,MAAM,KAAK,SAAS,IAAI,aAAa,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;QACrE,cAAc,CAAC,iBAAiB,EAAE,oBAAoB,EAAE,MAAM,CAAC,CAAC;QAChE,MAAM,GAAG,SAAS,CAAC;IACrB,CAAC;IACD,sEAAsE;IACtE,wCAAwC;IACxC,MAAM,UAAU,GAAG,MAAM,KAAK,SAAS,IAAI,SAAS,KAAK,SAAS,CAAC;IAEnE,IAAI,CAAC,MAAM,IAAI,UAAU,EAAE,CAAC;QAC1B,OAAO,CAAC,IAAI,CACV,yDAAyD,KAAK,KAAK,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,KAAK;YACjG,yBAAyB;YACzB,yDAAyD,0BAAkB,GAAG;YAC9E,CAAC,KAAK,KAAK,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,0CAA0C,CAAC;YACnE,CAAC,UAAU;gBACT,CAAC,CAAC,6EAA6E;oBAC7E,+CAA+C;gBACjD,CAAC,CAAC,EAAE,CAAC,CACV,CAAC;QACF,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,OAAO,EAAE,MAAM,EAAE,MAAM,IAAI,0BAAkB,EAAE,MAAM,EAAE,CAAC;AAC1D,CAAC"}
|
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
export declare const USAGE: string;
|
|
3
|
+
export type CancelAnswer = {
|
|
4
|
+
cancelled: true;
|
|
5
|
+
marked: number;
|
|
6
|
+
runNumber: number;
|
|
7
|
+
} | {
|
|
8
|
+
cancelled: false;
|
|
9
|
+
reason: "nothing_recorded" | "already_finished";
|
|
10
|
+
};
|
|
11
|
+
/** The one line printed for the app's answer. */
|
|
12
|
+
export declare function describeCancelAnswer(answer: CancelAnswer, ciRunId: string): string;
|
|
13
|
+
export type ParsedArgs = {
|
|
14
|
+
kind: "cancel";
|
|
15
|
+
jobKey: string | undefined;
|
|
16
|
+
} | {
|
|
17
|
+
kind: "help";
|
|
18
|
+
} | {
|
|
19
|
+
kind: "usage_error";
|
|
20
|
+
message: string;
|
|
21
|
+
};
|
|
22
|
+
export declare function parseArgs(argv: readonly string[]): ParsedArgs;
|
|
23
|
+
export interface CancelDeps {
|
|
24
|
+
env: NodeJS.ProcessEnv;
|
|
25
|
+
log: (line: string) => void;
|
|
26
|
+
warn: (line: string) => void;
|
|
27
|
+
/** API_REQUEST_TIMEOUT_MS; a parameter so a test of the hung-server path needs no 60 s. */
|
|
28
|
+
timeoutMs?: number;
|
|
29
|
+
retryDelayMs?: number;
|
|
30
|
+
}
|
|
31
|
+
/** `cancel`, start to finish. Never throws; resolves when there is nothing left to do. */
|
|
32
|
+
export declare function runCancel(jobKeyArg: string | undefined, deps: CancelDeps): Promise<void>;
|
|
33
|
+
/** The process entry. Returns the exit code: 0 for every cancel, 2 for a usage error. */
|
|
34
|
+
export declare function main(argv: readonly string[], env?: NodeJS.ProcessEnv): Promise<number>;
|
|
35
|
+
//# sourceMappingURL=cli.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AA+BA,eAAO,MAAM,KAAK,QAUN,CAAC;AAEb,MAAM,MAAM,YAAY,GACpB;IAAE,SAAS,EAAE,IAAI,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,GACtD;IAAE,SAAS,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,kBAAkB,GAAG,kBAAkB,CAAA;CAAE,CAAC;AAE1E,iDAAiD;AACjD,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAQlF;AAcD,MAAM,MAAM,UAAU,GAClB;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,GAC9C;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAChB;IAAE,IAAI,EAAE,aAAa,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAE7C,wBAAgB,SAAS,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,UAAU,CAqB7D;AAED,MAAM,WAAW,UAAU;IACzB,GAAG,EAAE,MAAM,CAAC,UAAU,CAAC;IACvB,GAAG,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5B,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC7B,2FAA2F;IAC3F,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAcD,0FAA0F;AAC1F,wBAAsB,SAAS,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,EAAE,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAsG9F;AAED,yFAAyF;AACzF,wBAAsB,IAAI,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,EAAE,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,OAAO,CAAC,MAAM,CAAC,CAoBzG"}
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
// `npx squally-reporter cancel` (0.14.0; squally-app docs/ingest-v2-spec.md
|
|
4
|
+
// section 1.9).
|
|
5
|
+
//
|
|
6
|
+
// A CI step under `if: ${{ cancelled() }}` marks the run as cancelled in
|
|
7
|
+
// Squally. It is the backstop for a reporter that never reached its own onEnd:
|
|
8
|
+
// on GitHub Actions a cancelled workflow sends SIGINT only to the step's shell,
|
|
9
|
+
// Playwright is killed, and without this step the run sits in "running" until
|
|
10
|
+
// the run timeout ends it as incomplete.
|
|
11
|
+
//
|
|
12
|
+
// ONE POST, POST /api/ingest/v2/runs/cancel { ciRunId }. The id is the one the
|
|
13
|
+
// reporter sent from the same job's environment (ci-identity.ts - the same
|
|
14
|
+
// function, not a copy), so the app finds the run's group by it. Every running
|
|
15
|
+
// shard of the group is marked; a group that has finished, or that never
|
|
16
|
+
// began, is an answer, not an error.
|
|
17
|
+
//
|
|
18
|
+
// IT NEVER FAILS THE JOB'S STEP: a missing key, an unreachable app, a 401 or a
|
|
19
|
+
// 5xx is one warning and exit 0, as everywhere in this package. Only a command
|
|
20
|
+
// this file does not know is exit 2 - that is a typo in the workflow, and a
|
|
21
|
+
// usage error has no run to protect.
|
|
22
|
+
//
|
|
23
|
+
// IT MUST NOT IMPORT index.ts: that is the whole reporter, loaded for one POST.
|
|
24
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
25
|
+
exports.USAGE = void 0;
|
|
26
|
+
exports.describeCancelAnswer = describeCancelAnswer;
|
|
27
|
+
exports.parseArgs = parseArgs;
|
|
28
|
+
exports.runCancel = runCancel;
|
|
29
|
+
exports.main = main;
|
|
30
|
+
const undici_1 = require("undici");
|
|
31
|
+
const ci_identity_1 = require("./ci-identity");
|
|
32
|
+
const http_config_1 = require("./http-config");
|
|
33
|
+
const text_1 = require("./text");
|
|
34
|
+
const PREFIX = "[squally-reporter]";
|
|
35
|
+
const BODY_LOG_LIMIT = 500;
|
|
36
|
+
exports.USAGE = [
|
|
37
|
+
"Usage: squally-reporter cancel [--job-key <key>]",
|
|
38
|
+
"",
|
|
39
|
+
" cancel Mark this CI run as cancelled in Squally. Run it in a step with",
|
|
40
|
+
" `if: ${{ cancelled() }}`. Reads SQUALLY_INGEST_KEY (and",
|
|
41
|
+
" SQUALLY_INGEST_URL, SQUALLY_CI_RUN_ID, SQUALLY_CI_JOB_KEY) like the",
|
|
42
|
+
" reporter does. Always exits 0.",
|
|
43
|
+
"",
|
|
44
|
+
" --job-key <key> The job's SQUALLY_CI_JOB_KEY, when it is not in this step's",
|
|
45
|
+
" environment.",
|
|
46
|
+
].join("\n");
|
|
47
|
+
/** The one line printed for the app's answer. */
|
|
48
|
+
function describeCancelAnswer(answer, ciRunId) {
|
|
49
|
+
if (answer.cancelled) {
|
|
50
|
+
const shards = `${answer.marked} ${answer.marked === 1 ? "shard" : "shards"}`;
|
|
51
|
+
return `Marked run #${answer.runNumber} as cancelled in Squally (${shards})`;
|
|
52
|
+
}
|
|
53
|
+
return answer.reason === "nothing_recorded"
|
|
54
|
+
? `Nothing to cancel: no run recorded for ${ciRunId}`
|
|
55
|
+
: "Run already finished";
|
|
56
|
+
}
|
|
57
|
+
function parseAnswer(body) {
|
|
58
|
+
if (typeof body !== "object" || body === null)
|
|
59
|
+
return null;
|
|
60
|
+
const b = body;
|
|
61
|
+
if (b.cancelled === true && Number.isInteger(b.marked) && Number.isInteger(b.runNumber)) {
|
|
62
|
+
return { cancelled: true, marked: b.marked, runNumber: b.runNumber };
|
|
63
|
+
}
|
|
64
|
+
if (b.cancelled === false && (b.reason === "nothing_recorded" || b.reason === "already_finished")) {
|
|
65
|
+
return { cancelled: false, reason: b.reason };
|
|
66
|
+
}
|
|
67
|
+
return null;
|
|
68
|
+
}
|
|
69
|
+
function parseArgs(argv) {
|
|
70
|
+
const [command, ...rest] = argv;
|
|
71
|
+
if (command === "--help" || command === "-h" || command === "help")
|
|
72
|
+
return { kind: "help" };
|
|
73
|
+
if (command !== "cancel") {
|
|
74
|
+
return { kind: "usage_error", message: command === undefined ? "No command given." : `Unknown command: ${command}` };
|
|
75
|
+
}
|
|
76
|
+
let jobKey;
|
|
77
|
+
for (let i = 0; i < rest.length; i++) {
|
|
78
|
+
const arg = rest[i];
|
|
79
|
+
if (arg === "--job-key") {
|
|
80
|
+
const value = rest[i + 1];
|
|
81
|
+
if (value === undefined || value.startsWith("--"))
|
|
82
|
+
return { kind: "usage_error", message: "--job-key needs a value." };
|
|
83
|
+
jobKey = value;
|
|
84
|
+
i++;
|
|
85
|
+
}
|
|
86
|
+
else if (arg.startsWith("--job-key=")) {
|
|
87
|
+
jobKey = arg.slice("--job-key=".length);
|
|
88
|
+
}
|
|
89
|
+
else {
|
|
90
|
+
return { kind: "usage_error", message: `Unknown option for cancel: ${arg}` };
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
return { kind: "cancel", jobKey };
|
|
94
|
+
}
|
|
95
|
+
function delay(ms) {
|
|
96
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
97
|
+
}
|
|
98
|
+
function describeError(err, timeoutMs) {
|
|
99
|
+
const name = err instanceof Error ? err.name : "";
|
|
100
|
+
if (name === "TimeoutError" || name === "AbortError")
|
|
101
|
+
return `no response within ${timeoutMs} ms`;
|
|
102
|
+
const cause = err?.cause;
|
|
103
|
+
const causeText = cause instanceof Error ? ` (${cause.message})` : "";
|
|
104
|
+
return `${String(err)}${causeText}`;
|
|
105
|
+
}
|
|
106
|
+
/** `cancel`, start to finish. Never throws; resolves when there is nothing left to do. */
|
|
107
|
+
async function runCancel(jobKeyArg, deps) {
|
|
108
|
+
const { env, log, warn } = deps;
|
|
109
|
+
const timeoutMs = deps.timeoutMs ?? http_config_1.API_REQUEST_TIMEOUT_MS;
|
|
110
|
+
const retryDelayMs = deps.retryDelayMs ?? http_config_1.SERVER_ERROR_RETRY_DELAY_MS;
|
|
111
|
+
// The flag wins over the environment, and is held to the same rule: an
|
|
112
|
+
// invalid key is a warning and no key, as in the reporter - which then
|
|
113
|
+
// built the id without one too.
|
|
114
|
+
const jobKey = (0, ci_identity_1.resolveCiJobKey)(jobKeyArg === undefined ? env : { ...env, SQUALLY_CI_JOB_KEY: jobKeyArg });
|
|
115
|
+
if (jobKey.warning)
|
|
116
|
+
warn(jobKey.warning);
|
|
117
|
+
const id = (0, ci_identity_1.detectCiRunIdFromEnv)(env, jobKey.key);
|
|
118
|
+
if (id === null) {
|
|
119
|
+
warn(`${PREFIX} no CI run id found, nothing to cancel - run this in the CI job that ran the tests, ` +
|
|
120
|
+
"or set SQUALLY_CI_RUN_ID to the value the reporter used.");
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
const ciRunId = (0, text_1.truncate)(id, ci_identity_1.CI_RUN_ID_MAX);
|
|
124
|
+
const originalWarn = console.warn;
|
|
125
|
+
// resolveConnection writes its own warnings with console.warn; route them
|
|
126
|
+
// through `warn` so a caller (and a test) sees every line this prints. `warn`
|
|
127
|
+
// must not itself look up console.warn at call time (see main()).
|
|
128
|
+
console.warn = (...args) => warn(args.map(String).join(" "));
|
|
129
|
+
let connection;
|
|
130
|
+
try {
|
|
131
|
+
connection = (0, ci_identity_1.resolveConnection)({}, env, new Set(), "cli");
|
|
132
|
+
}
|
|
133
|
+
finally {
|
|
134
|
+
console.warn = originalWarn;
|
|
135
|
+
}
|
|
136
|
+
if (!connection.apiUrl || !connection.apiKey)
|
|
137
|
+
return;
|
|
138
|
+
const url = `${connection.apiUrl.replace(/\/+$/, "")}/api/ingest/v2/runs/cancel`;
|
|
139
|
+
const dispatcher = new undici_1.Agent({ headersTimeout: timeoutMs, bodyTimeout: timeoutMs, keepAliveTimeout: 1000 });
|
|
140
|
+
try {
|
|
141
|
+
for (let attempt = 1;; attempt++) {
|
|
142
|
+
const last = attempt >= 2; // one retry
|
|
143
|
+
let response;
|
|
144
|
+
try {
|
|
145
|
+
response = await (0, undici_1.fetch)(url, {
|
|
146
|
+
method: "POST",
|
|
147
|
+
headers: {
|
|
148
|
+
"Content-Type": "application/json",
|
|
149
|
+
Authorization: `Bearer ${connection.apiKey}`,
|
|
150
|
+
"User-Agent": http_config_1.USER_AGENT,
|
|
151
|
+
},
|
|
152
|
+
body: JSON.stringify({ ciRunId }),
|
|
153
|
+
dispatcher,
|
|
154
|
+
signal: AbortSignal.timeout(timeoutMs),
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
catch (err) {
|
|
158
|
+
if (!last) {
|
|
159
|
+
await delay(retryDelayMs);
|
|
160
|
+
continue;
|
|
161
|
+
}
|
|
162
|
+
warn(`${PREFIX} could not reach Squally to cancel run ${ciRunId}: ${describeError(err, timeoutMs)}. The run is not marked cancelled.`);
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
let text = "";
|
|
166
|
+
try {
|
|
167
|
+
text = (await response.text()).trim();
|
|
168
|
+
}
|
|
169
|
+
catch {
|
|
170
|
+
// Best-effort, like the reporter's error bodies.
|
|
171
|
+
}
|
|
172
|
+
if (response.status >= 500 && !last) {
|
|
173
|
+
await delay(retryDelayMs);
|
|
174
|
+
continue;
|
|
175
|
+
}
|
|
176
|
+
if (!response.ok) {
|
|
177
|
+
const detail = `${response.status} ${response.statusText}${text ? ` - ${(0, text_1.truncate)(text, BODY_LOG_LIMIT)}` : ""}`;
|
|
178
|
+
const hint = response.status === 401
|
|
179
|
+
? " Check SQUALLY_INGEST_KEY: it must be the project's ingest key."
|
|
180
|
+
: response.status === 404
|
|
181
|
+
? " This Squally may not support cancelling from CI yet."
|
|
182
|
+
: "";
|
|
183
|
+
warn(`${PREFIX} Squally did not cancel run ${ciRunId}: ${detail}.${hint}`);
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
186
|
+
let answer = null;
|
|
187
|
+
try {
|
|
188
|
+
answer = parseAnswer(JSON.parse(text));
|
|
189
|
+
}
|
|
190
|
+
catch {
|
|
191
|
+
// Falls through to the warning below.
|
|
192
|
+
}
|
|
193
|
+
if (answer === null) {
|
|
194
|
+
warn(`${PREFIX} unexpected answer from Squally for run ${ciRunId}: ${(0, text_1.truncate)(text || "(empty)", BODY_LOG_LIMIT)}`);
|
|
195
|
+
return;
|
|
196
|
+
}
|
|
197
|
+
log(describeCancelAnswer(answer, ciRunId));
|
|
198
|
+
return;
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
catch (err) {
|
|
202
|
+
warn(`${PREFIX} cancel failed: ${describeError(err, timeoutMs)}`);
|
|
203
|
+
}
|
|
204
|
+
finally {
|
|
205
|
+
await dispatcher.close().catch(() => undefined);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
/** The process entry. Returns the exit code: 0 for every cancel, 2 for a usage error. */
|
|
209
|
+
async function main(argv, env = process.env) {
|
|
210
|
+
const parsed = parseArgs(argv);
|
|
211
|
+
if (parsed.kind === "help") {
|
|
212
|
+
console.log(exports.USAGE);
|
|
213
|
+
return 0;
|
|
214
|
+
}
|
|
215
|
+
if (parsed.kind === "usage_error") {
|
|
216
|
+
console.error(`${PREFIX} ${parsed.message}\n\n${exports.USAGE}`);
|
|
217
|
+
return 2;
|
|
218
|
+
}
|
|
219
|
+
// Bound now: runCancel routes console.warn through `warn` for a moment, and
|
|
220
|
+
// a `warn` that looked console.warn up at call time would call itself.
|
|
221
|
+
const warnLine = console.warn.bind(console);
|
|
222
|
+
try {
|
|
223
|
+
await runCancel(parsed.jobKey, { env, log: (l) => console.log(l), warn: warnLine });
|
|
224
|
+
}
|
|
225
|
+
catch (err) {
|
|
226
|
+
// runCancel does not throw; this is the last net under that promise.
|
|
227
|
+
console.warn(`${PREFIX} cancel failed: ${String(err)}`);
|
|
228
|
+
}
|
|
229
|
+
return 0;
|
|
230
|
+
}
|
|
231
|
+
if (require.main === module) {
|
|
232
|
+
// exitCode, not process.exit(): let the event loop drain on its own, as the
|
|
233
|
+
// reporter does - and an unexpected rejection still ends in 0.
|
|
234
|
+
main(process.argv.slice(2)).then((code) => {
|
|
235
|
+
process.exitCode = code;
|
|
236
|
+
}, () => {
|
|
237
|
+
process.exitCode = 0;
|
|
238
|
+
});
|
|
239
|
+
}
|
|
240
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http-config.d.ts","sourceRoot":"","sources":["../src/http-config.ts"],"names":[],"mappings":"AAcA,eAAO,MAAM,gBAAgB,QAA8D,CAAC;AAC5F,eAAO,MAAM,UAAU,QAAyC,CAAC;AAYjE,eAAO,MAAM,sBAAsB,QAAS,CAAC;AAI7C,eAAO,MAAM,2BAA2B,OAAQ,CAAC"}
|