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 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**, run Playwright as usual:
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
- - name: Run Playwright tests
236
- run: npx playwright test
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
- A cancelled workflow currently shows as incomplete in Squally.
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":"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"}
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
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ export declare const REPORTER_VERSION: string;
2
+ export declare const USER_AGENT: string;
3
+ export declare const API_REQUEST_TIMEOUT_MS = 30000;
4
+ export declare const SERVER_ERROR_RETRY_DELAY_MS = 1000;
5
+ //# sourceMappingURL=http-config.d.ts.map
@@ -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"}