@metasession.co/devaudit-cli 0.1.13 → 0.1.15
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/dist/index.js +60 -2
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/sdlc/SKILLS.md +6 -11
- package/sdlc/files/_common/5-deploy-main.md +9 -0
- package/sdlc/files/_common/implementing-an-sdlc-issue.md +30 -15
- package/sdlc/files/_common/scripts/close-out-release.sh +143 -0
- package/sdlc/files/ci/close-out-release.yml.template +96 -0
package/dist/index.js
CHANGED
|
@@ -54,7 +54,7 @@ function emitJsonResult(payload) {
|
|
|
54
54
|
|
|
55
55
|
// package.json
|
|
56
56
|
var package_default = {
|
|
57
|
-
version: "0.1.
|
|
57
|
+
version: "0.1.15"};
|
|
58
58
|
|
|
59
59
|
// src/lib/version.ts
|
|
60
60
|
var CLI_VERSION = package_default.version;
|
|
@@ -235,6 +235,57 @@ async function checkNodeVersion() {
|
|
|
235
235
|
const ok2 = major >= 22;
|
|
236
236
|
return { name: "node", ok: ok2, detail: `v${version} (require >=22)` };
|
|
237
237
|
}
|
|
238
|
+
async function checkReleaseCloseoutDrift() {
|
|
239
|
+
const name = "releases";
|
|
240
|
+
let cfg;
|
|
241
|
+
try {
|
|
242
|
+
cfg = JSON.parse(await promises.readFile("sdlc-config.json", "utf-8"));
|
|
243
|
+
} catch {
|
|
244
|
+
return { name, ok: true, detail: "skipped (not a consumer project)" };
|
|
245
|
+
}
|
|
246
|
+
let entries;
|
|
247
|
+
try {
|
|
248
|
+
entries = await promises.readdir("compliance/pending-releases");
|
|
249
|
+
} catch {
|
|
250
|
+
return { name, ok: true, detail: "no pending-releases/" };
|
|
251
|
+
}
|
|
252
|
+
const reqs = entries.filter((f) => /^RELEASE-TICKET-REQ-\d+\.md$/.test(f)).map((f) => f.replace(/^RELEASE-TICKET-/, "").replace(/\.md$/, ""));
|
|
253
|
+
if (reqs.length === 0) return { name, ok: true, detail: "no pending release tickets" };
|
|
254
|
+
const slug = cfg.devaudit?.project_slug ?? cfg.project_slug;
|
|
255
|
+
const base = (cfg.devaudit?.base_url ?? "").replace(/\/$/, "");
|
|
256
|
+
const apiKey = process.env["DEVAUDIT_API_KEY"];
|
|
257
|
+
if (!slug || !base || !apiKey) {
|
|
258
|
+
return {
|
|
259
|
+
name,
|
|
260
|
+
ok: true,
|
|
261
|
+
detail: `${reqs.length} pending ticket(s); portal drift check skipped (set DEVAUDIT_API_KEY + devaudit.base_url)`
|
|
262
|
+
};
|
|
263
|
+
}
|
|
264
|
+
const drifted = [];
|
|
265
|
+
for (const req of reqs) {
|
|
266
|
+
try {
|
|
267
|
+
const ctrl = new AbortController();
|
|
268
|
+
const timer = setTimeout(() => ctrl.abort(), 1e4);
|
|
269
|
+
const res = await fetch(
|
|
270
|
+
`${base}/api/ci/releases/resolve?projectSlug=${encodeURIComponent(slug)}&versionPrefix=${encodeURIComponent(req)}`,
|
|
271
|
+
{ headers: { Authorization: `Bearer ${apiKey}` }, signal: ctrl.signal }
|
|
272
|
+
);
|
|
273
|
+
clearTimeout(timer);
|
|
274
|
+
if (!res.ok) continue;
|
|
275
|
+
const body = await res.json();
|
|
276
|
+
if (body.latest?.status === "released") drifted.push(req);
|
|
277
|
+
} catch {
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
if (drifted.length > 0) {
|
|
281
|
+
return {
|
|
282
|
+
name,
|
|
283
|
+
ok: false,
|
|
284
|
+
detail: `released on the portal but still in pending-releases/: ${drifted.join(", ")} \u2014 run ./scripts/close-out-release.sh <REQ>`
|
|
285
|
+
};
|
|
286
|
+
}
|
|
287
|
+
return { name, ok: true, detail: `${reqs.length} pending ticket(s); none released on the portal` };
|
|
288
|
+
}
|
|
238
289
|
async function runDoctor(options = {}) {
|
|
239
290
|
const log = logger();
|
|
240
291
|
log.info("Running devaudit doctor \u2014 checking required tools...\n");
|
|
@@ -251,7 +302,13 @@ async function runDoctor(options = {}) {
|
|
|
251
302
|
if (!check.ok) allOk = false;
|
|
252
303
|
log.log(` ${marker} ${check.name.padEnd(8)} ${check.detail}`);
|
|
253
304
|
}
|
|
305
|
+
const closeout = await checkReleaseCloseoutDrift();
|
|
306
|
+
const closeoutMarker = closeout.ok ? "\u2713" : "\u26A0";
|
|
307
|
+
log.log(` ${closeoutMarker} ${closeout.name.padEnd(8)} ${closeout.detail}`);
|
|
254
308
|
log.log("");
|
|
309
|
+
if (!closeout.ok) {
|
|
310
|
+
log.warn("Release close-out drift detected \u2014 see above. (Does not affect the tool check.)");
|
|
311
|
+
}
|
|
255
312
|
const plugins = options.plugins ?? (await discoverPlugins()).loaded;
|
|
256
313
|
if (plugins.length > 0) {
|
|
257
314
|
const ctx = await buildPluginContext({ projectPath: resolve(process.cwd()) });
|
|
@@ -1741,7 +1798,8 @@ var CI_TEMPLATES = [
|
|
|
1741
1798
|
"compliance-validation.yml.template",
|
|
1742
1799
|
"check-release-approval.yml.template",
|
|
1743
1800
|
"post-deploy-prod.yml.template",
|
|
1744
|
-
"compliance-evidence.yml.template"
|
|
1801
|
+
"compliance-evidence.yml.template",
|
|
1802
|
+
"close-out-release.yml.template"
|
|
1745
1803
|
];
|
|
1746
1804
|
var OLD_WORKFLOWS_TO_REMOVE = ["test-on-pr.yml", "check-uat-approval.yml"];
|
|
1747
1805
|
function indentEnvBlock(env, indent) {
|