Add markdown-exclude-globs Input to validate-task.yml - #935
Conversation
validate-task.yml's Lint Markdown step hardcoded '**/*.md' with no workflow_call input to narrow it, and .markdownlint-cli2.jsonc is verbatim/whole per spec/files.json, so a repo that vendors a theme or imports content it does not author (Blog's PaperMod theme and WordPress archive) had no way to keep the gate from linting prose it cannot fix. Adds an optional markdown-exclude-globs input, appended after '**/*.md' in the globs: block. Empty by default: the action's own globs.split(separator).filter(String) drops the resulting blank line, verified locally against markdownlint-cli2-action's dist source and against a live run. Fixes #924 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|
Warning Review limit reached
Next review available in: 15 minutes Limit details: You’ve used all 10 included reviews currently available. Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?Wait for the limit to reset, then comment An organization admin can change what happens after included review limits in Billing. How do review limits work?CodeRabbit enforces per-developer PR review limits within each organization. For paid Pro and Pro+ reviews, CodeRabbit uses a developer's included PR review attempts over the past 7 days to set the current hourly allowance. At typical activity levels, the full plan allowance applies. Higher sustained activity can lower the allowance until earlier attempts leave the 7-day window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Plus Run ID: 📒 Files selected for processing (2)
Comment |
PR Summary by QodoAdd markdown-exclude-globs input to validate-task markdown lint
AI Description
Diagram
High-Level Assessment
Files changed (2)
|
There was a problem hiding this comment.
🟡 Changes recommended
The new input is documented/commented as “only ever narrowing” the default, but callers can append arbitrary non-negated globs and thereby expand what gets linted, so the contract text should be corrected for accuracy.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Pull request overview
Adds a workflow_call input to the hub’s reusable validation workflow so downstream repos can exclude tracked-but-not-authored Markdown trees (e.g., vendored themes or imported archives) from the markdownlint gate, and documents the adoption pattern.
Changes:
- Add optional
markdown-exclude-globsinput to.github/workflows/validate-task.ymland append it to the markdownlintglobs:list after**/*.md. - Document the new input and an example use case in
docs/reusable-workflows.md.
File summaries
| File | Description |
|---|---|
| .github/workflows/validate-task.yml | Exposes a caller-provided markdownlint glob exclusion hook via workflow_call input. |
| docs/reusable-workflows.md | Documents how downstream repos can use markdown-exclude-globs when adopting the validate task. |
Review details
- Files reviewed: 2/2 changed files
- Comments generated: 2
- Review effort level: Lite
💡 Configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Code Review by Qodo
1.
|
Copilot review, confirmed on both threads: the input and doc wording said a caller 'only ever narrows' the default glob, but the mechanism is unvalidated string concatenation, so a non-negated line adds to what is linted instead of excluding it. Reworded the input description and the doc prose to state that plainly rather than the narrower, inaccurate claim. Also trims the input's own comment to one line per the repository's default. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
There was a problem hiding this comment.
🟢 Approval recommended
The change is small, scoped, and matches the stated intent; the only finding is a minor comment-accuracy improvement.
Review details
Suppressed comments (1)
Previously missed (1) — in code that hasn't changed since the last review.
.github/workflows/validate-task.yml:39
- The comment relies on a specific implementation detail (
globs.split(...).filter(String)) that doesn’t match the action’s current parsing (it trims entries and filters truthy values). Prefer describing the observable behavior (blank/whitespace-only lines are ignored), so the comment stays correct even if the action’s internal code changes while behavior remains the same.
# An empty markdown-exclude-globs leaves a blank line here, which the action's own globs.split(separator).filter(String) drops, so the default caller passes nothing extra.
- Files reviewed: 2/2 changed files
- Comments generated: 0 new
- Review effort level: Lite
A suppressed CodeRabbit finding on the pushed diff: the comment named the action's internal split/filter call chain rather than the behavior a reader actually needs, blank lines are ignored, which stays true even if the action's internals change. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
There was a problem hiding this comment.
🟢 Approval recommended
The new optional input is correctly plumbed through without changing default behavior, and the documentation matches the implementation.
Review details
- Files reviewed: 2/2 changed files
- Comments generated: 0 new
- Review effort level: Lite
#958) Fixes #957. `repo_gate.py`'s `tracked()` read every git-tracked path with no way for a caller to narrow it, so `sha-pin` and `eol-coverage` (both of which read that list) had no per-repo exclusion point. Blog vendors the PaperMod theme under `themes/PaperMod/` as plain tracked files, byte-identical to upstream per `themes/README.md`'s documented invariant, and PaperMod's own CI workflows pin actions by floating tag, which Blog does not author and does not locally edit. Adopting the hub's `validate-task.yml` therefore fails `sha-pin` on all 5 of PaperMod's own pins every run, with no way to scope them out without breaking the byte-identical invariant. ## The fix The same shape `markdown-exclude-globs` (#935) already established for the Lint Markdown step, applied to the repo gate: - `repo_gate.py`: `tracked()` takes an optional `exclude` list, turned into `:!<pattern>` pathspecs appended to `git ls-files` after `--`. The CLI gained a repeatable `--exclude PATTERN` argument, and `main()` prints a note naming what was excluded, since a check that quietly scans less than its own docstring claims is exactly the silent narrowing this script's own `NOTES` convention exists to surface. - `.github/actions/repo-gate/action.yml`: a new `exclude-globs` input, newline-separated, turned into repeated `--exclude` arguments by the composite step's own shell before invoking `repo_gate.py`. - `.github/workflows/validate-task.yml`: a new `repo-gate-exclude-globs` `workflow_call` input, threaded straight through to the action's `exclude-globs`. Empty by default, so the default caller excludes nothing. - `docs/reusable-workflows.md` "Adopting the Gates": documents the new input with Blog's own PaperMod case, the same way the markdown section above it documents `markdown-exclude-globs`. Unlike `markdown-exclude-globs`, a line here is never negated: it is always a pathspec to drop, so `themes/PaperMod/**` excludes rather than `!themes/PaperMod/**`. ## Verified Added `TestExcludeGlobs` (a fresh git repo per case, so the exclude is proven against a real subtree rather than one this repo happens to carry) and a repo-level floor test excluding this repo's own two `workflows/*.yml`-matching directories down to zero. Exercised the composite action's own shell logic directly for both the multi-pattern and empty-input cases. Ran `--exclude` against this checkout directly, confirming `sha-pin` resolves 0 pins once every workflow directory is excluded. Full test suite (804 tests), ruff check and format, mypy, `repo_gate.py` against this checkout, `prose_lint.py --diff origin/develop`, and `docker_lint.py` (actionlint, markdownlint, editorconfig-checker) all pass clean. 🤖 Generated with [Claude Code](https://claude.com/claude-code) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added optional path exclusions for repository validation scans. * Supports multiple newline-separated patterns for excluding selected files or directories. * Workflows can pass exclusion patterns to repository checks. * Reports when exclusions narrow scans or match no files. * **Documentation** * Documented exclusion formatting and scanning behavior. * **Bug Fixes** * Improved handling and reporting of repository scan errors. * Supports repositories containing vendored or otherwise exempt content. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
Fixes #924.
validate-task.yml's Lint Markdown step hardcodedglobs: '**/*.md'with noworkflow_callinput to narrow or exclude paths, and.markdownlint-cli2.jsoncis declared"fidelity": "verbatim", "whole": trueinspec/files.json, so a downstream repo has no way to edit it locally either. Blog vendors the PaperMod theme underthemes/PaperMod/and carries an imported WordPress content archive undercontent/**, both git-tracked, so adopting the hub'svalidate-task.ymlas documented would start linting several hundred posts and an entire vendored theme tree Blog does not author and cannot keep clean, breaking the PR gate rather than improving it.The fix
An optional
markdown-exclude-globsinput, appended after**/*.mdin the Lint Markdown step's ownglobs:block, so a caller only ever narrows the default, never restates or replaces it:Empty by default. Verified this doesn't error against the action's own source (
DavidAnson/markdownlint-cli2-action'sdist/index.mjsat the pinned SHA):getInput("globs").split(separator).filter(String), so the blank line an empty input leaves behind is dropped, not passed to the CLI as an empty glob. Confirmed with a local test fixture too: without the exclude globs,content/**andthemes/**files are linted (and fail); with them, only the caller's own files are.docs/reusable-workflows.md's "Adopting the Gates" section documents the new input with Blog's own case as the example.🤖 Generated with Claude Code