@biffo/cli 0.283.3 → 0.283.4
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 +138 -43
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -9693,6 +9693,7 @@ import { cpSync as cpSync6, existsSync as existsSync35, mkdirSync as mkdirSync12
|
|
|
9693
9693
|
import { join as join37, relative as relative7, resolve as resolve17 } from "path";
|
|
9694
9694
|
import chalk19 from "chalk";
|
|
9695
9695
|
import { Command as Command20 } from "commander";
|
|
9696
|
+
import { execa as execa7 } from "execa";
|
|
9696
9697
|
import inquirer7 from "inquirer";
|
|
9697
9698
|
var pluginUpgradeCommand = new Command20("upgrade").description(
|
|
9698
9699
|
"Upgrade an installed plugin to a new minor version (biffo plugin upgrade <name>@<new-minor>) or refresh it in place from a local, unpublished checkout (biffo plugin upgrade --local <path>)"
|
|
@@ -9794,6 +9795,7 @@ async function runPluginUpgrade(target, options, deps) {
|
|
|
9794
9795
|
refuseIfModuleStillReferenced(options.cwd, modulesDir, entry.name);
|
|
9795
9796
|
}
|
|
9796
9797
|
const previousProvenance = readProvenance(targetDir);
|
|
9798
|
+
const previousPyproject = readPyprojectIfPresent(targetDir);
|
|
9797
9799
|
rmSync10(targetDir, { recursive: true, force: true });
|
|
9798
9800
|
mkdirSync12(targetDir, { recursive: true });
|
|
9799
9801
|
cpSync6(tmpDir, targetDir, { recursive: true });
|
|
@@ -9804,6 +9806,7 @@ async function runPluginUpgrade(target, options, deps) {
|
|
|
9804
9806
|
);
|
|
9805
9807
|
writePluginProvenance(targetDir, reconcileProvenance(previousProvenance, nextProvenance));
|
|
9806
9808
|
applyWorkspaceSources(targetDir, options.cwd, `services/${entry.name}`);
|
|
9809
|
+
const newPyproject = readPyprojectIfPresent(targetDir);
|
|
9807
9810
|
const stagePaths = [`services/${entry.name}`];
|
|
9808
9811
|
if (existsSync35(modulesDir)) {
|
|
9809
9812
|
rmSync10(modulesDir, { recursive: true, force: true });
|
|
@@ -9835,12 +9838,29 @@ async function runPluginUpgrade(target, options, deps) {
|
|
|
9835
9838
|
if (seedResult.vendored) {
|
|
9836
9839
|
stagePaths.push(seedResult.stagedPath);
|
|
9837
9840
|
}
|
|
9841
|
+
const lockOutcomes = await relockIfDependenciesChanged(
|
|
9842
|
+
options.cwd,
|
|
9843
|
+
`services/${entry.name}/pyproject.toml`,
|
|
9844
|
+
previousPyproject,
|
|
9845
|
+
newPyproject,
|
|
9846
|
+
deps
|
|
9847
|
+
);
|
|
9848
|
+
for (const outcome of lockOutcomes) {
|
|
9849
|
+
if (outcome.ok) stagePaths.push(outcome.trigger.lockfile);
|
|
9850
|
+
}
|
|
9838
9851
|
const label = currentVersion ? `${entry.name} ${currentVersion} -> ${entry.version}` : `${entry.name} to ${entry.version}`;
|
|
9839
9852
|
const commitMessage = `feat(plugins): upgrade ${label}`;
|
|
9840
9853
|
await deps.git.add(options.cwd, stagePaths);
|
|
9841
9854
|
await deps.git.commit(options.cwd, commitMessage);
|
|
9842
9855
|
log.success(`Committed: ${commitMessage}`);
|
|
9843
|
-
|
|
9856
|
+
const lockFailures = describeFailures(lockOutcomes);
|
|
9857
|
+
if (lockFailures.length > 0) {
|
|
9858
|
+
console.log(chalk19.yellow.bold("\n \u26A0 Plugin upgraded, but uv.lock needs attention\n"));
|
|
9859
|
+
for (const failure of lockFailures) console.log(chalk19.yellow(` ${failure}`));
|
|
9860
|
+
console.log();
|
|
9861
|
+
} else {
|
|
9862
|
+
console.log(chalk19.bold("\n Plugin upgraded!\n"));
|
|
9863
|
+
}
|
|
9844
9864
|
console.log(` ${entry.name}@${entry.version} is committed at services/${entry.name}/`);
|
|
9845
9865
|
console.log(" Push and redeploy to apply its updated tables and routes:");
|
|
9846
9866
|
console.log(chalk19.dim(` git push`));
|
|
@@ -9889,6 +9909,7 @@ async function runLocalPluginRefresh(localPath, options, deps) {
|
|
|
9889
9909
|
refuseIfModuleStillReferenced(options.cwd, modulesDir, source.name);
|
|
9890
9910
|
}
|
|
9891
9911
|
const previousProvenance = readProvenance(targetDir);
|
|
9912
|
+
const previousPyproject = readPyprojectIfPresent(targetDir);
|
|
9892
9913
|
if (inTreeSource) {
|
|
9893
9914
|
log.info(
|
|
9894
9915
|
`services/${source.name}/ is already the local checkout \u2014 nothing to copy; re-syncing its Terraform module and checking for a migration.`
|
|
@@ -9902,6 +9923,7 @@ async function runLocalPluginRefresh(localPath, options, deps) {
|
|
|
9902
9923
|
const nextProvenance = inTreeSource ? inTreePluginProvenance(`services/${source.name}`) : await resolveLocalProvenance(source.sourceDir, source.origin);
|
|
9903
9924
|
writePluginProvenance(targetDir, reconcileProvenance(previousProvenance, nextProvenance));
|
|
9904
9925
|
applyWorkspaceSources(targetDir, options.cwd, `services/${source.name}`);
|
|
9926
|
+
const newPyproject = readPyprojectIfPresent(targetDir);
|
|
9905
9927
|
const stagePaths = [`services/${source.name}`];
|
|
9906
9928
|
if (existsSync35(modulesDir)) {
|
|
9907
9929
|
rmSync10(modulesDir, { recursive: true, force: true });
|
|
@@ -9935,6 +9957,16 @@ async function runLocalPluginRefresh(localPath, options, deps) {
|
|
|
9935
9957
|
if (seedResult.vendored) {
|
|
9936
9958
|
stagePaths.push(seedResult.stagedPath);
|
|
9937
9959
|
}
|
|
9960
|
+
const lockOutcomes = await relockIfDependenciesChanged(
|
|
9961
|
+
options.cwd,
|
|
9962
|
+
`services/${source.name}/pyproject.toml`,
|
|
9963
|
+
previousPyproject,
|
|
9964
|
+
newPyproject,
|
|
9965
|
+
deps
|
|
9966
|
+
);
|
|
9967
|
+
for (const outcome of lockOutcomes) {
|
|
9968
|
+
if (outcome.ok) stagePaths.push(outcome.trigger.lockfile);
|
|
9969
|
+
}
|
|
9938
9970
|
await deps.git.add(options.cwd, stagePaths);
|
|
9939
9971
|
if (!await deps.git.hasUncommittedChanges(options.cwd)) {
|
|
9940
9972
|
log.warn(`services/${source.name}/ already matches ${source.origin} \u2014 nothing to commit.`);
|
|
@@ -9943,7 +9975,14 @@ async function runLocalPluginRefresh(localPath, options, deps) {
|
|
|
9943
9975
|
const commitMessage = `chore(plugins): refresh ${source.name} from local checkout`;
|
|
9944
9976
|
await deps.git.commit(options.cwd, commitMessage);
|
|
9945
9977
|
log.success(`Committed: ${commitMessage}`);
|
|
9946
|
-
|
|
9978
|
+
const lockFailures = describeFailures(lockOutcomes);
|
|
9979
|
+
if (lockFailures.length > 0) {
|
|
9980
|
+
console.log(chalk19.yellow.bold("\n \u26A0 Plugin refreshed, but uv.lock needs attention\n"));
|
|
9981
|
+
for (const failure of lockFailures) console.log(chalk19.yellow(` ${failure}`));
|
|
9982
|
+
console.log();
|
|
9983
|
+
} else {
|
|
9984
|
+
console.log(chalk19.bold("\n Plugin refreshed!\n"));
|
|
9985
|
+
}
|
|
9947
9986
|
console.log(` services/${source.name}/ now matches ${source.origin}`);
|
|
9948
9987
|
console.log(" Push and redeploy to apply any updated tables and routes:");
|
|
9949
9988
|
console.log(chalk19.dim(` git push`));
|
|
@@ -9964,6 +10003,62 @@ ${refList}
|
|
|
9964
10003
|
A plugin repo without terraform/ is missing the directory, not declaring that the module should go, and a wrong destructive action here is worse than no action. Either remove the reference(s) above yourself, or run 'biffo plugin uninstall ${name}', which removes the module and unwires the reference together.`
|
|
9965
10004
|
);
|
|
9966
10005
|
}
|
|
10006
|
+
async function relockIfDependenciesChanged(cwd, relPyprojectPath, previousPyproject, newPyproject, deps) {
|
|
10007
|
+
if (!dependenciesChanged(previousPyproject, newPyproject)) return [];
|
|
10008
|
+
const triggers = lockfilesNeedingRefresh([relPyprojectPath], cwd);
|
|
10009
|
+
if (triggers.length === 0) return [];
|
|
10010
|
+
const run = deps.runCommand ?? defaultRunCommand2;
|
|
10011
|
+
const outcomes = await refreshLockfiles(cwd, triggers, run);
|
|
10012
|
+
const refreshed = outcomes.filter((o) => o.ok);
|
|
10013
|
+
if (refreshed.length > 0) {
|
|
10014
|
+
log.success(
|
|
10015
|
+
`Refreshed ${refreshed.map((o) => o.trigger.lockfile).join(", ")} \u2014 this refresh changed a dependency it locks.`
|
|
10016
|
+
);
|
|
10017
|
+
}
|
|
10018
|
+
for (const message of describeFailures(outcomes)) log.warn(message);
|
|
10019
|
+
return outcomes;
|
|
10020
|
+
}
|
|
10021
|
+
var defaultRunCommand2 = async (command, cwd) => {
|
|
10022
|
+
const [bin, ...args] = command;
|
|
10023
|
+
if (!bin) return { ok: false, error: "empty command" };
|
|
10024
|
+
try {
|
|
10025
|
+
await execa7(bin, args, { cwd });
|
|
10026
|
+
return { ok: true };
|
|
10027
|
+
} catch (err) {
|
|
10028
|
+
const cause = err;
|
|
10029
|
+
const detail = cause.stderr?.trim() || cause.shortMessage || cause.message || "failed";
|
|
10030
|
+
return { ok: false, error: detail.split("\n")[0] ?? "failed" };
|
|
10031
|
+
}
|
|
10032
|
+
};
|
|
10033
|
+
function readPyprojectIfPresent(targetDir) {
|
|
10034
|
+
const path = join37(targetDir, "pyproject.toml");
|
|
10035
|
+
return existsSync35(path) ? readFileSync26(path, "utf8") : null;
|
|
10036
|
+
}
|
|
10037
|
+
function dependenciesChanged(before, after) {
|
|
10038
|
+
if (before === after) return false;
|
|
10039
|
+
const beforeItems = before ? dependencySurface(before) : [];
|
|
10040
|
+
const afterItems = after ? dependencySurface(after) : [];
|
|
10041
|
+
return JSON.stringify(beforeItems) !== JSON.stringify(afterItems);
|
|
10042
|
+
}
|
|
10043
|
+
function dependencySurface(text) {
|
|
10044
|
+
const items = [...readTomlStringArray(text, "dependencies")];
|
|
10045
|
+
for (const header of ["dependency-groups", "project.optional-dependencies"]) {
|
|
10046
|
+
const body = tomlTableBody(text, header);
|
|
10047
|
+
if (!body) continue;
|
|
10048
|
+
for (const m of body.matchAll(/^([A-Za-z0-9_.-]+)\s*=\s*\[/gm)) {
|
|
10049
|
+
items.push(...readTomlStringArray(body, m[1]));
|
|
10050
|
+
}
|
|
10051
|
+
}
|
|
10052
|
+
return items.sort();
|
|
10053
|
+
}
|
|
10054
|
+
function tomlTableBody(text, header) {
|
|
10055
|
+
const escaped = header.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
10056
|
+
const headerMatch = new RegExp(`^\\[${escaped}\\]\\s*$`, "m").exec(text);
|
|
10057
|
+
if (!headerMatch) return null;
|
|
10058
|
+
const rest = text.slice(headerMatch.index + headerMatch[0].length);
|
|
10059
|
+
const nextHeader = /^\[/m.exec(rest);
|
|
10060
|
+
return nextHeader ? rest.slice(0, nextHeader.index) : rest;
|
|
10061
|
+
}
|
|
9967
10062
|
function readInstalledVersion2(targetDir) {
|
|
9968
10063
|
const manifestPath = join37(targetDir, "biffo.plugin.json");
|
|
9969
10064
|
if (!existsSync35(manifestPath)) return void 0;
|
|
@@ -10314,7 +10409,7 @@ import { Command as Command24 } from "commander";
|
|
|
10314
10409
|
// src/scripts/check-adr-numbering.ts
|
|
10315
10410
|
import { existsSync as existsSync38 } from "fs";
|
|
10316
10411
|
import { join as join39 } from "path";
|
|
10317
|
-
import { execa as
|
|
10412
|
+
import { execa as execa8 } from "execa";
|
|
10318
10413
|
|
|
10319
10414
|
// src/lib/adr-numbering-guard.ts
|
|
10320
10415
|
import { existsSync as existsSync37, readdirSync as readdirSync15, readFileSync as readFileSync28 } from "fs";
|
|
@@ -10388,7 +10483,7 @@ function formatAdrReservedRangeViolations(violations, reservedUpTo = TEMPLATE_AD
|
|
|
10388
10483
|
|
|
10389
10484
|
// src/scripts/check-adr-numbering.ts
|
|
10390
10485
|
async function runAdrNumberingCheck() {
|
|
10391
|
-
const root = (await
|
|
10486
|
+
const root = (await execa8("git", ["rev-parse", "--show-toplevel"])).stdout.trim();
|
|
10392
10487
|
const adrDir = join39(root, "docs", "ADR");
|
|
10393
10488
|
if (!existsSync38(adrDir)) {
|
|
10394
10489
|
console.log("\u2713 ADR numbering guard: no docs/ADR/ directory \u2014 nothing to compare");
|
|
@@ -10429,7 +10524,7 @@ Already accepted? List it in docs/ADR/${ALLOWLIST_FILENAME} instead of leaving t
|
|
|
10429
10524
|
|
|
10430
10525
|
// src/scripts/check-branch-protection.ts
|
|
10431
10526
|
import { Octokit as Octokit2 } from "@octokit/rest";
|
|
10432
|
-
import { execa as
|
|
10527
|
+
import { execa as execa9 } from "execa";
|
|
10433
10528
|
|
|
10434
10529
|
// src/lib/branch-protection-apply.ts
|
|
10435
10530
|
var CONTEXT_CONSISTENCY_THRESHOLD = 2 / 3;
|
|
@@ -10556,7 +10651,7 @@ async function resolveRepo(explicit) {
|
|
|
10556
10651
|
}
|
|
10557
10652
|
return { owner, repo };
|
|
10558
10653
|
}
|
|
10559
|
-
const { stdout } = await
|
|
10654
|
+
const { stdout } = await execa9("git", ["remote", "get-url", "origin"]);
|
|
10560
10655
|
const m = /github\.com[:/]([^/]+)\/(.+?)(?:\.git)?$/.exec(stdout.trim());
|
|
10561
10656
|
if (!m?.[1] || !m[2]) {
|
|
10562
10657
|
console.error(
|
|
@@ -10690,7 +10785,7 @@ async function runBranchProtectionCheck(explicitRepo, options = {}) {
|
|
|
10690
10785
|
// src/scripts/check-codeql-suppression.ts
|
|
10691
10786
|
import { existsSync as existsSync39 } from "fs";
|
|
10692
10787
|
import { join as join41, relative as relative8 } from "path";
|
|
10693
|
-
import { execa as
|
|
10788
|
+
import { execa as execa10 } from "execa";
|
|
10694
10789
|
|
|
10695
10790
|
// src/lib/codeql-suppression-guard.ts
|
|
10696
10791
|
import { readdirSync as readdirSync16, readFileSync as readFileSync29, statSync as statSync9 } from "fs";
|
|
@@ -10761,7 +10856,7 @@ function sweepCodeqlSuppressionComments(root) {
|
|
|
10761
10856
|
|
|
10762
10857
|
// src/scripts/check-codeql-suppression.ts
|
|
10763
10858
|
async function runCodeqlSuppressionCheck() {
|
|
10764
|
-
const root = (await
|
|
10859
|
+
const root = (await execa10("git", ["rev-parse", "--show-toplevel"])).stdout.trim();
|
|
10765
10860
|
const scanRoot = join41(root, "cli", "src");
|
|
10766
10861
|
if (!existsSync39(scanRoot)) {
|
|
10767
10862
|
console.log(
|
|
@@ -10787,7 +10882,7 @@ async function runCodeqlSuppressionCheck() {
|
|
|
10787
10882
|
}
|
|
10788
10883
|
|
|
10789
10884
|
// src/scripts/check-cognito-invite-template.ts
|
|
10790
|
-
import { execa as
|
|
10885
|
+
import { execa as execa11 } from "execa";
|
|
10791
10886
|
|
|
10792
10887
|
// src/lib/cognito-invite-template-guard.ts
|
|
10793
10888
|
import { readdirSync as readdirSync17, readFileSync as readFileSync30, statSync as statSync10 } from "fs";
|
|
@@ -10894,7 +10989,7 @@ function checkCognitoInviteTemplates(repoRoot) {
|
|
|
10894
10989
|
|
|
10895
10990
|
// src/scripts/check-cognito-invite-template.ts
|
|
10896
10991
|
async function runCognitoInviteTemplateCheck() {
|
|
10897
|
-
const root = (await
|
|
10992
|
+
const root = (await execa11("git", ["rev-parse", "--show-toplevel"])).stdout.trim();
|
|
10898
10993
|
const files = findModuleTerraformFiles(root);
|
|
10899
10994
|
console.log(`audited ${files.length} .tf file(s) under modules/ under ${root}`);
|
|
10900
10995
|
if (files.length === 0) {
|
|
@@ -10917,7 +11012,7 @@ async function runCognitoInviteTemplateCheck() {
|
|
|
10917
11012
|
|
|
10918
11013
|
// src/scripts/check-core-direct-paths.ts
|
|
10919
11014
|
import { join as join44 } from "path";
|
|
10920
|
-
import { execa as
|
|
11015
|
+
import { execa as execa12 } from "execa";
|
|
10921
11016
|
|
|
10922
11017
|
// src/lib/core-direct-paths-audit.ts
|
|
10923
11018
|
import { existsSync as existsSync40, readFileSync as readFileSync31, readdirSync as readdirSync18, statSync as statSync11 } from "fs";
|
|
@@ -11245,7 +11340,7 @@ function auditSiblingCoreDirectPaths(params) {
|
|
|
11245
11340
|
|
|
11246
11341
|
// src/scripts/check-core-direct-paths.ts
|
|
11247
11342
|
async function runCoreDirectPathsCheck(opts = {}) {
|
|
11248
|
-
const root = (await
|
|
11343
|
+
const root = (await execa12("git", ["rev-parse", "--show-toplevel"])).stdout.trim();
|
|
11249
11344
|
const sibling = opts.sibling ?? "sibling-template (self-check)";
|
|
11250
11345
|
const frontendSrcDir = opts.frontendSrc ?? join44(root, "_skeletons", "sibling-template", "apps", "frontend", "src");
|
|
11251
11346
|
let coreApiSrcDir;
|
|
@@ -11299,7 +11394,7 @@ async function runCoreDirectPathsCheck(opts = {}) {
|
|
|
11299
11394
|
}
|
|
11300
11395
|
|
|
11301
11396
|
// src/scripts/check-core-ownership.ts
|
|
11302
|
-
import { execa as
|
|
11397
|
+
import { execa as execa13 } from "execa";
|
|
11303
11398
|
var BOLD = "\x1B[1m";
|
|
11304
11399
|
var DIM = "\x1B[2m";
|
|
11305
11400
|
var RED = "\x1B[31m";
|
|
@@ -11310,7 +11405,7 @@ async function runOwnershipCheck(argv) {
|
|
|
11310
11405
|
const stagedFlag = args.indexOf("--staged");
|
|
11311
11406
|
const staged = stagedFlag !== -1;
|
|
11312
11407
|
const messageFile = staged ? args[stagedFlag + 1] : void 0;
|
|
11313
|
-
const root = (await
|
|
11408
|
+
const root = (await execa13("git", ["rev-parse", "--show-toplevel"])).stdout.trim();
|
|
11314
11409
|
const ownership = classifyRepoOwnership(root);
|
|
11315
11410
|
if (ownership === "template") {
|
|
11316
11411
|
console.log("\u2713 core ownership guard: skipped \u2014 this is the template, which owns these paths.");
|
|
@@ -11326,7 +11421,7 @@ async function runOwnershipCheck(argv) {
|
|
|
11326
11421
|
let deletedFiles = [];
|
|
11327
11422
|
let commitMessage = "";
|
|
11328
11423
|
if (staged) {
|
|
11329
|
-
const { stdout } = await
|
|
11424
|
+
const { stdout } = await execa13("git", ["diff", "--cached", "--name-status"], { cwd: root });
|
|
11330
11425
|
({ changed: changedFiles, deleted: deletedFiles } = parseNameStatus(stdout));
|
|
11331
11426
|
if (messageFile) {
|
|
11332
11427
|
const { readFileSync: readFileSync41, existsSync: existsSync50 } = await import("fs");
|
|
@@ -11338,18 +11433,18 @@ async function runOwnershipCheck(argv) {
|
|
|
11338
11433
|
console.error("No base ref: set GITHUB_BASE_REF or pass a base branch as the first argument.");
|
|
11339
11434
|
process.exit(2);
|
|
11340
11435
|
}
|
|
11341
|
-
await
|
|
11342
|
-
const { stdout } = await
|
|
11436
|
+
await execa13("git", ["fetch", "--quiet", "origin", base], { cwd: root, reject: false });
|
|
11437
|
+
const { stdout } = await execa13("git", ["diff", "--name-status", `origin/${base}...HEAD`], {
|
|
11343
11438
|
cwd: root
|
|
11344
11439
|
});
|
|
11345
11440
|
({ changed: changedFiles, deleted: deletedFiles } = parseNameStatus(stdout));
|
|
11346
|
-
const { stdout: log2 } = await
|
|
11441
|
+
const { stdout: log2 } = await execa13("git", ["log", "--format=%B", `origin/${base}..HEAD`], {
|
|
11347
11442
|
cwd: root,
|
|
11348
11443
|
reject: false
|
|
11349
11444
|
});
|
|
11350
11445
|
commitMessage = log2;
|
|
11351
11446
|
}
|
|
11352
|
-
const { stdout: gitBranch } = await
|
|
11447
|
+
const { stdout: gitBranch } = await execa13("git", ["rev-parse", "--abbrev-ref", "HEAD"], {
|
|
11353
11448
|
cwd: root,
|
|
11354
11449
|
reject: false
|
|
11355
11450
|
});
|
|
@@ -11431,7 +11526,7 @@ ${BOLD}If the divergence is deliberate${OFF}
|
|
|
11431
11526
|
}
|
|
11432
11527
|
|
|
11433
11528
|
// src/scripts/check-eventbridge-log-permissions.ts
|
|
11434
|
-
import { execa as
|
|
11529
|
+
import { execa as execa14 } from "execa";
|
|
11435
11530
|
|
|
11436
11531
|
// src/lib/eventbridge-log-permission-guard.ts
|
|
11437
11532
|
import { readFileSync as readFileSync32, readdirSync as readdirSync19, statSync as statSync12 } from "fs";
|
|
@@ -11608,7 +11703,7 @@ function auditEventBridgeLogPermissions(root) {
|
|
|
11608
11703
|
|
|
11609
11704
|
// src/scripts/check-eventbridge-log-permissions.ts
|
|
11610
11705
|
async function runEventBridgeLogPermissionCheck() {
|
|
11611
|
-
const root = (await
|
|
11706
|
+
const root = (await execa14("git", ["rev-parse", "--show-toplevel"])).stdout.trim();
|
|
11612
11707
|
let report;
|
|
11613
11708
|
try {
|
|
11614
11709
|
report = auditEventBridgeLogPermissions(root);
|
|
@@ -11645,7 +11740,7 @@ async function runEventBridgeLogPermissionCheck() {
|
|
|
11645
11740
|
}
|
|
11646
11741
|
|
|
11647
11742
|
// src/scripts/check-lambda-output.ts
|
|
11648
|
-
import { execa as
|
|
11743
|
+
import { execa as execa15 } from "execa";
|
|
11649
11744
|
|
|
11650
11745
|
// src/lib/lambda-output-guard.ts
|
|
11651
11746
|
import { readFileSync as readFileSync34 } from "fs";
|
|
@@ -11807,7 +11902,7 @@ function checkLambdaOutput(repoRoot) {
|
|
|
11807
11902
|
|
|
11808
11903
|
// src/scripts/check-lambda-output.ts
|
|
11809
11904
|
async function runLambdaOutputCheck() {
|
|
11810
|
-
const root = (await
|
|
11905
|
+
const root = (await execa15("git", ["rev-parse", "--show-toplevel"])).stdout.trim();
|
|
11811
11906
|
const files = findWorkflowFiles(root);
|
|
11812
11907
|
console.log(`audited ${files.length} workflow file(s) under ${root}`);
|
|
11813
11908
|
if (files.length === 0) {
|
|
@@ -11831,7 +11926,7 @@ async function runLambdaOutputCheck() {
|
|
|
11831
11926
|
// src/scripts/check-pipe-trap.ts
|
|
11832
11927
|
import { readFileSync as readFileSync35, readdirSync as readdirSync21 } from "fs";
|
|
11833
11928
|
import { join as join48, relative as relative9 } from "path";
|
|
11834
|
-
import { execa as
|
|
11929
|
+
import { execa as execa16 } from "execa";
|
|
11835
11930
|
|
|
11836
11931
|
// src/lib/pipe-trap-guard.ts
|
|
11837
11932
|
var STATUS_BEARING = [
|
|
@@ -11943,7 +12038,7 @@ function shellFiles(root) {
|
|
|
11943
12038
|
return out;
|
|
11944
12039
|
}
|
|
11945
12040
|
async function runPipeTrapCheck() {
|
|
11946
|
-
const root = (await
|
|
12041
|
+
const root = (await execa16("git", ["rev-parse", "--show-toplevel"])).stdout.trim();
|
|
11947
12042
|
const files = shellFiles(root);
|
|
11948
12043
|
console.log(`audited ${files.length} shell file(s) under scripts/ and .githooks/ under ${root}`);
|
|
11949
12044
|
if (files.length === 0) {
|
|
@@ -11970,7 +12065,7 @@ async function runPipeTrapCheck() {
|
|
|
11970
12065
|
}
|
|
11971
12066
|
|
|
11972
12067
|
// src/scripts/check-plugin-allowlist-convention.ts
|
|
11973
|
-
import { execa as
|
|
12068
|
+
import { execa as execa17 } from "execa";
|
|
11974
12069
|
|
|
11975
12070
|
// src/lib/plugin-allowlist-convention.ts
|
|
11976
12071
|
import { readFileSync as readFileSync36 } from "fs";
|
|
@@ -12081,7 +12176,7 @@ Plugins would be rejected by require_service_principal (ADR-0009). Fix the glob,
|
|
|
12081
12176
|
|
|
12082
12177
|
// src/scripts/check-plugin-allowlist-convention.ts
|
|
12083
12178
|
async function runPluginAllowlistConventionCheck() {
|
|
12084
|
-
const root = (await
|
|
12179
|
+
const root = (await execa17("git", ["rev-parse", "--show-toplevel"])).stdout.trim();
|
|
12085
12180
|
let violations;
|
|
12086
12181
|
try {
|
|
12087
12182
|
violations = checkAllowlistConvention(root);
|
|
@@ -12108,7 +12203,7 @@ async function runPluginAllowlistConventionCheck() {
|
|
|
12108
12203
|
// src/scripts/check-plugin-collisions.ts
|
|
12109
12204
|
import { existsSync as existsSync43 } from "fs";
|
|
12110
12205
|
import { join as join51 } from "path";
|
|
12111
|
-
import { execa as
|
|
12206
|
+
import { execa as execa18 } from "execa";
|
|
12112
12207
|
|
|
12113
12208
|
// src/lib/plugin-collision-guard.ts
|
|
12114
12209
|
import { existsSync as existsSync42, readdirSync as readdirSync22, statSync as statSync14 } from "fs";
|
|
@@ -12178,7 +12273,7 @@ function formatCollisions(collisions) {
|
|
|
12178
12273
|
|
|
12179
12274
|
// src/scripts/check-plugin-collisions.ts
|
|
12180
12275
|
async function runPluginCollisionCheck() {
|
|
12181
|
-
const root = (await
|
|
12276
|
+
const root = (await execa18("git", ["rev-parse", "--show-toplevel"])).stdout.trim();
|
|
12182
12277
|
const servicesDir = join51(root, "services");
|
|
12183
12278
|
if (!existsSync43(servicesDir)) {
|
|
12184
12279
|
console.log("\u2713 plugin collision guard: no services/ directory \u2014 nothing to compare");
|
|
@@ -12197,7 +12292,7 @@ async function runPluginCollisionCheck() {
|
|
|
12197
12292
|
}
|
|
12198
12293
|
|
|
12199
12294
|
// src/scripts/check-plugin-terraform.ts
|
|
12200
|
-
import { execa as
|
|
12295
|
+
import { execa as execa19 } from "execa";
|
|
12201
12296
|
|
|
12202
12297
|
// src/lib/plugin-terraform-guard.ts
|
|
12203
12298
|
import { existsSync as existsSync44, readFileSync as readFileSync37, readdirSync as readdirSync23 } from "fs";
|
|
@@ -12270,7 +12365,7 @@ function formatViolations(violations) {
|
|
|
12270
12365
|
|
|
12271
12366
|
// src/scripts/check-plugin-terraform.ts
|
|
12272
12367
|
async function runPluginTerraformCheck() {
|
|
12273
|
-
const root = (await
|
|
12368
|
+
const root = (await execa19("git", ["rev-parse", "--show-toplevel"])).stdout.trim();
|
|
12274
12369
|
const violations = checkPluginTerraform(root);
|
|
12275
12370
|
if (violations.length > 0) {
|
|
12276
12371
|
console.error("\u2717 plugin Terraform guard: event subscriptions with no infrastructure\n");
|
|
@@ -12283,7 +12378,7 @@ async function runPluginTerraformCheck() {
|
|
|
12283
12378
|
// src/scripts/check-plugin-tool-supply.ts
|
|
12284
12379
|
import { existsSync as existsSync46 } from "fs";
|
|
12285
12380
|
import { join as join54 } from "path";
|
|
12286
|
-
import { execa as
|
|
12381
|
+
import { execa as execa20 } from "execa";
|
|
12287
12382
|
|
|
12288
12383
|
// src/lib/plugin-tool-supply-audit.ts
|
|
12289
12384
|
import { existsSync as existsSync45, readFileSync as readFileSync38, readdirSync as readdirSync24, statSync as statSync15 } from "fs";
|
|
@@ -13235,7 +13330,7 @@ function auditPluginToolSupply(pluginsRoot) {
|
|
|
13235
13330
|
|
|
13236
13331
|
// src/scripts/check-plugin-tool-supply.ts
|
|
13237
13332
|
async function runPluginToolSupplyCheck() {
|
|
13238
|
-
const root = (await
|
|
13333
|
+
const root = (await execa20("git", ["rev-parse", "--show-toplevel"])).stdout.trim();
|
|
13239
13334
|
let allOk = true;
|
|
13240
13335
|
const pluginsRoot = join54(root, "services", "_plugins");
|
|
13241
13336
|
if (!existsSync46(pluginsRoot)) {
|
|
@@ -13315,7 +13410,7 @@ async function runPluginToolSupplyCheck() {
|
|
|
13315
13410
|
}
|
|
13316
13411
|
|
|
13317
13412
|
// src/scripts/check-release-subject.ts
|
|
13318
|
-
import { execa as
|
|
13413
|
+
import { execa as execa21 } from "execa";
|
|
13319
13414
|
|
|
13320
13415
|
// src/lib/release-version.ts
|
|
13321
13416
|
var MINOR_TYPES = /* @__PURE__ */ new Set(["feat"]);
|
|
@@ -13352,7 +13447,7 @@ async function fetchPrTitleViaGh({
|
|
|
13352
13447
|
PR_NUMBER,
|
|
13353
13448
|
GH_REPO
|
|
13354
13449
|
}) {
|
|
13355
|
-
const { stdout } = await
|
|
13450
|
+
const { stdout } = await execa21(
|
|
13356
13451
|
"gh",
|
|
13357
13452
|
["pr", "view", PR_NUMBER, "--repo", GH_REPO, "--json", "title", "--jq", ".title"],
|
|
13358
13453
|
{ env: { ...process.env, GH_TOKEN } }
|
|
@@ -13388,7 +13483,7 @@ async function resolveReleaseSubject({
|
|
|
13388
13483
|
);
|
|
13389
13484
|
}
|
|
13390
13485
|
}
|
|
13391
|
-
return (await
|
|
13486
|
+
return (await execa21("git", ["log", "-1", "--format=%s"], { cwd })).stdout.trim();
|
|
13392
13487
|
}
|
|
13393
13488
|
async function runReleaseSubjectCheck(argv) {
|
|
13394
13489
|
const base = process.env["GITHUB_BASE_REF"] ?? argv[0];
|
|
@@ -13396,9 +13491,9 @@ async function runReleaseSubjectCheck(argv) {
|
|
|
13396
13491
|
console.error("No base ref: set GITHUB_BASE_REF or pass a base branch as the first argument.");
|
|
13397
13492
|
process.exit(2);
|
|
13398
13493
|
}
|
|
13399
|
-
const root = (await
|
|
13400
|
-
await
|
|
13401
|
-
const { stdout } = await
|
|
13494
|
+
const root = (await execa21("git", ["rev-parse", "--show-toplevel"])).stdout.trim();
|
|
13495
|
+
await execa21("git", ["fetch", "--quiet", "origin", base], { cwd: root, reject: false });
|
|
13496
|
+
const { stdout } = await execa21("git", ["diff", "--name-only", `origin/${base}...HEAD`], {
|
|
13402
13497
|
cwd: root
|
|
13403
13498
|
});
|
|
13404
13499
|
const changedFiles = stdout.split("\n").map((s) => s.trim()).filter(Boolean);
|
|
@@ -13448,7 +13543,7 @@ async function runReleaseSubjectCheck(argv) {
|
|
|
13448
13543
|
// src/scripts/check-skeleton-drift.ts
|
|
13449
13544
|
import { existsSync as existsSync47, readdirSync as readdirSync26 } from "fs";
|
|
13450
13545
|
import { join as join56 } from "path";
|
|
13451
|
-
import { execa as
|
|
13546
|
+
import { execa as execa22 } from "execa";
|
|
13452
13547
|
|
|
13453
13548
|
// src/lib/skeleton-drift-guard.ts
|
|
13454
13549
|
import { readFileSync as readFileSync39, readdirSync as readdirSync25, statSync as statSync16 } from "fs";
|
|
@@ -13577,7 +13672,7 @@ function discoverSkeletons(root) {
|
|
|
13577
13672
|
return entries.filter((name) => existsSync47(join56(skeletonsDir, name, ".github", "workflows", "ci.yml"))).sort();
|
|
13578
13673
|
}
|
|
13579
13674
|
async function runSkeletonDriftCheck() {
|
|
13580
|
-
const root = (await
|
|
13675
|
+
const root = (await execa22("git", ["rev-parse", "--show-toplevel"])).stdout.trim();
|
|
13581
13676
|
const skeletons = discoverSkeletons(root);
|
|
13582
13677
|
let filesConsidered = 0;
|
|
13583
13678
|
for (const name of skeletons) {
|
|
@@ -13609,9 +13704,9 @@ async function runSkeletonDriftCheck() {
|
|
|
13609
13704
|
}
|
|
13610
13705
|
|
|
13611
13706
|
// src/scripts/check-terraform-input.ts
|
|
13612
|
-
import { execa as
|
|
13707
|
+
import { execa as execa23 } from "execa";
|
|
13613
13708
|
async function runTerraformInputCheck() {
|
|
13614
|
-
const root = (await
|
|
13709
|
+
const root = (await execa23("git", ["rev-parse", "--show-toplevel"])).stdout.trim();
|
|
13615
13710
|
const files = findWorkflowFiles(root);
|
|
13616
13711
|
console.log(`audited ${files.length} workflow file(s) under ${root}`);
|
|
13617
13712
|
if (files.length === 0) {
|