@biffo/cli 0.238.3 → 0.240.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/_skeletons/plugin-template/scripts/biffo.sh +13 -0
- package/_skeletons/sibling-template/scripts/biffo.sh +13 -0
- package/dist/index.js +10 -1
- package/package.json +3 -2
- package/_skeletons/sibling-template/scripts/gate-coverage.sh +0 -131
- /package/{_skeletons/plugin-template/scripts → scripts}/gate-coverage.sh +0 -0
|
@@ -35,6 +35,19 @@
|
|
|
35
35
|
set -eu
|
|
36
36
|
|
|
37
37
|
root=$(git rev-parse --show-toplevel)
|
|
38
|
+
|
|
39
|
+
# Where the CALLER stood, before this script normalises to the repo root.
|
|
40
|
+
#
|
|
41
|
+
# Some packaged scripts take their target from the working directory rather than
|
|
42
|
+
# from a repo layout -- the dependency audits are invoked from a CI job's
|
|
43
|
+
# `working-directory: apps/frontend`, and one byte-identical script is correct
|
|
44
|
+
# at a repo root, in a sibling's frontend and in a service directory alike. The
|
|
45
|
+
# `cd` below would silently retarget them at the repo root, which is a wrong
|
|
46
|
+
# ANSWER rather than an error: the audit would pass, having audited the wrong
|
|
47
|
+
# tree. packagedScriptCommand() spawns each script back in this directory.
|
|
48
|
+
BIFFO_ORIGINAL_CWD=$PWD
|
|
49
|
+
export BIFFO_ORIGINAL_CWD
|
|
50
|
+
|
|
38
51
|
cd "$root"
|
|
39
52
|
|
|
40
53
|
# Satellites (sibling apps, plugin repos, runner fleets) carry neither
|
|
@@ -35,6 +35,19 @@
|
|
|
35
35
|
set -eu
|
|
36
36
|
|
|
37
37
|
root=$(git rev-parse --show-toplevel)
|
|
38
|
+
|
|
39
|
+
# Where the CALLER stood, before this script normalises to the repo root.
|
|
40
|
+
#
|
|
41
|
+
# Some packaged scripts take their target from the working directory rather than
|
|
42
|
+
# from a repo layout -- the dependency audits are invoked from a CI job's
|
|
43
|
+
# `working-directory: apps/frontend`, and one byte-identical script is correct
|
|
44
|
+
# at a repo root, in a sibling's frontend and in a service directory alike. The
|
|
45
|
+
# `cd` below would silently retarget them at the repo root, which is a wrong
|
|
46
|
+
# ANSWER rather than an error: the audit would pass, having audited the wrong
|
|
47
|
+
# tree. packagedScriptCommand() spawns each script back in this directory.
|
|
48
|
+
BIFFO_ORIGINAL_CWD=$PWD
|
|
49
|
+
export BIFFO_ORIGINAL_CWD
|
|
50
|
+
|
|
38
51
|
cd "$root"
|
|
39
52
|
|
|
40
53
|
# Satellites (sibling apps, plugin repos, runner fleets) carry neither
|
package/dist/index.js
CHANGED
|
@@ -10808,7 +10808,8 @@ function packagedScriptCommand(spec) {
|
|
|
10808
10808
|
}
|
|
10809
10809
|
const at = process.argv.indexOf(spec.name);
|
|
10810
10810
|
const args = at === -1 ? [] : process.argv.slice(at + 1);
|
|
10811
|
-
const
|
|
10811
|
+
const cwd = process.env["BIFFO_ORIGINAL_CWD"] || process.cwd();
|
|
10812
|
+
const result = spawnSync("sh", [script, ...args], { stdio: "inherit", cwd });
|
|
10812
10813
|
process.exit(result.status === null ? 2 : result.status);
|
|
10813
10814
|
});
|
|
10814
10815
|
}
|
|
@@ -10834,6 +10835,13 @@ var rewriteScopeCheckCommand = packagedScriptCommand({
|
|
|
10834
10835
|
description: "Refuse a push whose rewrite scope absorbs merged work from another branch"
|
|
10835
10836
|
});
|
|
10836
10837
|
|
|
10838
|
+
// src/commands/gate-coverage.ts
|
|
10839
|
+
var gateCoverageCommand = packagedScriptCommand({
|
|
10840
|
+
name: "gate-coverage",
|
|
10841
|
+
script: "scripts/gate-coverage.sh",
|
|
10842
|
+
description: "Report how much of CI the local gate actually mirrors"
|
|
10843
|
+
});
|
|
10844
|
+
|
|
10837
10845
|
// src/commands/branch-health.ts
|
|
10838
10846
|
var branchHealthCommand = packagedScriptCommand({
|
|
10839
10847
|
name: "branch-health",
|
|
@@ -10873,6 +10881,7 @@ program.addCommand(teardownCommand);
|
|
|
10873
10881
|
program.addCommand(waitForChecksCommand);
|
|
10874
10882
|
program.addCommand(branchHealthCommand);
|
|
10875
10883
|
program.addCommand(claimCommand);
|
|
10884
|
+
program.addCommand(gateCoverageCommand);
|
|
10876
10885
|
program.addCommand(hookAuditCommand);
|
|
10877
10886
|
program.addCommand(pgTestDbCommand);
|
|
10878
10887
|
program.addCommand(rewriteScopeCheckCommand);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@biffo/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.240.0",
|
|
4
4
|
"description": "Biffo project scaffolding CLI",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -29,7 +29,8 @@
|
|
|
29
29
|
"scripts/claim.sh",
|
|
30
30
|
"scripts/hook-audit.sh",
|
|
31
31
|
"scripts/pg-test-db.sh",
|
|
32
|
-
"scripts/rewrite-scope-check.sh"
|
|
32
|
+
"scripts/rewrite-scope-check.sh",
|
|
33
|
+
"scripts/gate-coverage.sh"
|
|
33
34
|
],
|
|
34
35
|
"scripts": {
|
|
35
36
|
"build": "tsup src/index.ts --format esm --dts --clean",
|
|
@@ -1,131 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bash
|
|
2
|
-
#
|
|
3
|
-
# Does each repo's local gate actually cover that repo's CI?
|
|
4
|
-
#
|
|
5
|
-
# ## Why this exists
|
|
6
|
-
#
|
|
7
|
-
# `hook-audit.sh` answers "will a hook execute here". That question hit 100%
|
|
8
|
-
# across the estate on 2026-07-29 while eight repos had a gate that checked
|
|
9
|
-
# **nothing they were written in** — `tabsii-crm` ran one check, terraform-fmt,
|
|
10
|
-
# on a 700-line TypeScript-and-Python change, and printed `verify passed`.
|
|
11
|
-
#
|
|
12
|
-
# Arming was a proxy and it was reported as the outcome. This is the metric that
|
|
13
|
-
# can actually fail: for every repo, the set of check *kinds* its CI runs, minus
|
|
14
|
-
# the ones deliberately excluded, must be covered by the set its gate runs.
|
|
15
|
-
#
|
|
16
|
-
# The parity test in `cli/src/lib/verify-parity.test.ts` compares the gate to CI
|
|
17
|
-
# too — but it runs only in `biffo-template`, the single repo with both a root
|
|
18
|
-
# `package.json` and a root `pyproject.toml`, i.e. the one place the root-only
|
|
19
|
-
# assumption held. It validated the gate where the gate was already correct.
|
|
20
|
-
# This runs everywhere, which is the whole point.
|
|
21
|
-
#
|
|
22
|
-
# Usage:
|
|
23
|
-
# sh scripts/gate-coverage.sh # this repo
|
|
24
|
-
# sh scripts/gate-coverage.sh --estate ~/code # every repo under a directory
|
|
25
|
-
#
|
|
26
|
-
# Exits non-zero if any repo's gate misses a check kind its CI runs.
|
|
27
|
-
|
|
28
|
-
set -uo pipefail
|
|
29
|
-
|
|
30
|
-
ESTATE=""
|
|
31
|
-
[ "${1:-}" = "--estate" ] && ESTATE="${2:-}"
|
|
32
|
-
|
|
33
|
-
# Deliberately excluded from local gates, with the reason. Kept in step with
|
|
34
|
-
# verify-parity.test.ts. An exclusion here must describe what the CI step
|
|
35
|
-
# actually DOES, not what it was assumed to do — the bandit exclusion claimed
|
|
36
|
-
# "the finding gate is the upload step" when `bandit -ll` exits non-zero and it
|
|
37
|
-
# is the run step that fails (#855).
|
|
38
|
-
EXCLUDED_KINDS="pytest build audit gitleaks codeql e2e playwright release-subject ownership"
|
|
39
|
-
|
|
40
|
-
# Reduce a command to the KIND of check it is. Comparing raw command strings is
|
|
41
|
-
# hopeless across repos — CI uses `working-directory:` where the gate uses
|
|
42
|
-
# `--dir` — and what matters is "does a lint run locally where CI runs a lint".
|
|
43
|
-
kind_of() {
|
|
44
|
-
case "$1" in
|
|
45
|
-
*"run lint"*) echo lint ;;
|
|
46
|
-
*"run typecheck"*) echo typecheck ;;
|
|
47
|
-
*"run format:check"*) echo format ;;
|
|
48
|
-
*"run e2e"*) echo e2e ;;
|
|
49
|
-
*"run build"*|*"portal build"*) echo build ;;
|
|
50
|
-
*"run test"*) echo test ;;
|
|
51
|
-
*"ruff check"*) echo ruff-check ;;
|
|
52
|
-
*"ruff format"*) echo ruff-format ;;
|
|
53
|
-
*pyright*) echo pyright ;;
|
|
54
|
-
*pytest*) echo pytest ;;
|
|
55
|
-
*bandit*) echo bandit ;;
|
|
56
|
-
*"terraform fmt"*) echo terraform-fmt ;;
|
|
57
|
-
*playwright*) echo playwright ;;
|
|
58
|
-
*"dependency-audit"*|*"pnpm audit"*|*"pip-audit"*) echo audit ;;
|
|
59
|
-
*gitleaks*) echo gitleaks ;;
|
|
60
|
-
*"check release-subject"*) echo release-subject ;;
|
|
61
|
-
*"check ownership"*) echo ownership ;;
|
|
62
|
-
*"check plugin-terraform"*) echo plugin-terraform ;;
|
|
63
|
-
*"check plugin-collisions"*) echo plugin-collisions ;;
|
|
64
|
-
*install*|*"uv sync"*) echo "" ;;
|
|
65
|
-
*) echo "" ;;
|
|
66
|
-
esac
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
kinds_from_ci() {
|
|
70
|
-
d="$1"
|
|
71
|
-
f="$d/.github/workflows/ci.yml"
|
|
72
|
-
[ -f "$f" ] || return 0
|
|
73
|
-
grep -hoE "run: (pnpm|uv|terraform|sh scripts/)[^\"']*" "$f" 2>/dev/null |
|
|
74
|
-
sed 's/^run: //' | while read -r cmd; do kind_of "$cmd"; done | grep -v '^$' | sort -u
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
kinds_from_gate() {
|
|
78
|
-
d="$1"
|
|
79
|
-
[ -f "$d/scripts/verify.sh" ] || return 0
|
|
80
|
-
(cd "$d" && sh scripts/verify.sh --list 2>/dev/null) |
|
|
81
|
-
while read -r cmd; do kind_of "$cmd"; done | grep -v '^$' | sort -u
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
failed=0
|
|
85
|
-
report() {
|
|
86
|
-
d="$1"
|
|
87
|
-
label="$2"
|
|
88
|
-
if [ ! -f "$d/scripts/verify.sh" ]; then
|
|
89
|
-
printf '%-26s \033[33mNO GATE\033[0m\n' "$label"
|
|
90
|
-
return
|
|
91
|
-
fi
|
|
92
|
-
ci=$(kinds_from_ci "$d")
|
|
93
|
-
gate=$(kinds_from_gate "$d")
|
|
94
|
-
if [ -z "$ci" ]; then
|
|
95
|
-
printf '%-26s \033[90mno CI to mirror\033[0m (gate runs %s)\n' "$label" "$(echo "$gate" | grep -cv '^$')"
|
|
96
|
-
return
|
|
97
|
-
fi
|
|
98
|
-
missing=""
|
|
99
|
-
total=0
|
|
100
|
-
covered=0
|
|
101
|
-
for k in $ci; do
|
|
102
|
-
case " $EXCLUDED_KINDS " in *" $k "*) continue ;; esac
|
|
103
|
-
total=$((total + 1))
|
|
104
|
-
if echo "$gate" | grep -qx "$k"; then covered=$((covered + 1)); else missing="$missing $k"; fi
|
|
105
|
-
done
|
|
106
|
-
if [ -n "$missing" ]; then
|
|
107
|
-
failed=1
|
|
108
|
-
printf '%-26s \033[31m%s/%s\033[0m missing:%s\n' "$label" "$covered" "$total" "$missing"
|
|
109
|
-
else
|
|
110
|
-
printf '%-26s \033[32m%s/%s\033[0m\n' "$label" "$covered" "$total"
|
|
111
|
-
fi
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
printf '\ngate coverage - CI check kinds mirrored by the local gate\n\n'
|
|
115
|
-
if [ -n "$ESTATE" ]; then
|
|
116
|
-
for d in "$ESTATE"/*/; do
|
|
117
|
-
[ -e "$d/.git" ] || continue
|
|
118
|
-
report "${d%/}" "$(basename "${d%/}")"
|
|
119
|
-
done
|
|
120
|
-
else
|
|
121
|
-
root=$(git rev-parse --show-toplevel 2>/dev/null) || { echo "not a git repo" >&2; exit 2; }
|
|
122
|
-
report "$root" "$(basename "$root")"
|
|
123
|
-
fi
|
|
124
|
-
|
|
125
|
-
printf '\n'
|
|
126
|
-
if [ "$failed" -ne 0 ]; then
|
|
127
|
-
printf '\033[31mSome gates do not cover their own CI.\033[0m A gate that misses the language a\n'
|
|
128
|
-
printf 'change is written in reports `verify passed` on work it never checked.\n\n'
|
|
129
|
-
exit 1
|
|
130
|
-
fi
|
|
131
|
-
printf '\033[32mEvery gate covers its own CI.\033[0m\n\n'
|
|
File without changes
|