From 1645bb5ffd040174ba2fdea2a890c3d2b3aeb541 Mon Sep 17 00:00:00 2001 From: Tom Boucher Date: Mon, 18 May 2026 12:41:01 -0400 Subject: [PATCH] fix(ci): replace minimatch with path.matchesGlob in pr-template-policy (#3701) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Root cause: e50ad812 introduced `const { minimatch } = require('minimatch')` in scripts/pr-template-policy.cjs, but minimatch is not listed in package.json (neither dependencies nor devDependencies). The .github/workflows/pr-template-format.yml workflow checks out main via actions/checkout and runs the script directly with no `npm ci`/`npm install` step. Because the workflow uses `pull_request_target` + plain checkout (no `ref:`), every PR — including PRs that don't touch this file — invokes main's broken script and the `Pull request template format` check fails with `Cannot find module 'minimatch'`. This blocks every open PR's check. Fix choice: replace minimatch with Node's built-in `path.matchesGlob` (stable since Node 22, required engine is `>=22.0.0`). The only minimatch usage was `minimatch(file, pattern, { matchBase: false, dot: true })` in allPathsAreTooling, against simple glob patterns (`**`, `*`, `*.md`, `requirements*.txt`, etc.) with no extglobs, brace-expansion alternation, or negation. path.matchesGlob handles all required cases including dot files, so no new dependency is needed and no workflow change is required. Verified: all 25 existing tests in tests/pr-template-policy.test.cjs pass, including the tooling carve-out, exempt-marker, and template-detection suites. Direct script invocation with CHANGED_FILES=.github/workflows/... produces the expected `skipped: tooling-paths` carve-out. This unblocks every open PR's `Pull request template format` check. --- scripts/pr-template-policy.cjs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/pr-template-policy.cjs b/scripts/pr-template-policy.cjs index 59ce578e7..0e9222449 100644 --- a/scripts/pr-template-policy.cjs +++ b/scripts/pr-template-policy.cjs @@ -1,6 +1,6 @@ #!/usr/bin/env node -const { minimatch } = require('minimatch'); +const { matchesGlob } = require('path'); const TRUSTED_AUTHOR_ASSOCIATIONS = new Set([ 'CONTRIBUTOR', @@ -145,7 +145,7 @@ function matchingTemplate(body) { function allPathsAreTooling(changedFiles, allowlist) { if (!Array.isArray(changedFiles) || changedFiles.length === 0) return false; return changedFiles.every((file) => - allowlist.some((pattern) => minimatch(file, pattern, { matchBase: false, dot: true })), + allowlist.some((pattern) => matchesGlob(file, pattern)), ); }