@rmartz/pr-policy 0.8.0 → 0.9.1
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.
package/dist/bin/pr-policy.js
CHANGED
|
@@ -892,10 +892,17 @@ function substantiveWorkflowChanges(changes) {
|
|
|
892
892
|
return changes.filter((change) => !isShippedReusableWorkflow(change) && !isPinBumpOnly(change)).map((change) => change.path);
|
|
893
893
|
}
|
|
894
894
|
|
|
895
|
+
// src/checks/test-paths.ts
|
|
896
|
+
var TEST_DIRS = /* @__PURE__ */ new Set(["test", "tests", "__tests__", "__snapshots__", "__mocks__", "e2e"]);
|
|
897
|
+
var TEST_FILE = /\.(test|spec)\.[cm]?[jt]sx?$|^test_.*\.py$|_test\.(py|go)$|^conftest\.py$/;
|
|
898
|
+
function isTestPath(path) {
|
|
899
|
+
const parts = path.split("/");
|
|
900
|
+
const name = parts.at(-1) ?? "";
|
|
901
|
+
return parts.slice(0, -1).some((dir) => TEST_DIRS.has(dir)) || TEST_FILE.test(name);
|
|
902
|
+
}
|
|
903
|
+
|
|
895
904
|
// src/checks/uat/trivial.ts
|
|
896
905
|
var TRIVIAL_CATEGORIES = ["docs", "tests", "ci", "dependencies", "metadata"];
|
|
897
|
-
var TEST_DIRS = /* @__PURE__ */ new Set(["test", "tests", "__tests__", "__snapshots__", "__mocks__", "e2e"]);
|
|
898
|
-
var TEST_FILE = /\.(test|spec)\.[cm]?[jt]sx?$|^test_.*\.py$|_test\.py$|^conftest\.py$/;
|
|
899
906
|
var LOCKFILES = /* @__PURE__ */ new Set([
|
|
900
907
|
"pnpm-lock.yaml",
|
|
901
908
|
"package-lock.json",
|
|
@@ -930,9 +937,8 @@ function isDependencyOnlyManifest(change) {
|
|
|
930
937
|
function categoryOf(path, pr) {
|
|
931
938
|
const parts = path.split("/");
|
|
932
939
|
const name = parts[parts.length - 1] ?? "";
|
|
933
|
-
const dirs = parts.slice(0, -1);
|
|
934
940
|
if (name.endsWith(".md") || parts[0] === "docs") return "docs";
|
|
935
|
-
if (
|
|
941
|
+
if (isTestPath(path)) return "tests";
|
|
936
942
|
if (path.startsWith(".github/workflows/") || path.startsWith(".github/actions/")) {
|
|
937
943
|
const change = pr.workflowChanges.find((file) => file.path === path);
|
|
938
944
|
return change !== void 0 && isShippedReusableWorkflow(change) ? void 0 : "ci";
|
|
@@ -1149,6 +1155,35 @@ function isReleasePleaseTitle(title) {
|
|
|
1149
1155
|
return RELEASE_PLEASE_TITLE.test(title);
|
|
1150
1156
|
}
|
|
1151
1157
|
|
|
1158
|
+
// src/checks/title/type-paths.ts
|
|
1159
|
+
function isMarkdownPath(path) {
|
|
1160
|
+
return path.toLowerCase().endsWith(".md");
|
|
1161
|
+
}
|
|
1162
|
+
var quote = (paths) => {
|
|
1163
|
+
const shown = paths.slice(0, 5).map((path) => `\`${path}\``);
|
|
1164
|
+
if (paths.length > 5) shown.push(`and ${paths.length - 5} more`);
|
|
1165
|
+
return shown.join(", ");
|
|
1166
|
+
};
|
|
1167
|
+
function typePathViolation(type, changedFiles) {
|
|
1168
|
+
const paths = [...new Set(changedFiles)];
|
|
1169
|
+
if (type === "docs") {
|
|
1170
|
+
const offending = paths.filter((path) => !isMarkdownPath(path));
|
|
1171
|
+
if (offending.length === 0) return void 0;
|
|
1172
|
+
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.`;
|
|
1173
|
+
}
|
|
1174
|
+
if (type === "refactor") {
|
|
1175
|
+
const offending = paths.filter((path) => isTestPath(path) && !isMarkdownPath(path));
|
|
1176
|
+
if (offending.length === 0) return void 0;
|
|
1177
|
+
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.`;
|
|
1178
|
+
}
|
|
1179
|
+
if (type === "test") {
|
|
1180
|
+
const offending = paths.filter((path) => !isTestPath(path) && !isMarkdownPath(path));
|
|
1181
|
+
if (offending.length === 0) return void 0;
|
|
1182
|
+
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.`;
|
|
1183
|
+
}
|
|
1184
|
+
return void 0;
|
|
1185
|
+
}
|
|
1186
|
+
|
|
1152
1187
|
// src/checks/title/index.ts
|
|
1153
1188
|
var TITLE_CHECK = "title";
|
|
1154
1189
|
var FUNCTIONAL = FUNCTIONAL_TYPES.map((type) => `\`${type}\``).join("/");
|
|
@@ -1202,6 +1237,8 @@ function decideTitle(pr) {
|
|
|
1202
1237
|
)
|
|
1203
1238
|
);
|
|
1204
1239
|
}
|
|
1240
|
+
const pathViolation = typePathViolation(title.type, pr.changedFiles);
|
|
1241
|
+
if (pathViolation !== void 0) findings.push(block2(pathViolation));
|
|
1205
1242
|
const mayRetitle = !functional && title.type !== "ci";
|
|
1206
1243
|
const workflows = substantiveWorkflowChanges(pr.workflowChanges);
|
|
1207
1244
|
if (workflows.length > 0 && mayRetitle) {
|
package/dist/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rmartz/pr-policy",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.1",
|
|
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",
|