diff --git a/.github/workflows/governance-enforce.yml b/.github/workflows/governance-enforce.yml index e68aef6..bb54162 100644 --- a/.github/workflows/governance-enforce.yml +++ b/.github/workflows/governance-enforce.yml @@ -7,6 +7,7 @@ name: governance-enforce on: pull_request: + merge_group: push: branches: [main, master] @@ -35,15 +36,29 @@ jobs: run: | mkdir -p "$RUNNER_TEMP/gov" && cd "$RUNNER_TEMP/gov" printf '@wave-av:registry=https://npm.pkg.github.com\n//npm.pkg.github.com/:_authToken=${NODE_AUTH_TOKEN}\n' > .npmrc - npm install @wave-av/governance@^0.4.4 --no-save --no-audit --no-fund + # Floor is 0.4.6, not 0.4.4: the published 0.4.4/0.4.5 diff lister fails OPEN (any git + # error, including a tree-object base, yields "0 changed file(s) scanned" and exit 0). + # 0.4.6 diffs two-dot (`git diff HEAD`, which accepts the empty-tree object the + # indeterminate-base fallback supplies) and fails closed on any git listing error. + npm install @wave-av/governance@^0.4.6 --no-save --no-audit --no-fund - name: A_BLOCK enforce (secrets + hardcoded paths on the diff) env: PR_BASE_SHA: ${{ github.event.pull_request.base.sha }} + MERGE_BASE_SHA: ${{ github.event.merge_group.base_sha }} PUSH_BEFORE_SHA: ${{ github.event.before }} run: | - BASE="${PR_BASE_SHA:-$PUSH_BEFORE_SHA}" - if [ -z "$BASE" ] || [ "$BASE" = "0000000000000000000000000000000000000000" ]; then - BASE=$(git rev-parse HEAD~1 2>/dev/null || git rev-parse HEAD) + BASE="${PR_BASE_SHA:-${MERGE_BASE_SHA:-$PUSH_BEFORE_SHA}}" + if [ -z "$BASE" ] || [ "$BASE" = "0000000000000000000000000000000000000000" ] \ + || ! git cat-file -e "$BASE^{commit}" 2>/dev/null; then + # Indeterminate base: first push (before-SHA is all zeros) or force-push (before-SHA is + # the orphaned old tip, which the clone cannot resolve — hence the cat-file guard; the + # fail-closed enforcer would otherwise hard-fail on a raw git error). Do NOT silently + # scan a partial range — HEAD~1 would skip earlier commits in a multi-commit push and + # let a violation through (a config-no-silent-noop hole). Diff the full tree against + # git's empty-tree object so every introduced file is scanned; loud, never a silent + # empty/partial pass. + BASE=$(git hash-object -t tree /dev/null) + echo "::warning::indeterminate diff base; scanning full tree (empty-tree base) so no commit is skipped" fi echo "diffing against $BASE" node "$RUNNER_TEMP/gov/node_modules/@wave-av/governance/bin/enforce.mjs" --changed "$BASE"