@runcofactor/cli 0.10.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 +125 -0
- package/dist/api-catalog-GFGCLVS4.js +401 -0
- package/dist/api-catalog-GFGCLVS4.js.map +1 -0
- package/dist/attachment-SJC7D7FY.js +276 -0
- package/dist/attachment-SJC7D7FY.js.map +1 -0
- package/dist/auth-EN6NQCJY.js +31 -0
- package/dist/auth-EN6NQCJY.js.map +1 -0
- package/dist/bin.js +7 -0
- package/dist/bin.js.map +1 -0
- package/dist/chunk-3CZU7XCS.js +272 -0
- package/dist/chunk-3CZU7XCS.js.map +1 -0
- package/dist/chunk-4NRDONSC.js +1048 -0
- package/dist/chunk-4NRDONSC.js.map +1 -0
- package/dist/chunk-4PNOV7OV.js +51980 -0
- package/dist/chunk-4PNOV7OV.js.map +1 -0
- package/dist/chunk-52IO7ACJ.js +2941 -0
- package/dist/chunk-52IO7ACJ.js.map +1 -0
- package/dist/chunk-6LEZCKKV.js +663 -0
- package/dist/chunk-6LEZCKKV.js.map +1 -0
- package/dist/chunk-A4OFTUVV.js +170 -0
- package/dist/chunk-A4OFTUVV.js.map +1 -0
- package/dist/chunk-B2VISN2V.js +2459 -0
- package/dist/chunk-B2VISN2V.js.map +1 -0
- package/dist/chunk-CLAWT7BJ.js +271 -0
- package/dist/chunk-CLAWT7BJ.js.map +1 -0
- package/dist/chunk-GKY2KXO5.js +281 -0
- package/dist/chunk-GKY2KXO5.js.map +1 -0
- package/dist/chunk-I4QLI3JO.js +413 -0
- package/dist/chunk-I4QLI3JO.js.map +1 -0
- package/dist/chunk-IMPZAX6L.js +180 -0
- package/dist/chunk-IMPZAX6L.js.map +1 -0
- package/dist/chunk-J6SH7GQT.js +241 -0
- package/dist/chunk-J6SH7GQT.js.map +1 -0
- package/dist/chunk-JDBCZ3Z2.js +298 -0
- package/dist/chunk-JDBCZ3Z2.js.map +1 -0
- package/dist/chunk-JICSYFRJ.js +46 -0
- package/dist/chunk-JICSYFRJ.js.map +1 -0
- package/dist/chunk-JWHYXEA2.js +32 -0
- package/dist/chunk-JWHYXEA2.js.map +1 -0
- package/dist/chunk-N7HFALX3.js +88 -0
- package/dist/chunk-N7HFALX3.js.map +1 -0
- package/dist/chunk-Q4BO4Z5V.js +178 -0
- package/dist/chunk-Q4BO4Z5V.js.map +1 -0
- package/dist/chunk-QFDOWABX.js +195 -0
- package/dist/chunk-QFDOWABX.js.map +1 -0
- package/dist/chunk-SJJW77WN.js +605 -0
- package/dist/chunk-SJJW77WN.js.map +1 -0
- package/dist/chunk-VKVL7WBN.js +50 -0
- package/dist/chunk-VKVL7WBN.js.map +1 -0
- package/dist/chunk-WOHL4FTB.js +353 -0
- package/dist/chunk-WOHL4FTB.js.map +1 -0
- package/dist/chunk-XQXVG7RA.js +426 -0
- package/dist/chunk-XQXVG7RA.js.map +1 -0
- package/dist/chunk-ZD3KHESI.js +94 -0
- package/dist/chunk-ZD3KHESI.js.map +1 -0
- package/dist/credential-COLTBV6D.js +450 -0
- package/dist/credential-COLTBV6D.js.map +1 -0
- package/dist/credential-template-EEPYFG7R.js +291 -0
- package/dist/credential-template-EEPYFG7R.js.map +1 -0
- package/dist/debug-workflow-KOVH5GOP.js +259 -0
- package/dist/debug-workflow-KOVH5GOP.js.map +1 -0
- package/dist/dist-44PZR7BQ.js +423 -0
- package/dist/dist-44PZR7BQ.js.map +1 -0
- package/dist/docs-3SSORHB5.js +366 -0
- package/dist/docs-3SSORHB5.js.map +1 -0
- package/dist/doctor-OTSIWV6G.js +132 -0
- package/dist/doctor-OTSIWV6G.js.map +1 -0
- package/dist/feature-flag-T2LRZME3.js +283 -0
- package/dist/feature-flag-T2LRZME3.js.map +1 -0
- package/dist/file-type-S3UUBVCT.js +4205 -0
- package/dist/file-type-S3UUBVCT.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +982 -0
- package/dist/index.js.map +1 -0
- package/dist/init-TGWRECT2.js +208 -0
- package/dist/init-TGWRECT2.js.map +1 -0
- package/dist/install-DXSNWZKO.js +295 -0
- package/dist/install-DXSNWZKO.js.map +1 -0
- package/dist/issues-XIZOPX6T.js +564 -0
- package/dist/issues-XIZOPX6T.js.map +1 -0
- package/dist/knobs-NBINZIUB.js +295 -0
- package/dist/knobs-NBINZIUB.js.map +1 -0
- package/dist/list-3TDHK637.js +59 -0
- package/dist/list-3TDHK637.js.map +1 -0
- package/dist/local-HICVD6PU.js +100 -0
- package/dist/local-HICVD6PU.js.map +1 -0
- package/dist/login-UOIUXVUK.js +315 -0
- package/dist/login-UOIUXVUK.js.map +1 -0
- package/dist/mcp-54IJEOUA.js +1956 -0
- package/dist/mcp-54IJEOUA.js.map +1 -0
- package/dist/pdf-extract-ABWV3L5X.js +13 -0
- package/dist/pdf-extract-ABWV3L5X.js.map +1 -0
- package/dist/pdfjs-DQ2YA5S3.js +41561 -0
- package/dist/pdfjs-DQ2YA5S3.js.map +1 -0
- package/dist/property-UXLOLPTD.js +701 -0
- package/dist/property-UXLOLPTD.js.map +1 -0
- package/dist/property-skill-guide.md +189 -0
- package/dist/psql-BYUUNLGG.js +115 -0
- package/dist/psql-BYUUNLGG.js.map +1 -0
- package/dist/record-4TR2UIIS.js +233 -0
- package/dist/record-4TR2UIIS.js.map +1 -0
- package/dist/redis-35VBUYW7.js +116 -0
- package/dist/redis-35VBUYW7.js.map +1 -0
- package/dist/release-OOLTUBUT.js +354 -0
- package/dist/release-OOLTUBUT.js.map +1 -0
- package/dist/sandbox-XGSUU6G7.js +2046 -0
- package/dist/sandbox-XGSUU6G7.js.map +1 -0
- package/dist/scenarios-GWLJEGHA.js +280 -0
- package/dist/scenarios-GWLJEGHA.js.map +1 -0
- package/dist/session-MYFNZPRP.js +2414 -0
- package/dist/session-MYFNZPRP.js.map +1 -0
- package/dist/skill-KM34LDMO.js +1839 -0
- package/dist/skill-KM34LDMO.js.map +1 -0
- package/dist/skills/debug-run/SKILL.md +262 -0
- package/dist/skills/debug-run/history/1.0.0.md +244 -0
- package/dist/skills/debug-run/history/1.0.1.md +245 -0
- package/dist/skills/debug-run/history/1.0.2.md +254 -0
- package/dist/skills/debug-run/history/1.1.0.md +262 -0
- package/dist/skills/debug-run/version.json +3 -0
- package/dist/spec-RA3CFEKG.js +951 -0
- package/dist/spec-RA3CFEKG.js.map +1 -0
- package/dist/src-LB4HBTJQ.js +1516 -0
- package/dist/src-LB4HBTJQ.js.map +1 -0
- package/dist/src-N3TPKGTY.js +244 -0
- package/dist/src-N3TPKGTY.js.map +1 -0
- package/dist/src-UVDX5UP6.js +17 -0
- package/dist/src-UVDX5UP6.js.map +1 -0
- package/dist/start-PSEQSQA3.js +151 -0
- package/dist/start-PSEQSQA3.js.map +1 -0
- package/dist/tag-YY6YAABQ.js +22 -0
- package/dist/tag-YY6YAABQ.js.map +1 -0
- package/dist/task-IQC3YR5K.js +922 -0
- package/dist/task-IQC3YR5K.js.map +1 -0
- package/dist/test-suite-DZNJFXDW.js +394 -0
- package/dist/test-suite-DZNJFXDW.js.map +1 -0
- package/dist/trace-HXIW7U2D.js +14 -0
- package/dist/trace-HXIW7U2D.js.map +1 -0
- package/dist/triage-ORG45R5W.js +16 -0
- package/dist/triage-ORG45R5W.js.map +1 -0
- package/dist/upgrade-L2VYMP2V.js +61 -0
- package/dist/upgrade-L2VYMP2V.js.map +1 -0
- package/dist/workflow-XYFH5LTP.js +3708 -0
- package/dist/workflow-XYFH5LTP.js.map +1 -0
- package/dist/workflow-cache-NQJQFWMV.js +253 -0
- package/dist/workflow-cache-NQJQFWMV.js.map +1 -0
- package/dist/workflow-debug-BGD4UIXU.js +927 -0
- package/dist/workflow-debug-BGD4UIXU.js.map +1 -0
- package/dist/workflow-proposals-MTUDX46O.js +382 -0
- package/dist/workflow-proposals-MTUDX46O.js.map +1 -0
- package/package.json +61 -0
|
@@ -0,0 +1,354 @@
|
|
|
1
|
+
import { createRequire as __cr } from "module"; const require = __cr(import.meta.url);
|
|
2
|
+
import {
|
|
3
|
+
getApplicationIdArg
|
|
4
|
+
} from "./chunk-WOHL4FTB.js";
|
|
5
|
+
import "./chunk-SJJW77WN.js";
|
|
6
|
+
import "./chunk-3CZU7XCS.js";
|
|
7
|
+
import {
|
|
8
|
+
getArgValue,
|
|
9
|
+
hasFlag,
|
|
10
|
+
resolveConfig
|
|
11
|
+
} from "./chunk-A4OFTUVV.js";
|
|
12
|
+
import "./chunk-JWHYXEA2.js";
|
|
13
|
+
import "./chunk-VKVL7WBN.js";
|
|
14
|
+
|
|
15
|
+
// src/release.ts
|
|
16
|
+
import process from "process";
|
|
17
|
+
var TERMINAL_STATUSES = /* @__PURE__ */ new Set([
|
|
18
|
+
"completed",
|
|
19
|
+
"completed_with_errors",
|
|
20
|
+
"failed",
|
|
21
|
+
"canceled",
|
|
22
|
+
"timeout"
|
|
23
|
+
]);
|
|
24
|
+
async function handleTrigger(argv, apiUrl, token) {
|
|
25
|
+
const propertyId = getApplicationIdArg(argv);
|
|
26
|
+
if (!propertyId) {
|
|
27
|
+
console.error("Error: Missing --application-id <uuid> (alias: --property-id).");
|
|
28
|
+
console.error(
|
|
29
|
+
"Usage: canary release trigger --application-id <uuid> [--credential-ids <uuid,...>] [--skip-regressions]"
|
|
30
|
+
);
|
|
31
|
+
process.exit(1);
|
|
32
|
+
}
|
|
33
|
+
const skipRegressions = hasFlag(argv, "--skip-regressions");
|
|
34
|
+
const credentialIdsRaw = getArgValue(argv, "--credential-ids");
|
|
35
|
+
const body = { propertyId, runRegressions: !skipRegressions };
|
|
36
|
+
if (credentialIdsRaw) {
|
|
37
|
+
body.credentialIds = credentialIdsRaw.split(",").map((id) => id.trim());
|
|
38
|
+
}
|
|
39
|
+
if (skipRegressions) {
|
|
40
|
+
console.warn(
|
|
41
|
+
"WARNING: --skip-regressions is set. The regression suite will NOT run if there are no new commits. Gate is degraded."
|
|
42
|
+
);
|
|
43
|
+
}
|
|
44
|
+
const res = await fetch(`${apiUrl}/api/v1/release-qa/trigger`, {
|
|
45
|
+
method: "POST",
|
|
46
|
+
headers: {
|
|
47
|
+
Authorization: `Bearer ${token}`,
|
|
48
|
+
"Content-Type": "application/json"
|
|
49
|
+
},
|
|
50
|
+
body: JSON.stringify(body)
|
|
51
|
+
});
|
|
52
|
+
if (res.status === 401) {
|
|
53
|
+
console.error("Error: Unauthorized. Check your API token.");
|
|
54
|
+
process.exit(1);
|
|
55
|
+
}
|
|
56
|
+
const json = await res.json();
|
|
57
|
+
if (!json.ok) {
|
|
58
|
+
console.error(`Error: ${json.error}`);
|
|
59
|
+
process.exit(1);
|
|
60
|
+
}
|
|
61
|
+
console.log(`Release QA run triggered`);
|
|
62
|
+
console.log(` Run ID: ${json.releaseRunId}`);
|
|
63
|
+
console.log(` Job ID: ${json.jobId}`);
|
|
64
|
+
}
|
|
65
|
+
async function fetchRunStatus(apiUrl, token, runId) {
|
|
66
|
+
const res = await fetch(`${apiUrl}/api/v1/release-qa/runs/${encodeURIComponent(runId)}`, {
|
|
67
|
+
headers: { Authorization: `Bearer ${token}` }
|
|
68
|
+
});
|
|
69
|
+
if (res.status === 401) {
|
|
70
|
+
console.error("Error: Unauthorized. Check your API token.");
|
|
71
|
+
process.exit(1);
|
|
72
|
+
}
|
|
73
|
+
return await res.json();
|
|
74
|
+
}
|
|
75
|
+
async function handleStatus(argv, apiUrl, token) {
|
|
76
|
+
const runId = argv[0];
|
|
77
|
+
if (!runId || runId.startsWith("--")) {
|
|
78
|
+
console.error("Error: Missing run ID.");
|
|
79
|
+
console.error("Usage: canary release status <run-id>");
|
|
80
|
+
process.exit(1);
|
|
81
|
+
}
|
|
82
|
+
const jsonOutput = hasFlag(argv, "--json");
|
|
83
|
+
const json = await fetchRunStatus(apiUrl, token, runId);
|
|
84
|
+
if (!json.ok) {
|
|
85
|
+
console.error(`Error: ${json.error}`);
|
|
86
|
+
process.exit(1);
|
|
87
|
+
}
|
|
88
|
+
const run = json.run;
|
|
89
|
+
if (jsonOutput) {
|
|
90
|
+
console.log(JSON.stringify(run, null, 2));
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
console.log(`Release QA Run: ${run.id}`);
|
|
94
|
+
console.log(` Status: ${run.status}`);
|
|
95
|
+
console.log(` Trigger: ${run.triggerSource}`);
|
|
96
|
+
if (run.repos && run.repos.length > 0) {
|
|
97
|
+
console.log(` Repositories:`);
|
|
98
|
+
for (const r of run.repos) {
|
|
99
|
+
const range = r.fromSha === r.toSha ? "(no changes)" : `${r.fromSha.slice(0, 7)}..${r.toSha.slice(0, 7)}`;
|
|
100
|
+
console.log(` - ${r.repoFullName} ${range}`);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
console.log(` Commits analyzed: ${run.commitsAnalyzed}`);
|
|
104
|
+
console.log(` Testers: ${run.testersCompleted}/${run.testersSpawned} completed, ${run.testersFailed} failed`);
|
|
105
|
+
console.log(` Issues found: ${run.issuesFound}`);
|
|
106
|
+
console.log(` Regression tests: ${run.regressionTestsPassed}/${run.regressionTestsTotal} passed, ${run.regressionTestsFailed} failed`);
|
|
107
|
+
if (run.startedAt) console.log(` Started: ${run.startedAt}`);
|
|
108
|
+
if (run.finishedAt) console.log(` Finished: ${run.finishedAt}`);
|
|
109
|
+
}
|
|
110
|
+
function sleep(ms) {
|
|
111
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
112
|
+
}
|
|
113
|
+
async function handleRun(argv, apiUrl, token) {
|
|
114
|
+
const propertyId = getApplicationIdArg(argv);
|
|
115
|
+
if (!propertyId) {
|
|
116
|
+
console.error("Error: Missing --application-id <uuid> (alias: --property-id).");
|
|
117
|
+
console.error(
|
|
118
|
+
"Usage: canary release run --application-id <uuid> [--timeout 3600] [--poll-interval 30] [--skip-regressions]"
|
|
119
|
+
);
|
|
120
|
+
process.exit(1);
|
|
121
|
+
}
|
|
122
|
+
const timeoutSec = parseInt(getArgValue(argv, "--timeout") ?? "3600", 10);
|
|
123
|
+
const pollIntervalSec = parseInt(getArgValue(argv, "--poll-interval") ?? "30", 10);
|
|
124
|
+
const skipRegressions = hasFlag(argv, "--skip-regressions");
|
|
125
|
+
const credentialIdsRaw = getArgValue(argv, "--credential-ids");
|
|
126
|
+
const body = { propertyId, runRegressions: !skipRegressions };
|
|
127
|
+
if (credentialIdsRaw) {
|
|
128
|
+
body.credentialIds = credentialIdsRaw.split(",").map((id) => id.trim());
|
|
129
|
+
}
|
|
130
|
+
if (skipRegressions) {
|
|
131
|
+
console.warn(
|
|
132
|
+
"WARNING: --skip-regressions is set. The regression suite will NOT run if there are no new commits. Deploy gate is degraded."
|
|
133
|
+
);
|
|
134
|
+
}
|
|
135
|
+
console.log("Triggering Release QA run...");
|
|
136
|
+
const triggerRes = await fetch(`${apiUrl}/api/v1/release-qa/trigger`, {
|
|
137
|
+
method: "POST",
|
|
138
|
+
headers: {
|
|
139
|
+
Authorization: `Bearer ${token}`,
|
|
140
|
+
"Content-Type": "application/json"
|
|
141
|
+
},
|
|
142
|
+
body: JSON.stringify(body)
|
|
143
|
+
});
|
|
144
|
+
if (triggerRes.status === 401) {
|
|
145
|
+
console.error("Error: Unauthorized. Check your API token.");
|
|
146
|
+
process.exit(1);
|
|
147
|
+
}
|
|
148
|
+
const triggerJson = await triggerRes.json();
|
|
149
|
+
if (!triggerJson.ok) {
|
|
150
|
+
console.error(`Error triggering run: ${triggerJson.error}`);
|
|
151
|
+
process.exit(1);
|
|
152
|
+
}
|
|
153
|
+
const runId = triggerJson.releaseRunId;
|
|
154
|
+
console.log(`Run started: ${runId}`);
|
|
155
|
+
const deadline = Date.now() + timeoutSec * 1e3;
|
|
156
|
+
let lastStatus = "";
|
|
157
|
+
while (Date.now() < deadline) {
|
|
158
|
+
await sleep(pollIntervalSec * 1e3);
|
|
159
|
+
let statusJson;
|
|
160
|
+
try {
|
|
161
|
+
statusJson = await fetchRunStatus(apiUrl, token, runId);
|
|
162
|
+
} catch (err) {
|
|
163
|
+
console.error(`Warning: Failed to fetch status, retrying... (${err})`);
|
|
164
|
+
continue;
|
|
165
|
+
}
|
|
166
|
+
if (!statusJson.ok) {
|
|
167
|
+
console.error(`Error: ${statusJson.error}`);
|
|
168
|
+
process.exit(1);
|
|
169
|
+
}
|
|
170
|
+
const run = statusJson.run;
|
|
171
|
+
const statusLine = `[${run.status}] testers: ${run.testersCompleted}/${run.testersSpawned}, regressions: ${run.regressionTestsPassed}/${run.regressionTestsTotal} passed`;
|
|
172
|
+
if (run.status !== lastStatus) {
|
|
173
|
+
console.log(statusLine);
|
|
174
|
+
lastStatus = run.status;
|
|
175
|
+
} else {
|
|
176
|
+
console.log(statusLine);
|
|
177
|
+
}
|
|
178
|
+
if (TERMINAL_STATUSES.has(run.status)) {
|
|
179
|
+
console.log("");
|
|
180
|
+
console.log(`Run finished: ${run.status}`);
|
|
181
|
+
console.log(` Testers: ${run.testersCompleted}/${run.testersSpawned} completed, ${run.testersFailed} failed`);
|
|
182
|
+
console.log(` Regressions: ${run.regressionTestsPassed}/${run.regressionTestsTotal} passed, ${run.regressionTestsFailed} failed`);
|
|
183
|
+
console.log(` Issues found: ${run.issuesFound}`);
|
|
184
|
+
if (run.status === "failed" || run.status === "canceled" || run.status === "timeout") {
|
|
185
|
+
console.error(`
|
|
186
|
+
Release QA FAILED (${run.status})`);
|
|
187
|
+
process.exit(1);
|
|
188
|
+
}
|
|
189
|
+
if (run.status === "completed_with_errors") {
|
|
190
|
+
const suffix = run.cutoffReason ? `: ${run.cutoffReason}` : "";
|
|
191
|
+
console.error(`
|
|
192
|
+
Release QA FAILED (completed_with_errors${suffix})`);
|
|
193
|
+
process.exit(1);
|
|
194
|
+
}
|
|
195
|
+
if (run.regressionTestsTotal === 0 && !skipRegressions) {
|
|
196
|
+
console.error(
|
|
197
|
+
"\nRelease QA FAILED (no regression tests executed \u2014 expected suite to run). If this was intentional, re-run with --skip-regressions."
|
|
198
|
+
);
|
|
199
|
+
process.exit(1);
|
|
200
|
+
}
|
|
201
|
+
if (run.regressionTestsFailed === 0) {
|
|
202
|
+
console.log(
|
|
203
|
+
`
|
|
204
|
+
Release QA PASSED (${run.regressionTestsPassed}/${run.regressionTestsTotal} regressions passed)`
|
|
205
|
+
);
|
|
206
|
+
process.exit(0);
|
|
207
|
+
}
|
|
208
|
+
console.error(`
|
|
209
|
+
Release QA FAILED (${run.regressionTestsFailed} regression test(s) failed)`);
|
|
210
|
+
process.exit(1);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
console.error(`
|
|
214
|
+
Timeout: Release QA did not complete within ${timeoutSec}s`);
|
|
215
|
+
process.exit(1);
|
|
216
|
+
}
|
|
217
|
+
async function handleMarkDeploy(argv, apiUrl, token) {
|
|
218
|
+
const commitSha = getArgValue(argv, "--commit");
|
|
219
|
+
const propertyId = getApplicationIdArg(argv);
|
|
220
|
+
const commitMessage = getArgValue(argv, "--message");
|
|
221
|
+
if (!commitSha) {
|
|
222
|
+
console.error("Error: Missing --commit <sha>.");
|
|
223
|
+
console.error('Usage: canary release mark-deploy --commit <sha> --application-id <uuid> [--message "..."]');
|
|
224
|
+
process.exit(1);
|
|
225
|
+
}
|
|
226
|
+
if (!propertyId) {
|
|
227
|
+
console.error("Error: Missing --application-id <uuid> (alias: --property-id).");
|
|
228
|
+
console.error('Usage: canary release mark-deploy --commit <sha> --application-id <uuid> [--message "..."]');
|
|
229
|
+
process.exit(1);
|
|
230
|
+
}
|
|
231
|
+
const body = { propertyId, commitSha };
|
|
232
|
+
if (commitMessage) body.commitMessage = commitMessage;
|
|
233
|
+
const res = await fetch(`${apiUrl}/api/v1/deployments/mark`, {
|
|
234
|
+
method: "POST",
|
|
235
|
+
headers: {
|
|
236
|
+
Authorization: `Bearer ${token}`,
|
|
237
|
+
"Content-Type": "application/json"
|
|
238
|
+
},
|
|
239
|
+
body: JSON.stringify(body)
|
|
240
|
+
});
|
|
241
|
+
if (res.status === 401) {
|
|
242
|
+
console.error("Error: Unauthorized. Check your API token.");
|
|
243
|
+
process.exit(1);
|
|
244
|
+
}
|
|
245
|
+
const json = await res.json();
|
|
246
|
+
if (!json.ok) {
|
|
247
|
+
console.error(`Error: ${json.error}`);
|
|
248
|
+
process.exit(1);
|
|
249
|
+
}
|
|
250
|
+
console.log("Deployment marked");
|
|
251
|
+
console.log(` Deployment ID: ${json.deploymentId}`);
|
|
252
|
+
console.log(` Commit: ${json.commitSha}`);
|
|
253
|
+
console.log(` Tasks triggered: ${json.tasksTriggered}`);
|
|
254
|
+
}
|
|
255
|
+
async function handleLatestDeploy(argv, apiUrl, token) {
|
|
256
|
+
const propertyId = getApplicationIdArg(argv);
|
|
257
|
+
if (!propertyId) {
|
|
258
|
+
console.error("Error: Missing --application-id <uuid> (alias: --property-id).");
|
|
259
|
+
console.error("Usage: canary release latest-deploy --application-id <uuid> [--json]");
|
|
260
|
+
process.exit(1);
|
|
261
|
+
}
|
|
262
|
+
const jsonOutput = hasFlag(argv, "--json");
|
|
263
|
+
const res = await fetch(
|
|
264
|
+
`${apiUrl}/api/v1/deployments/latest?propertyId=${encodeURIComponent(propertyId)}`,
|
|
265
|
+
{ headers: { Authorization: `Bearer ${token}` } }
|
|
266
|
+
);
|
|
267
|
+
if (res.status === 401) {
|
|
268
|
+
console.error("Error: Unauthorized. Check your API token.");
|
|
269
|
+
process.exit(1);
|
|
270
|
+
}
|
|
271
|
+
const data = await res.json();
|
|
272
|
+
if (!data.ok) {
|
|
273
|
+
console.error(`Error: ${data.error}`);
|
|
274
|
+
process.exit(1);
|
|
275
|
+
}
|
|
276
|
+
if (!data.deployment) {
|
|
277
|
+
console.log("No deployments found for this application.");
|
|
278
|
+
return;
|
|
279
|
+
}
|
|
280
|
+
if (jsonOutput) {
|
|
281
|
+
console.log(JSON.stringify(data.deployment, null, 2));
|
|
282
|
+
return;
|
|
283
|
+
}
|
|
284
|
+
console.log(`Latest deployment:`);
|
|
285
|
+
console.log(` ID: ${data.deployment.id}`);
|
|
286
|
+
console.log(` Commit: ${data.deployment.commitSha}`);
|
|
287
|
+
if (data.deployment.commitMessage) {
|
|
288
|
+
console.log(` Message: ${data.deployment.commitMessage}`);
|
|
289
|
+
}
|
|
290
|
+
console.log(` Deployed by: ${data.deployment.deployedBy}`);
|
|
291
|
+
console.log(` Source: ${data.deployment.triggerSource}`);
|
|
292
|
+
console.log(` Tasks triggered: ${data.deployment.tasksTriggered}`);
|
|
293
|
+
console.log(` Created: ${data.deployment.createdAt}`);
|
|
294
|
+
}
|
|
295
|
+
function printReleaseHelp() {
|
|
296
|
+
console.log(
|
|
297
|
+
[
|
|
298
|
+
"Usage: canary release <sub-command> [options]",
|
|
299
|
+
"",
|
|
300
|
+
"Sub-commands:",
|
|
301
|
+
" trigger --application-id <uuid> [--credential-ids <uuid,...>]",
|
|
302
|
+
" Trigger a Release QA run",
|
|
303
|
+
" status <run-id> [--json] Check run status",
|
|
304
|
+
" run --application-id <uuid> [options] Trigger and poll until complete",
|
|
305
|
+
' mark-deploy --commit <sha> --application-id <uuid> [--message "..."]',
|
|
306
|
+
" Mark a commit as deployed",
|
|
307
|
+
" latest-deploy --application-id <uuid> [--json]",
|
|
308
|
+
" Show latest deployment for an application",
|
|
309
|
+
"",
|
|
310
|
+
"Run options:",
|
|
311
|
+
" --timeout <seconds> Max wait time (default: 3600)",
|
|
312
|
+
" --poll-interval <secs> Poll frequency (default: 30)",
|
|
313
|
+
" --credential-ids <ids> Comma-separated credential UUIDs",
|
|
314
|
+
"",
|
|
315
|
+
"Options:",
|
|
316
|
+
" --env <env> Target environment (prod, dev, local)",
|
|
317
|
+
" --api-url <url> API URL override",
|
|
318
|
+
" --token <key> API token override (or set CANARY_API_TOKEN)"
|
|
319
|
+
].join("\n")
|
|
320
|
+
);
|
|
321
|
+
}
|
|
322
|
+
async function runRelease(argv) {
|
|
323
|
+
const [subCommand, ...rest] = argv;
|
|
324
|
+
if (!subCommand || subCommand === "help" || hasFlag(argv, "--help", "-h")) {
|
|
325
|
+
printReleaseHelp();
|
|
326
|
+
return;
|
|
327
|
+
}
|
|
328
|
+
const { apiUrl, token } = await resolveConfig(argv);
|
|
329
|
+
switch (subCommand) {
|
|
330
|
+
case "trigger":
|
|
331
|
+
await handleTrigger(rest, apiUrl, token);
|
|
332
|
+
break;
|
|
333
|
+
case "status":
|
|
334
|
+
await handleStatus(rest, apiUrl, token);
|
|
335
|
+
break;
|
|
336
|
+
case "run":
|
|
337
|
+
await handleRun(rest, apiUrl, token);
|
|
338
|
+
break;
|
|
339
|
+
case "mark-deploy":
|
|
340
|
+
await handleMarkDeploy(rest, apiUrl, token);
|
|
341
|
+
break;
|
|
342
|
+
case "latest-deploy":
|
|
343
|
+
await handleLatestDeploy(rest, apiUrl, token);
|
|
344
|
+
break;
|
|
345
|
+
default:
|
|
346
|
+
console.error(`Unknown sub-command: ${subCommand}`);
|
|
347
|
+
printReleaseHelp();
|
|
348
|
+
process.exit(1);
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
export {
|
|
352
|
+
runRelease
|
|
353
|
+
};
|
|
354
|
+
//# sourceMappingURL=release-OOLTUBUT.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/release.ts"],"sourcesContent":["/**\n * CLI Release QA Management\n *\n * Trigger, poll, and check status of Release QA runs from CI/CD pipelines.\n * Used by the scheduled-release GitHub Actions workflow to gate deployments.\n */\n\nimport process from \"node:process\";\nimport { resolveConfig, getArgValue, hasFlag } from \"./auth.js\";\nimport { getApplicationIdArg } from \"./cli-helpers.js\";\n\ntype TriggerResponse = {\n ok: boolean;\n releaseRunId?: string;\n jobId?: string;\n error?: string;\n};\n\ntype RunStatusResponse = {\n ok: boolean;\n run?: {\n id: string;\n status: string;\n triggerSource: string;\n cutoffReason: string | null;\n fromSha: string | null;\n toSha: string | null;\n commitsAnalyzed: number;\n testersSpawned: number;\n testersCompleted: number;\n testersFailed: number;\n issuesFound: number;\n regressionTestsTotal: number;\n regressionTestsPassed: number;\n regressionTestsFailed: number;\n startedAt: string | null;\n finishedAt: string | null;\n createdAt: string;\n // Multi-repo: one entry per participating repo. Empty array for\n // single-repo/legacy runs; consumers fall back to top-level fromSha/toSha.\n repos?: Array<{\n repoFullName: string;\n fromSha: string;\n toSha: string;\n }>;\n };\n error?: string;\n};\n\n/** Terminal statuses that stop polling */\nconst TERMINAL_STATUSES = new Set([\n \"completed\",\n \"completed_with_errors\",\n \"failed\",\n \"canceled\",\n \"timeout\",\n]);\n\nasync function handleTrigger(argv: string[], apiUrl: string, token: string): Promise<void> {\n const propertyId = getApplicationIdArg(argv);\n if (!propertyId) {\n console.error(\"Error: Missing --application-id <uuid> (alias: --property-id).\");\n console.error(\n \"Usage: canary release trigger --application-id <uuid> [--credential-ids <uuid,...>] [--skip-regressions]\"\n );\n process.exit(1);\n }\n\n const skipRegressions = hasFlag(argv, \"--skip-regressions\");\n const credentialIdsRaw = getArgValue(argv, \"--credential-ids\");\n const body: Record<string, unknown> = { propertyId, runRegressions: !skipRegressions };\n if (credentialIdsRaw) {\n body.credentialIds = credentialIdsRaw.split(\",\").map((id) => id.trim());\n }\n\n if (skipRegressions) {\n console.warn(\n \"WARNING: --skip-regressions is set. The regression suite will NOT run if there are no new commits. Gate is degraded.\"\n );\n }\n\n const res = await fetch(`${apiUrl}/api/v1/release-qa/trigger`, {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${token}`,\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify(body),\n });\n\n if (res.status === 401) {\n console.error(\"Error: Unauthorized. Check your API token.\");\n process.exit(1);\n }\n\n const json = (await res.json()) as TriggerResponse;\n\n if (!json.ok) {\n console.error(`Error: ${json.error}`);\n process.exit(1);\n }\n\n console.log(`Release QA run triggered`);\n console.log(` Run ID: ${json.releaseRunId}`);\n console.log(` Job ID: ${json.jobId}`);\n}\n\nasync function fetchRunStatus(\n apiUrl: string,\n token: string,\n runId: string\n): Promise<RunStatusResponse> {\n const res = await fetch(`${apiUrl}/api/v1/release-qa/runs/${encodeURIComponent(runId)}`, {\n headers: { Authorization: `Bearer ${token}` },\n });\n\n if (res.status === 401) {\n console.error(\"Error: Unauthorized. Check your API token.\");\n process.exit(1);\n }\n\n return (await res.json()) as RunStatusResponse;\n}\n\nasync function handleStatus(argv: string[], apiUrl: string, token: string): Promise<void> {\n const runId = argv[0];\n if (!runId || runId.startsWith(\"--\")) {\n console.error(\"Error: Missing run ID.\");\n console.error(\"Usage: canary release status <run-id>\");\n process.exit(1);\n }\n\n const jsonOutput = hasFlag(argv, \"--json\");\n const json = await fetchRunStatus(apiUrl, token, runId);\n\n if (!json.ok) {\n console.error(`Error: ${json.error}`);\n process.exit(1);\n }\n\n const run = json.run!;\n\n if (jsonOutput) {\n console.log(JSON.stringify(run, null, 2));\n return;\n }\n\n console.log(`Release QA Run: ${run.id}`);\n console.log(` Status: ${run.status}`);\n console.log(` Trigger: ${run.triggerSource}`);\n if (run.repos && run.repos.length > 0) {\n console.log(` Repositories:`);\n for (const r of run.repos) {\n const range =\n r.fromSha === r.toSha\n ? \"(no changes)\"\n : `${r.fromSha.slice(0, 7)}..${r.toSha.slice(0, 7)}`;\n console.log(` - ${r.repoFullName} ${range}`);\n }\n }\n console.log(` Commits analyzed: ${run.commitsAnalyzed}`);\n console.log(` Testers: ${run.testersCompleted}/${run.testersSpawned} completed, ${run.testersFailed} failed`);\n console.log(` Issues found: ${run.issuesFound}`);\n console.log(` Regression tests: ${run.regressionTestsPassed}/${run.regressionTestsTotal} passed, ${run.regressionTestsFailed} failed`);\n if (run.startedAt) console.log(` Started: ${run.startedAt}`);\n if (run.finishedAt) console.log(` Finished: ${run.finishedAt}`);\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nasync function handleRun(argv: string[], apiUrl: string, token: string): Promise<void> {\n const propertyId = getApplicationIdArg(argv);\n if (!propertyId) {\n console.error(\"Error: Missing --application-id <uuid> (alias: --property-id).\");\n console.error(\n \"Usage: canary release run --application-id <uuid> [--timeout 3600] [--poll-interval 30] [--skip-regressions]\"\n );\n process.exit(1);\n }\n\n const timeoutSec = parseInt(getArgValue(argv, \"--timeout\") ?? \"3600\", 10);\n const pollIntervalSec = parseInt(getArgValue(argv, \"--poll-interval\") ?? \"30\", 10);\n const skipRegressions = hasFlag(argv, \"--skip-regressions\");\n\n const credentialIdsRaw = getArgValue(argv, \"--credential-ids\");\n const body: Record<string, unknown> = { propertyId, runRegressions: !skipRegressions };\n if (credentialIdsRaw) {\n body.credentialIds = credentialIdsRaw.split(\",\").map((id) => id.trim());\n }\n\n if (skipRegressions) {\n console.warn(\n \"WARNING: --skip-regressions is set. The regression suite will NOT run if there are no new commits. Deploy gate is degraded.\"\n );\n }\n\n // Trigger\n console.log(\"Triggering Release QA run...\");\n const triggerRes = await fetch(`${apiUrl}/api/v1/release-qa/trigger`, {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${token}`,\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify(body),\n });\n\n if (triggerRes.status === 401) {\n console.error(\"Error: Unauthorized. Check your API token.\");\n process.exit(1);\n }\n\n const triggerJson = (await triggerRes.json()) as TriggerResponse;\n\n if (!triggerJson.ok) {\n console.error(`Error triggering run: ${triggerJson.error}`);\n process.exit(1);\n }\n\n const runId = triggerJson.releaseRunId!;\n console.log(`Run started: ${runId}`);\n\n // Poll\n const deadline = Date.now() + timeoutSec * 1000;\n let lastStatus = \"\";\n\n while (Date.now() < deadline) {\n await sleep(pollIntervalSec * 1000);\n\n let statusJson: RunStatusResponse;\n try {\n statusJson = await fetchRunStatus(apiUrl, token, runId);\n } catch (err) {\n console.error(`Warning: Failed to fetch status, retrying... (${err})`);\n continue;\n }\n\n if (!statusJson.ok) {\n console.error(`Error: ${statusJson.error}`);\n process.exit(1);\n }\n\n const run = statusJson.run!;\n const statusLine = `[${run.status}] testers: ${run.testersCompleted}/${run.testersSpawned}, regressions: ${run.regressionTestsPassed}/${run.regressionTestsTotal} passed`;\n\n if (run.status !== lastStatus) {\n console.log(statusLine);\n lastStatus = run.status;\n } else {\n // Print progress on same status change in metrics\n console.log(statusLine);\n }\n\n if (TERMINAL_STATUSES.has(run.status)) {\n console.log(\"\");\n console.log(`Run finished: ${run.status}`);\n console.log(` Testers: ${run.testersCompleted}/${run.testersSpawned} completed, ${run.testersFailed} failed`);\n console.log(` Regressions: ${run.regressionTestsPassed}/${run.regressionTestsTotal} passed, ${run.regressionTestsFailed} failed`);\n console.log(` Issues found: ${run.issuesFound}`);\n\n // Gate deployment on: (a) terminal status, (b) any regression failures,\n // (c) empty regression suite (unless explicitly opted out).\n // Non-regression signals (failed testers, issues, build errors) are\n // visible in the UI but intentionally do not gate the deploy.\n if (run.status === \"failed\" || run.status === \"canceled\" || run.status === \"timeout\") {\n console.error(`\\nRelease QA FAILED (${run.status})`);\n process.exit(1);\n }\n\n if (run.status === \"completed_with_errors\") {\n const suffix = run.cutoffReason ? `: ${run.cutoffReason}` : \"\";\n console.error(`\\nRelease QA FAILED (completed_with_errors${suffix})`);\n process.exit(1);\n }\n\n if (run.regressionTestsTotal === 0 && !skipRegressions) {\n console.error(\n \"\\nRelease QA FAILED (no regression tests executed — expected suite to run). \" +\n \"If this was intentional, re-run with --skip-regressions.\"\n );\n process.exit(1);\n }\n\n if (run.regressionTestsFailed === 0) {\n console.log(\n `\\nRelease QA PASSED (${run.regressionTestsPassed}/${run.regressionTestsTotal} regressions passed)`\n );\n process.exit(0);\n }\n\n console.error(`\\nRelease QA FAILED (${run.regressionTestsFailed} regression test(s) failed)`);\n process.exit(1);\n }\n }\n\n console.error(`\\nTimeout: Release QA did not complete within ${timeoutSec}s`);\n process.exit(1);\n}\n\n// ---------------------------------------------------------------------------\n// Deployment marking\n// ---------------------------------------------------------------------------\n\ntype MarkDeployResponse = {\n ok: boolean;\n deploymentId?: string;\n commitSha?: string;\n tasksTriggered?: number;\n error?: string;\n};\n\ntype LatestDeployResponse = {\n ok: boolean;\n deployment?: {\n id: string;\n commitSha: string;\n commitMessage: string | null;\n deployedBy: string;\n triggerSource: string;\n tasksTriggered: number;\n createdAt: string;\n } | null;\n error?: string;\n};\n\nasync function handleMarkDeploy(argv: string[], apiUrl: string, token: string): Promise<void> {\n const commitSha = getArgValue(argv, \"--commit\");\n const propertyId = getApplicationIdArg(argv);\n const commitMessage = getArgValue(argv, \"--message\");\n\n if (!commitSha) {\n console.error(\"Error: Missing --commit <sha>.\");\n console.error(\"Usage: canary release mark-deploy --commit <sha> --application-id <uuid> [--message \\\"...\\\"]\");\n process.exit(1);\n }\n if (!propertyId) {\n console.error(\"Error: Missing --application-id <uuid> (alias: --property-id).\");\n console.error(\"Usage: canary release mark-deploy --commit <sha> --application-id <uuid> [--message \\\"...\\\"]\");\n process.exit(1);\n }\n\n const body: Record<string, unknown> = { propertyId, commitSha };\n if (commitMessage) body.commitMessage = commitMessage;\n\n const res = await fetch(`${apiUrl}/api/v1/deployments/mark`, {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${token}`,\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify(body),\n });\n\n if (res.status === 401) {\n console.error(\"Error: Unauthorized. Check your API token.\");\n process.exit(1);\n }\n\n const json = (await res.json()) as MarkDeployResponse;\n\n if (!json.ok) {\n console.error(`Error: ${json.error}`);\n process.exit(1);\n }\n\n console.log(\"Deployment marked\");\n console.log(` Deployment ID: ${json.deploymentId}`);\n console.log(` Commit: ${json.commitSha}`);\n console.log(` Tasks triggered: ${json.tasksTriggered}`);\n}\n\nasync function handleLatestDeploy(argv: string[], apiUrl: string, token: string): Promise<void> {\n const propertyId = getApplicationIdArg(argv);\n if (!propertyId) {\n console.error(\"Error: Missing --application-id <uuid> (alias: --property-id).\");\n console.error(\"Usage: canary release latest-deploy --application-id <uuid> [--json]\");\n process.exit(1);\n }\n\n const jsonOutput = hasFlag(argv, \"--json\");\n\n const res = await fetch(\n `${apiUrl}/api/v1/deployments/latest?propertyId=${encodeURIComponent(propertyId)}`,\n { headers: { Authorization: `Bearer ${token}` } }\n );\n\n if (res.status === 401) {\n console.error(\"Error: Unauthorized. Check your API token.\");\n process.exit(1);\n }\n\n const data = (await res.json()) as LatestDeployResponse;\n\n if (!data.ok) {\n console.error(`Error: ${data.error}`);\n process.exit(1);\n }\n\n if (!data.deployment) {\n console.log(\"No deployments found for this application.\");\n return;\n }\n\n if (jsonOutput) {\n console.log(JSON.stringify(data.deployment, null, 2));\n return;\n }\n\n console.log(`Latest deployment:`);\n console.log(` ID: ${data.deployment.id}`);\n console.log(` Commit: ${data.deployment.commitSha}`);\n if (data.deployment.commitMessage) {\n console.log(` Message: ${data.deployment.commitMessage}`);\n }\n console.log(` Deployed by: ${data.deployment.deployedBy}`);\n console.log(` Source: ${data.deployment.triggerSource}`);\n console.log(` Tasks triggered: ${data.deployment.tasksTriggered}`);\n console.log(` Created: ${data.deployment.createdAt}`);\n}\n\n// ---------------------------------------------------------------------------\n// Help & routing\n// ---------------------------------------------------------------------------\n\nfunction printReleaseHelp(): void {\n console.log(\n [\n \"Usage: canary release <sub-command> [options]\",\n \"\",\n \"Sub-commands:\",\n \" trigger --application-id <uuid> [--credential-ids <uuid,...>]\",\n \" Trigger a Release QA run\",\n \" status <run-id> [--json] Check run status\",\n \" run --application-id <uuid> [options] Trigger and poll until complete\",\n \" mark-deploy --commit <sha> --application-id <uuid> [--message \\\"...\\\"]\",\n \" Mark a commit as deployed\",\n \" latest-deploy --application-id <uuid> [--json]\",\n \" Show latest deployment for an application\",\n \"\",\n \"Run options:\",\n \" --timeout <seconds> Max wait time (default: 3600)\",\n \" --poll-interval <secs> Poll frequency (default: 30)\",\n \" --credential-ids <ids> Comma-separated credential UUIDs\",\n \"\",\n \"Options:\",\n \" --env <env> Target environment (prod, dev, local)\",\n \" --api-url <url> API URL override\",\n \" --token <key> API token override (or set CANARY_API_TOKEN)\",\n ].join(\"\\n\")\n );\n}\n\nexport async function runRelease(argv: string[]): Promise<void> {\n const [subCommand, ...rest] = argv;\n\n if (!subCommand || subCommand === \"help\" || hasFlag(argv, \"--help\", \"-h\")) {\n printReleaseHelp();\n return;\n }\n\n const { apiUrl, token } = await resolveConfig(argv);\n\n switch (subCommand) {\n case \"trigger\":\n await handleTrigger(rest, apiUrl, token);\n break;\n case \"status\":\n await handleStatus(rest, apiUrl, token);\n break;\n case \"run\":\n await handleRun(rest, apiUrl, token);\n break;\n case \"mark-deploy\":\n await handleMarkDeploy(rest, apiUrl, token);\n break;\n case \"latest-deploy\":\n await handleLatestDeploy(rest, apiUrl, token);\n break;\n default:\n console.error(`Unknown sub-command: ${subCommand}`);\n printReleaseHelp();\n process.exit(1);\n }\n}\n"],"mappings":"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","names":[]}
|