@metasession.co/devaudit-cli 0.3.6 → 0.3.8
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 +23 -9
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/scripts/upload-evidence.sh +10 -0
- package/sdlc/files/_common/scripts/close-out-contract.sh +34 -0
- package/sdlc/files/_common/scripts/derive-release-version.sh +18 -0
- package/sdlc/files/_common/scripts/derive-release-version.test.sh +9 -0
- package/sdlc/files/_common/scripts/extract-release-metadata.sh +119 -0
- package/sdlc/files/_common/scripts/extract-release-metadata.test.sh +278 -0
- package/sdlc/files/_common/scripts/validate-test-summary.sh +37 -0
- package/sdlc/files/_common/scripts/validate-test-summary.test.sh +87 -0
- package/sdlc/files/_common/skills/e2e-test-engineer/SKILL.md +16 -0
- package/sdlc/files/_common/skills/sdlc-implementer/SKILL.md +7 -4
- package/sdlc/files/ci/check-release-approval.yml.template +80 -21
- package/sdlc/files/ci/ci-status-fallback.yml.template +3 -0
- package/sdlc/files/ci/ci.yml.template +24 -33
- package/sdlc/files/ci/close-out-release.yml.template +67 -11
- package/sdlc/files/ci/compliance-evidence.yml.template +32 -16
- package/sdlc/files/ci/quality-gates-provenance.yml.template +62 -0
- package/sdlc/files/stacks/node/hooks/pre-push +58 -8
- package/sdlc/package.json +1 -1
- package/sdlc/src/bin/devaudit-sdlc.js +22 -2
- package/sdlc/src/blueprints/3-compile-evidence.raw.md +20 -6
package/dist/index.js
CHANGED
|
@@ -56,7 +56,7 @@ function emitJsonResult(payload) {
|
|
|
56
56
|
|
|
57
57
|
// package.json
|
|
58
58
|
var package_default = {
|
|
59
|
-
version: "0.3.
|
|
59
|
+
version: "0.3.8"};
|
|
60
60
|
|
|
61
61
|
// src/lib/version.ts
|
|
62
62
|
var CLI_VERSION = package_default.version;
|
|
@@ -649,6 +649,7 @@ function buildUploadForm(file, buf, opts) {
|
|
|
649
649
|
if (opts.evidenceCategory) form.set("evidenceCategory", opts.evidenceCategory);
|
|
650
650
|
if (opts.releaseBranch) form.set("releaseBranch", opts.releaseBranch);
|
|
651
651
|
if (opts.releaseTitle) form.set("releaseTitle", opts.releaseTitle);
|
|
652
|
+
if (opts.releaseSummary) form.set("releaseSummary", opts.releaseSummary);
|
|
652
653
|
if (opts.changeType) form.set("changeType", opts.changeType);
|
|
653
654
|
if (opts.gateStatus) form.set("gateStatus", opts.gateStatus);
|
|
654
655
|
if (opts.sdlcStage) form.set("sdlcStage", opts.sdlcStage);
|
|
@@ -767,6 +768,8 @@ async function uploadPresigned(file, buf, opts) {
|
|
|
767
768
|
...opts.releaseBranch ? { releaseBranch: opts.releaseBranch } : {},
|
|
768
769
|
...opts.environment ? { environment: opts.environment } : {},
|
|
769
770
|
...opts.evidenceCategory ? { evidenceCategory: opts.evidenceCategory } : {},
|
|
771
|
+
...opts.releaseTitle ? { releaseTitle: opts.releaseTitle } : {},
|
|
772
|
+
...opts.releaseSummary ? { releaseSummary: opts.releaseSummary } : {},
|
|
770
773
|
...opts.sdlcStage ? { sdlcStage: opts.sdlcStage } : {},
|
|
771
774
|
...opts.testCycleId ? { testCycleId: opts.testCycleId } : {}
|
|
772
775
|
}),
|
|
@@ -1008,6 +1011,7 @@ async function runPush(options) {
|
|
|
1008
1011
|
...options.category !== void 0 ? { evidenceCategory: options.category } : {},
|
|
1009
1012
|
...options.branch !== void 0 ? { releaseBranch: options.branch } : {},
|
|
1010
1013
|
...options.releaseTitle !== void 0 ? { releaseTitle: options.releaseTitle } : {},
|
|
1014
|
+
...options.releaseSummary !== void 0 ? { releaseSummary: options.releaseSummary } : {},
|
|
1011
1015
|
...options.changeType !== void 0 ? { changeType: options.changeType } : {},
|
|
1012
1016
|
...options.gateStatus !== void 0 ? { gateStatus: options.gateStatus } : {},
|
|
1013
1017
|
...options.sdlcStage !== void 0 ? { sdlcStage: options.sdlcStage } : {},
|
|
@@ -1732,10 +1736,13 @@ async function bootstrapNode(ctx) {
|
|
|
1732
1736
|
await execa("npx", ["husky", "init"], { cwd: ctx.projectPath, stdio: "inherit" });
|
|
1733
1737
|
return { step: "8/11 Bootstrap hook framework", status: "ok", message: ".husky/ bootstrapped" };
|
|
1734
1738
|
}
|
|
1735
|
-
var
|
|
1739
|
+
var MAIN_REQUIRED_CHECKS = [
|
|
1736
1740
|
"Quality Gates",
|
|
1737
1741
|
"CI Status Fallback"
|
|
1738
1742
|
];
|
|
1743
|
+
var DEVELOP_REQUIRED_CHECKS = [
|
|
1744
|
+
"Quality Gates"
|
|
1745
|
+
];
|
|
1739
1746
|
var MAIN_REVIEW_COUNT = 1;
|
|
1740
1747
|
var DEVELOP_REVIEW_COUNT = 0;
|
|
1741
1748
|
async function resolveIntegrationBranch(projectPath) {
|
|
@@ -1771,18 +1778,18 @@ async function configureBranchProtection(ctx, provider) {
|
|
|
1771
1778
|
return {
|
|
1772
1779
|
step: "9/11 Configure branch protection",
|
|
1773
1780
|
status: "planned",
|
|
1774
|
-
message: `would apply branch protection on ${repo}:${meta.defaultBranch} (1 review) + ${integrationBranch} (0 reviews
|
|
1781
|
+
message: `would apply branch protection on ${repo}:${meta.defaultBranch} (1 review, checks=${JSON.stringify(MAIN_REQUIRED_CHECKS)}) + ${integrationBranch} (0 reviews, checks=${JSON.stringify(DEVELOP_REQUIRED_CHECKS)})`
|
|
1775
1782
|
};
|
|
1776
1783
|
}
|
|
1777
1784
|
const results = [];
|
|
1778
|
-
const mainResult = await provider.applyBranchProtection(ctx.projectPath, meta.defaultBranch,
|
|
1785
|
+
const mainResult = await provider.applyBranchProtection(ctx.projectPath, meta.defaultBranch, MAIN_REQUIRED_CHECKS, { requiredReviewCount: MAIN_REVIEW_COUNT });
|
|
1779
1786
|
if (mainResult.applied) {
|
|
1780
1787
|
results.push(`${meta.defaultBranch}: ok (${MAIN_REVIEW_COUNT} review)`);
|
|
1781
1788
|
} else {
|
|
1782
1789
|
results.push(`${meta.defaultBranch}: FAILED \u2014 ${mainResult.message ?? "unknown"}`);
|
|
1783
1790
|
}
|
|
1784
1791
|
if (integrationBranch !== meta.defaultBranch) {
|
|
1785
|
-
const devResult = await provider.applyBranchProtection(ctx.projectPath, integrationBranch,
|
|
1792
|
+
const devResult = await provider.applyBranchProtection(ctx.projectPath, integrationBranch, DEVELOP_REQUIRED_CHECKS, { requiredReviewCount: DEVELOP_REVIEW_COUNT });
|
|
1786
1793
|
if (devResult.applied) {
|
|
1787
1794
|
results.push(`${integrationBranch}: ok (${DEVELOP_REVIEW_COUNT} reviews)`);
|
|
1788
1795
|
} else {
|
|
@@ -2253,6 +2260,9 @@ function stripServicesBlock(content) {
|
|
|
2253
2260
|
var CI_TEMPLATES = [
|
|
2254
2261
|
"ci.yml.template",
|
|
2255
2262
|
"ci-status-fallback.yml.template",
|
|
2263
|
+
// DevAudit-Installer#280: same-SHA provenance check on PRs to main.
|
|
2264
|
+
// Verifies prior Quality Gates success without rerunning heavy CI.
|
|
2265
|
+
"quality-gates-provenance.yml.template",
|
|
2256
2266
|
"compliance-validation.yml.template",
|
|
2257
2267
|
"check-release-approval.yml.template",
|
|
2258
2268
|
"post-deploy-prod.yml.template",
|
|
@@ -2514,10 +2524,13 @@ async function syncWorkflows(ctx) {
|
|
|
2514
2524
|
message: files.length > 0 ? `synced to .devin/workflows/` : "no workflow files found"
|
|
2515
2525
|
};
|
|
2516
2526
|
}
|
|
2517
|
-
var
|
|
2527
|
+
var MAIN_REQUIRED_CHECKS2 = [
|
|
2518
2528
|
"Quality Gates",
|
|
2519
2529
|
"CI Status Fallback"
|
|
2520
2530
|
];
|
|
2531
|
+
var DEVELOP_REQUIRED_CHECKS2 = [
|
|
2532
|
+
"Quality Gates"
|
|
2533
|
+
];
|
|
2521
2534
|
var MAIN_REVIEW_COUNT2 = 1;
|
|
2522
2535
|
var DEVELOP_REVIEW_COUNT2 = 0;
|
|
2523
2536
|
async function verifyBranchProtection(ctx) {
|
|
@@ -2545,14 +2558,14 @@ async function verifyBranchProtection(ctx) {
|
|
|
2545
2558
|
};
|
|
2546
2559
|
}
|
|
2547
2560
|
const results = [];
|
|
2548
|
-
const mainResult = await provider.applyBranchProtection(ctx.projectPath, meta.defaultBranch,
|
|
2561
|
+
const mainResult = await provider.applyBranchProtection(ctx.projectPath, meta.defaultBranch, MAIN_REQUIRED_CHECKS2, { requiredReviewCount: MAIN_REVIEW_COUNT2 });
|
|
2549
2562
|
if (mainResult.applied) {
|
|
2550
2563
|
results.push(`${meta.defaultBranch}: ok`);
|
|
2551
2564
|
} else {
|
|
2552
2565
|
results.push(`${meta.defaultBranch}: failed \u2014 ${mainResult.message ?? "unknown"}`);
|
|
2553
2566
|
}
|
|
2554
2567
|
if (integrationBranch !== meta.defaultBranch) {
|
|
2555
|
-
const devResult = await provider.applyBranchProtection(ctx.projectPath, integrationBranch,
|
|
2568
|
+
const devResult = await provider.applyBranchProtection(ctx.projectPath, integrationBranch, DEVELOP_REQUIRED_CHECKS2, { requiredReviewCount: DEVELOP_REVIEW_COUNT2 });
|
|
2556
2569
|
if (devResult.applied) {
|
|
2557
2570
|
results.push(`${integrationBranch}: ok`);
|
|
2558
2571
|
} else {
|
|
@@ -3327,7 +3340,7 @@ async function main(argv) {
|
|
|
3327
3340
|
...globals.dryRun !== void 0 ? { dryRun: Boolean(globals.dryRun) } : {}
|
|
3328
3341
|
});
|
|
3329
3342
|
});
|
|
3330
|
-
program.command("push <project-slug> <requirement-id> <evidence-type> <file>").description("Upload evidence file(s) to DevAudit (port of scripts/upload-evidence.sh)").option("--release <version>", "release version (e.g. v1.0.0)").option("--create-release-if-missing", "auto-create the release as 'draft' if absent").option("--environment <env>", "uat | production").option("--category <cat>", "ci_pipeline | local_dev | planning | test_report | security_scan | release_artifact").option("--git-sha <sha>", "attached to metadata.gitSha").option("--ci-run-id <id>", "attached to metadata.ciRunId").option("--branch <name>", "git branch \u2014 sent as releaseBranch + metadata.branch").option("--release-title <text>", "human title for the release row (releaseTitle; portal no-clobbers)").option("--change-type <type>", "conventional-commit prefix for the release row (changeType)").option("--gate-status <status>", "passed | failed | skipped (gateStatus)").option("--sdlc-stage <stage>", "SDLC stage 1-5 (sdlcStage)").option("--test-cycle <id>", "test cycle identifier (typically the CI run ID)").option(
|
|
3343
|
+
program.command("push <project-slug> <requirement-id> <evidence-type> <file>").description("Upload evidence file(s) to DevAudit (port of scripts/upload-evidence.sh)").option("--release <version>", "release version (e.g. v1.0.0)").option("--create-release-if-missing", "auto-create the release as 'draft' if absent").option("--environment <env>", "uat | production").option("--category <cat>", "ci_pipeline | local_dev | planning | test_report | security_scan | release_artifact").option("--git-sha <sha>", "attached to metadata.gitSha").option("--ci-run-id <id>", "attached to metadata.ciRunId").option("--branch <name>", "git branch \u2014 sent as releaseBranch + metadata.branch").option("--release-title <text>", "human title for the release row (releaseTitle; portal no-clobbers)").option("--release-summary <text>", "reviewer-facing short description (releaseSummary; portal no-clobbers)").option("--change-type <type>", "conventional-commit prefix for the release row (changeType)").option("--gate-status <status>", "passed | failed | skipped (gateStatus)").option("--sdlc-stage <stage>", "SDLC stage 1-5 (sdlcStage)").option("--test-cycle <id>", "test cycle identifier (typically the CI run ID)").option(
|
|
3331
3344
|
"--meta-key <pair>",
|
|
3332
3345
|
"repeatable key=value merged into the metadata JSON",
|
|
3333
3346
|
(val, acc) => [...acc, val],
|
|
@@ -3348,6 +3361,7 @@ async function main(argv) {
|
|
|
3348
3361
|
...opts.ciRunId !== void 0 ? { ciRunId: opts.ciRunId } : {},
|
|
3349
3362
|
...opts.branch !== void 0 ? { branch: opts.branch } : {},
|
|
3350
3363
|
...opts.releaseTitle !== void 0 ? { releaseTitle: opts.releaseTitle } : {},
|
|
3364
|
+
...opts.releaseSummary !== void 0 ? { releaseSummary: opts.releaseSummary } : {},
|
|
3351
3365
|
...opts.changeType !== void 0 ? { changeType: opts.changeType } : {},
|
|
3352
3366
|
...opts.gateStatus !== void 0 ? { gateStatus: opts.gateStatus } : {},
|
|
3353
3367
|
...opts.sdlcStage !== void 0 ? { sdlcStage: opts.sdlcStage } : {},
|