@rmartz/pr-policy 0.8.0 → 0.9.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.
@@ -7,7 +7,7 @@ import {
7
7
  postVerdict,
8
8
  resolveRepoTarget,
9
9
  selectChecks
10
- } from "../chunk-5VYRZAUT.js";
10
+ } from "../chunk-PVXDVMME.js";
11
11
 
12
12
  // src/bin/pr-policy.ts
13
13
  import { readFile } from "fs/promises";
@@ -1149,6 +1149,42 @@ function isReleasePleaseTitle(title) {
1149
1149
  return RELEASE_PLEASE_TITLE.test(title);
1150
1150
  }
1151
1151
 
1152
+ // src/checks/title/type-paths.ts
1153
+ var TEST_DIRS2 = /* @__PURE__ */ new Set(["test", "tests", "__tests__"]);
1154
+ var TEST_FILE2 = /\.(test|spec)\.[^/]+$|^test_[^/]*\.py$|_test\.(py|go)$/;
1155
+ function isMarkdownPath(path) {
1156
+ return path.toLowerCase().endsWith(".md");
1157
+ }
1158
+ function isTestPath(path) {
1159
+ const parts = path.split("/");
1160
+ const name = parts.at(-1) ?? "";
1161
+ return parts.slice(0, -1).some((dir) => TEST_DIRS2.has(dir)) || TEST_FILE2.test(name);
1162
+ }
1163
+ var quote = (paths) => {
1164
+ const shown = paths.slice(0, 5).map((path) => `\`${path}\``);
1165
+ if (paths.length > 5) shown.push(`and ${paths.length - 5} more`);
1166
+ return shown.join(", ");
1167
+ };
1168
+ function typePathViolation(type, changedFiles) {
1169
+ const paths = [...new Set(changedFiles)];
1170
+ if (type === "docs") {
1171
+ const offending = paths.filter((path) => !isMarkdownPath(path));
1172
+ if (offending.length === 0) return void 0;
1173
+ return `A \`docs\` PR may change only Markdown files, but this one changes ${quote(offending)}. \`docs\` doesn't release, so that change would never ship. Retitle to the type of the non-docs change, or split it into its own PR.`;
1174
+ }
1175
+ if (type === "refactor") {
1176
+ const offending = paths.filter((path) => isTestPath(path) && !isMarkdownPath(path));
1177
+ if (offending.length === 0) return void 0;
1178
+ return `A \`refactor\` PR must leave the tests untouched, so they can confirm behaviour is unchanged, but this one changes ${quote(offending)}. Land the test changes first as a \`test:\` PR, then refactor against them.`;
1179
+ }
1180
+ if (type === "test") {
1181
+ const offending = paths.filter((path) => !isTestPath(path) && !isMarkdownPath(path));
1182
+ if (offending.length === 0) return void 0;
1183
+ return `A \`test\` PR may change only test files and docs, so it locks in current behaviour without changing it, but this one changes ${quote(offending)}. \`test\` doesn't release, so that change would never ship. Retitle to the type of the non-test change, or split it into its own PR.`;
1184
+ }
1185
+ return void 0;
1186
+ }
1187
+
1152
1188
  // src/checks/title/index.ts
1153
1189
  var TITLE_CHECK = "title";
1154
1190
  var FUNCTIONAL = FUNCTIONAL_TYPES.map((type) => `\`${type}\``).join("/");
@@ -1202,6 +1238,8 @@ function decideTitle(pr) {
1202
1238
  )
1203
1239
  );
1204
1240
  }
1241
+ const pathViolation = typePathViolation(title.type, pr.changedFiles);
1242
+ if (pathViolation !== void 0) findings.push(block2(pathViolation));
1205
1243
  const mayRetitle = !functional && title.type !== "ci";
1206
1244
  const workflows = substantiveWorkflowChanges(pr.workflowChanges);
1207
1245
  if (workflows.length > 0 && mayRetitle) {
package/dist/index.js CHANGED
@@ -48,7 +48,7 @@ import {
48
48
  sensitiveBumps,
49
49
  statusBody,
50
50
  titleCheck
51
- } from "./chunk-5VYRZAUT.js";
51
+ } from "./chunk-PVXDVMME.js";
52
52
  export {
53
53
  AMBIGUOUS_INDICATORS,
54
54
  BLOCKED_LABEL,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rmartz/pr-policy",
3
- "version": "0.8.0",
3
+ "version": "0.9.0",
4
4
  "description": "Read-only PR content classifiers — CI-change classification, title-type rules, and more — reported as one blocking pr-policy check-run. Distributed as a pinned Action kept current by Dependabot.",
5
5
  "keywords": [
6
6
  "pr-policy",