Skip to content

repo-gate's sha-pin check scans vendored third-party workflow files with no per-repo exclusion #957

Description

@ptr727

Found while driving ptr727/Blog#99, adopting the hub's validate-task.yml per RESYNC.md's "Adopting the Gates" section (#924, #950 both landed already this same day).

The gap

validate-task.yml's lint job runs a "Check repo gates step" that resolves to $/.github/actions/repo-gate, which runs repo_gate.py with no arguments beyond --root. Its sha-pin check (the only one it runs by default) discovers targets with:

def tracked(root: Path) -> list[str]:
    out = sh("git", "-C", str(root), "ls-files")
    return [l for l in out.split("\n") if l]

def workflow_files(files: list[str]) -> list[str]:
    return [f for f in files if WORKFLOW.search(f)]

WORKFLOW matches workflows/.*\.ya?ml$ against every git-tracked path repo-wide, with no way for a caller to narrow it. The composite action itself (.github/actions/repo-gate/action.yml) takes zero inputs, and repo_gate.py main() accepts only --root and --check.

Blog's own validate-task.yml never carried this step (it predates the repo-gate action), so adopting the hub's version is what surfaces this for the first time.

Where this actually bites

Blog vendors the PaperMod theme under themes/PaperMod/, plain tracked files rather than a submodule, and themes/README.md documents a deliberate invariant: the vendored tree stays byte-identical to upstream, verified with diff -r --exclude=.git after every update, "Nothing is carried, so an update is a replace: delete PaperMod/, drop the new upstream tree in its place." PaperMod's own .github/workflows/build-check.yml and gh-pages.yml (its own CI, meaningless once vendored, never run by Blog) pin actions by floating tag (actions/checkout@v6, actions/configure-pages@v6, and others), which Blog does not author, does not control, and by its own documented policy does not locally edit. The sha-pin check fails on all 5 of them every run, and there is no way to exclude the vendored subtree without breaking the byte-identical invariant themes/README.md exists to keep verifiable.

This is the same defect shape as #924 (markdownlint) and #950 (shellcheck/shfmt): a hub-hosted check scans repo-wide with no per-repo exclusion point, and a repo that vendors third-party content it cannot edit has no way to satisfy it.

Ask

An optional workflow_call input on validate-task.yml (or a mechanism repo_gate.py itself takes) that narrows what sha-pin (and, for the same reason, eol/eol-coverage, which read the same tracked() list) scans, the same shape #950 added for the shell step's target discovery: a caller-supplied set of exclude globs appended to git ls-files's own pathspec, so git ls-files ':!themes/PaperMod/**'-equivalent scoping is possible from the caller stub without touching repo_gate.py's zero-argument composite action contract otherwise.

Blog's test-pull-request.yml/publish-release.yml/deploy-site.yml adoption (ptr727/Blog#99) is blocked on this for a green Lint sources job.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions