issue-flow 0.12.0 → 0.14.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.
- package/README.md +79 -274
- package/dist/agent-OX3KPHE4.js +30 -0
- package/dist/{analyze-OEET7KGE.js → analyze-WIND2SEB.js} +31 -16
- package/dist/analyze-WIND2SEB.js.map +1 -0
- package/dist/{apply-ZIA3C52S.js → apply-JNOI2LR4.js} +18 -7
- package/dist/{apply-ZIA3C52S.js.map → apply-JNOI2LR4.js.map} +1 -1
- package/dist/bench-B4VZON7E.js +910 -0
- package/dist/bench-B4VZON7E.js.map +1 -0
- package/dist/{chunk-FADTCQGM.js → chunk-2IQ6M4ZE.js} +94 -32
- package/dist/chunk-2IQ6M4ZE.js.map +1 -0
- package/dist/chunk-3BWZO4YI.js +141 -0
- package/dist/chunk-3BWZO4YI.js.map +1 -0
- package/dist/chunk-3WFZETIM.js +163 -0
- package/dist/chunk-3WFZETIM.js.map +1 -0
- package/dist/chunk-67YIU2VB.js +362 -0
- package/dist/chunk-67YIU2VB.js.map +1 -0
- package/dist/{chunk-QCPGHBSZ.js → chunk-6BENHR2I.js} +63 -21
- package/dist/chunk-6BENHR2I.js.map +1 -0
- package/dist/{chunk-BYZDPR7N.js → chunk-6QYMSNVA.js} +194 -235
- package/dist/chunk-6QYMSNVA.js.map +1 -0
- package/dist/{chunk-Y5ZDJ4PJ.js → chunk-76MMPJ53.js} +20 -10
- package/dist/chunk-76MMPJ53.js.map +1 -0
- package/dist/chunk-7Z4Y3VKM.js +26 -0
- package/dist/chunk-7Z4Y3VKM.js.map +1 -0
- package/dist/{chunk-3QHK4YQA.js → chunk-B72RQZBV.js} +346 -119
- package/dist/chunk-B72RQZBV.js.map +1 -0
- package/dist/chunk-BEZ5BA5U.js +625 -0
- package/dist/chunk-BEZ5BA5U.js.map +1 -0
- package/dist/chunk-BRCNQXYQ.js +74 -0
- package/dist/chunk-BRCNQXYQ.js.map +1 -0
- package/dist/chunk-CGKLE6WR.js +1203 -0
- package/dist/chunk-CGKLE6WR.js.map +1 -0
- package/dist/chunk-CRGIQFUQ.js +83 -0
- package/dist/chunk-CRGIQFUQ.js.map +1 -0
- package/dist/{chunk-NS6R37II.js → chunk-F6TOYSYY.js} +141 -12
- package/dist/chunk-F6TOYSYY.js.map +1 -0
- package/dist/chunk-G5EK2XRN.js +25 -0
- package/dist/chunk-G5EK2XRN.js.map +1 -0
- package/dist/chunk-HAKDLR6N.js +134 -0
- package/dist/chunk-HAKDLR6N.js.map +1 -0
- package/dist/chunk-J3SOTUVI.js +298 -0
- package/dist/chunk-J3SOTUVI.js.map +1 -0
- package/dist/chunk-JN6D3MY6.js +30 -0
- package/dist/chunk-JN6D3MY6.js.map +1 -0
- package/dist/{chunk-LAFNLLQP.js → chunk-KMRFRXIT.js} +5 -5
- package/dist/chunk-KT7JKOXB.js +72 -0
- package/dist/chunk-KT7JKOXB.js.map +1 -0
- package/dist/chunk-L6HSKTQE.js +77 -0
- package/dist/chunk-L6HSKTQE.js.map +1 -0
- package/dist/chunk-LBGHI4S2.js +1264 -0
- package/dist/chunk-LBGHI4S2.js.map +1 -0
- package/dist/chunk-LEW4QM74.js +180 -0
- package/dist/chunk-LEW4QM74.js.map +1 -0
- package/dist/{chunk-FJP3UQGD.js → chunk-LFEQIZLB.js} +115 -20
- package/dist/chunk-LFEQIZLB.js.map +1 -0
- package/dist/chunk-OOVG2KBY.js +77 -0
- package/dist/chunk-OOVG2KBY.js.map +1 -0
- package/dist/{chunk-56KS3TFQ.js → chunk-OR43364P.js} +115 -160
- package/dist/chunk-OR43364P.js.map +1 -0
- package/dist/chunk-P3LRUNC6.js +16 -0
- package/dist/chunk-P3LRUNC6.js.map +1 -0
- package/dist/{chunk-TSOLWK7Y.js → chunk-PBTA3QQX.js} +8 -7
- package/dist/{chunk-TSOLWK7Y.js.map → chunk-PBTA3QQX.js.map} +1 -1
- package/dist/{chunk-MJULIKQU.js → chunk-PHW2YV6N.js} +23 -47
- package/dist/chunk-PHW2YV6N.js.map +1 -0
- package/dist/{chunk-73ATPIYX.js → chunk-PZTWU277.js} +36 -71
- package/dist/chunk-PZTWU277.js.map +1 -0
- package/dist/{chunk-M5UCXTIT.js → chunk-QD4VOILZ.js} +22 -18
- package/dist/chunk-QD4VOILZ.js.map +1 -0
- package/dist/chunk-QJ5UZAH5.js +2718 -0
- package/dist/chunk-QJ5UZAH5.js.map +1 -0
- package/dist/chunk-QK7WUO7A.js +283 -0
- package/dist/chunk-QK7WUO7A.js.map +1 -0
- package/dist/{chunk-A4SLHOW7.js → chunk-QZVKRDJY.js} +27 -19
- package/dist/chunk-QZVKRDJY.js.map +1 -0
- package/dist/chunk-REO3PXXO.js +71 -0
- package/dist/chunk-REO3PXXO.js.map +1 -0
- package/dist/{chunk-EZATO3DW.js → chunk-RVO7L4FX.js} +594 -17
- package/dist/chunk-RVO7L4FX.js.map +1 -0
- package/dist/{chunk-XQUSIEKA.js → chunk-SZMHCEYV.js} +63 -14
- package/dist/chunk-SZMHCEYV.js.map +1 -0
- package/dist/chunk-TYRNTSPJ.js +243 -0
- package/dist/chunk-TYRNTSPJ.js.map +1 -0
- package/dist/chunk-UJ3L2MS7.js +238 -0
- package/dist/chunk-UJ3L2MS7.js.map +1 -0
- package/dist/chunk-V7MO5EDS.js +120 -0
- package/dist/chunk-V7MO5EDS.js.map +1 -0
- package/dist/chunk-WB2X37MO.js +415 -0
- package/dist/chunk-WB2X37MO.js.map +1 -0
- package/dist/{chunk-NTMMF5UD.js → chunk-X44FKNKP.js} +525 -252
- package/dist/chunk-X44FKNKP.js.map +1 -0
- package/dist/chunk-XEYH6ZZI.js +289 -0
- package/dist/chunk-XEYH6ZZI.js.map +1 -0
- package/dist/cli.js +267 -44
- package/dist/cli.js.map +1 -1
- package/dist/{config-PRJGWW7J.js → config-HMFMCY2M.js} +31 -5
- package/dist/contract-JH2WBIO6.js +8 -0
- package/dist/conventions-NJF2OPVQ.js +146 -0
- package/dist/conventions-NJF2OPVQ.js.map +1 -0
- package/dist/diagnostics-THH42ZMP.js +23 -0
- package/dist/execute-KFNNZZHI.js +35 -0
- package/dist/{generate-EGB4KV2B.js → generate-FW5C6NP7.js} +37 -20
- package/dist/{generate-EGB4KV2B.js.map → generate-FW5C6NP7.js.map} +1 -1
- package/dist/git-W72QQ6GT.js +33 -0
- package/dist/init-HTN4V67Q.js +24 -0
- package/dist/{operations-BYT626KQ.js → operations-BCFOBH42.js} +27 -15
- package/dist/{operations-BYT626KQ.js.map → operations-BCFOBH42.js.map} +1 -1
- package/dist/permissions-4AKNQZHK.js +18 -0
- package/dist/plan-SIZLGA4V.js +34 -0
- package/dist/{policy-6S4GFC76.js → policy-DT6Q6ZVM.js} +20 -6
- package/dist/policy-DT6Q6ZVM.js.map +1 -0
- package/dist/pr-OMWCGUOW.js +39 -0
- package/dist/pr-review-N24CZPKR.js +32 -0
- package/dist/pr-review-N24CZPKR.js.map +1 -0
- package/dist/prd-5OFTZAHJ.js +33 -0
- package/dist/prd-5OFTZAHJ.js.map +1 -0
- package/dist/ps-RFORTCUD.js +93 -0
- package/dist/ps-RFORTCUD.js.map +1 -0
- package/dist/recorder-KCCPMKQG.js +32 -0
- package/dist/recorder-KCCPMKQG.js.map +1 -0
- package/dist/registry-GLPXOMFG.js +15 -0
- package/dist/registry-GLPXOMFG.js.map +1 -0
- package/dist/{resume-PPCNQVVV.js → resume-M5RLKP4I.js} +55 -34
- package/dist/{resume-PPCNQVVV.js.map → resume-M5RLKP4I.js.map} +1 -1
- package/dist/review-YM4JAABY.js +35 -0
- package/dist/review-YM4JAABY.js.map +1 -0
- package/dist/routing-NNT5WKGX.js +94 -0
- package/dist/routing-NNT5WKGX.js.map +1 -0
- package/dist/run-PZUKHPQK.js +54 -0
- package/dist/run-PZUKHPQK.js.map +1 -0
- package/dist/session-publisher-T7EI3CIP.js +11 -0
- package/dist/session-publisher-T7EI3CIP.js.map +1 -0
- package/dist/{state-manager-2EDVDBAR.js → state-manager-GQH32C44.js} +4 -2
- package/dist/state-manager-GQH32C44.js.map +1 -0
- package/dist/usage-V2CHE5PY.js +177 -0
- package/dist/usage-V2CHE5PY.js.map +1 -0
- package/dist/{web-EF5WIIGG.js → web-EA3KGNFN.js} +45 -30
- package/dist/web-EA3KGNFN.js.map +1 -0
- package/package.json +6 -2
- package/prompts/execute.md +7 -8
- package/prompts/plan.md +4 -5
- package/prompts/pr.md +2 -2
- package/web/AGENTS.md +152 -13
- package/web/public/app.css +380 -109
- package/web/public/app.js +525 -25
- package/web/public/index.html +68 -1
- package/dist/analyze-OEET7KGE.js.map +0 -1
- package/dist/chunk-3QHK4YQA.js.map +0 -1
- package/dist/chunk-42PJFMAR.js +0 -605
- package/dist/chunk-42PJFMAR.js.map +0 -1
- package/dist/chunk-4JSOYE4G.js +0 -368
- package/dist/chunk-4JSOYE4G.js.map +0 -1
- package/dist/chunk-56KS3TFQ.js.map +0 -1
- package/dist/chunk-73ATPIYX.js.map +0 -1
- package/dist/chunk-A4SLHOW7.js.map +0 -1
- package/dist/chunk-BAUPQXPE.js +0 -173
- package/dist/chunk-BAUPQXPE.js.map +0 -1
- package/dist/chunk-BYZDPR7N.js.map +0 -1
- package/dist/chunk-CD5ULRVC.js +0 -615
- package/dist/chunk-CD5ULRVC.js.map +0 -1
- package/dist/chunk-DIDUVL6O.js +0 -1365
- package/dist/chunk-DIDUVL6O.js.map +0 -1
- package/dist/chunk-EZATO3DW.js.map +0 -1
- package/dist/chunk-FADTCQGM.js.map +0 -1
- package/dist/chunk-FJP3UQGD.js.map +0 -1
- package/dist/chunk-LWRSMTTZ.js +0 -18
- package/dist/chunk-LWRSMTTZ.js.map +0 -1
- package/dist/chunk-M5UCXTIT.js.map +0 -1
- package/dist/chunk-M66SJHQQ.js +0 -206
- package/dist/chunk-M66SJHQQ.js.map +0 -1
- package/dist/chunk-MJULIKQU.js.map +0 -1
- package/dist/chunk-NS6R37II.js.map +0 -1
- package/dist/chunk-NTMMF5UD.js.map +0 -1
- package/dist/chunk-QCPGHBSZ.js.map +0 -1
- package/dist/chunk-XQUSIEKA.js.map +0 -1
- package/dist/chunk-Y5ZDJ4PJ.js.map +0 -1
- package/dist/execute-XBNVL753.js +0 -18
- package/dist/init-AJHCXJBP.js +0 -10
- package/dist/plan-QOZ3RIO6.js +0 -21
- package/dist/policy-6S4GFC76.js.map +0 -1
- package/dist/pr-EBBHD2ZX.js +0 -26
- package/dist/pr-review-VVMW5PO4.js +0 -20
- package/dist/prd-JQSZF7PR.js +0 -21
- package/dist/review-3F6MARWH.js +0 -19
- package/dist/run-RXE5GDQO.js +0 -36
- package/dist/web-EF5WIIGG.js.map +0 -1
- /package/dist/{config-PRJGWW7J.js.map → agent-OX3KPHE4.js.map} +0 -0
- /package/dist/{chunk-LAFNLLQP.js.map → chunk-KMRFRXIT.js.map} +0 -0
- /package/dist/{execute-XBNVL753.js.map → config-HMFMCY2M.js.map} +0 -0
- /package/dist/{init-AJHCXJBP.js.map → contract-JH2WBIO6.js.map} +0 -0
- /package/dist/{plan-QOZ3RIO6.js.map → diagnostics-THH42ZMP.js.map} +0 -0
- /package/dist/{pr-EBBHD2ZX.js.map → execute-KFNNZZHI.js.map} +0 -0
- /package/dist/{pr-review-VVMW5PO4.js.map → git-W72QQ6GT.js.map} +0 -0
- /package/dist/{prd-JQSZF7PR.js.map → init-HTN4V67Q.js.map} +0 -0
- /package/dist/{review-3F6MARWH.js.map → permissions-4AKNQZHK.js.map} +0 -0
- /package/dist/{run-RXE5GDQO.js.map → plan-SIZLGA4V.js.map} +0 -0
- /package/dist/{state-manager-2EDVDBAR.js.map → pr-OMWCGUOW.js.map} +0 -0
|
@@ -2,14 +2,353 @@
|
|
|
2
2
|
import {
|
|
3
3
|
loadPolicyConfig,
|
|
4
4
|
mergeConfigLayers
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-QJ5UZAH5.js";
|
|
6
|
+
import {
|
|
7
|
+
printWarning
|
|
8
|
+
} from "./chunk-TYRNTSPJ.js";
|
|
6
9
|
import {
|
|
7
10
|
getProjectRoot,
|
|
8
11
|
run
|
|
9
|
-
} from "./chunk-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
12
|
+
} from "./chunk-BEZ5BA5U.js";
|
|
13
|
+
|
|
14
|
+
// src/conventions/git/types.ts
|
|
15
|
+
var CHANGE_TYPES = [
|
|
16
|
+
"feat",
|
|
17
|
+
"fix",
|
|
18
|
+
"docs",
|
|
19
|
+
"refactor",
|
|
20
|
+
"perf",
|
|
21
|
+
"test",
|
|
22
|
+
"build",
|
|
23
|
+
"ci",
|
|
24
|
+
"chore",
|
|
25
|
+
"style",
|
|
26
|
+
"revert"
|
|
27
|
+
];
|
|
28
|
+
var DEFAULT_BRANCH_CONVENTION = "{type}/{N}-{slug}";
|
|
29
|
+
var SLUG_MAX_LENGTH = 40;
|
|
30
|
+
var BRANCH_MAX_LENGTH = 60;
|
|
31
|
+
var DEFAULT_LABEL_TYPE_MAP = {
|
|
32
|
+
bug: "fix",
|
|
33
|
+
documentation: "docs",
|
|
34
|
+
docs: "docs",
|
|
35
|
+
refactor: "refactor",
|
|
36
|
+
"tech-debt": "refactor",
|
|
37
|
+
infra: "ci",
|
|
38
|
+
"ci-cd": "ci",
|
|
39
|
+
enhancement: "feat",
|
|
40
|
+
architecture: "feat",
|
|
41
|
+
investigation: "chore"
|
|
42
|
+
};
|
|
43
|
+
var FORBIDDEN_PROVIDER_NAMES = ["claude", "codex", "cursor", "antigravity"];
|
|
44
|
+
function isChangeType(value) {
|
|
45
|
+
return CHANGE_TYPES.includes(value);
|
|
46
|
+
}
|
|
47
|
+
function isForbiddenProviderToken(value) {
|
|
48
|
+
return FORBIDDEN_PROVIDER_NAMES.includes(value.toLowerCase());
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// src/conventions/git/slug.ts
|
|
52
|
+
var COMBINING = /[\u0300-\u036f]/g;
|
|
53
|
+
var NON_SLUG = /[^a-z0-9]+/g;
|
|
54
|
+
function slugify(title, maxLength = SLUG_MAX_LENGTH) {
|
|
55
|
+
const withoutLock = title.replace(/\.lock$/i, "");
|
|
56
|
+
const normalized = withoutLock.normalize("NFD").replace(COMBINING, "").toLowerCase();
|
|
57
|
+
let slug = normalized.replace(NON_SLUG, "-").replace(/^-+|-+$/g, "");
|
|
58
|
+
slug = slug.replace(/\.{2,}/g, ".").replace(/^\.+|\.+$/g, "");
|
|
59
|
+
slug = slug.replace(/[^a-z0-9-]+/g, "-").replace(/^-+|-+$/g, "");
|
|
60
|
+
if (slug.length <= maxLength) return slug;
|
|
61
|
+
const cut = slug.slice(0, maxLength);
|
|
62
|
+
const lastHyphen = cut.lastIndexOf("-");
|
|
63
|
+
if (lastHyphen >= Math.floor(maxLength / 2)) {
|
|
64
|
+
return cut.slice(0, lastHyphen).replace(/-+$/g, "");
|
|
65
|
+
}
|
|
66
|
+
return cut.replace(/-+$/g, "");
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// src/conventions/git/branch.ts
|
|
70
|
+
var LEGACY_PREFIX = "issue";
|
|
71
|
+
function branchType(type) {
|
|
72
|
+
return type === "style" || type === "revert" ? "chore" : type;
|
|
73
|
+
}
|
|
74
|
+
function applyConvention(convention, type, issueNumber, slug) {
|
|
75
|
+
const hasNumber = issueNumber !== void 0 && issueNumber !== null;
|
|
76
|
+
let result = convention.replaceAll("{type}", type).replaceAll("{N}", hasNumber ? String(issueNumber) : "").replaceAll("{slug}", slug);
|
|
77
|
+
result = result.replace(/\/{2,}/g, "/").replace(/-{2,}/g, "-");
|
|
78
|
+
result = result.replace(/\/-/g, "/").replace(/-\//g, "/");
|
|
79
|
+
result = result.replace(/^\/+|\/+$/g, "").replace(/^-+|-+$/g, "");
|
|
80
|
+
if (!hasNumber) {
|
|
81
|
+
result = result.replace(`${type}/-`, `${type}/`).replace(/\/$/g, "");
|
|
82
|
+
}
|
|
83
|
+
if (slug === "") {
|
|
84
|
+
result = result.replace(/\/-$/, "").replace(/-$/, "");
|
|
85
|
+
}
|
|
86
|
+
return result.replace(/\/{2,}/g, "/").replace(/^\/+|\/+$/g, "");
|
|
87
|
+
}
|
|
88
|
+
function truncateBranch(name, max) {
|
|
89
|
+
if (name.length <= max) return name;
|
|
90
|
+
const slash = name.indexOf("/");
|
|
91
|
+
const prefix = slash === -1 ? "" : name.slice(0, slash + 1);
|
|
92
|
+
const rest = slash === -1 ? name : name.slice(slash + 1);
|
|
93
|
+
const budget = max - prefix.length;
|
|
94
|
+
if (budget < 1) return name.slice(0, max);
|
|
95
|
+
const cut = rest.slice(0, budget);
|
|
96
|
+
const lastHyphen = cut.lastIndexOf("-");
|
|
97
|
+
const trimmed = lastHyphen >= Math.floor(budget / 2) ? cut.slice(0, lastHyphen) : cut;
|
|
98
|
+
return `${prefix}${trimmed.replace(/-+$/g, "")}`;
|
|
99
|
+
}
|
|
100
|
+
function collide(name, existingRefs, currentOid) {
|
|
101
|
+
if (existingRefs === void 0 || existingRefs.length === 0) return name;
|
|
102
|
+
const byName = new Map(existingRefs.map((ref) => [ref.name, ref.oid]));
|
|
103
|
+
const existing = byName.get(name);
|
|
104
|
+
if (existing === void 0) return name;
|
|
105
|
+
if (currentOid !== void 0 && existing === currentOid) return name;
|
|
106
|
+
for (let n = 2; n < 100; n += 1) {
|
|
107
|
+
const candidate = `${name}-${n}`;
|
|
108
|
+
const oid = byName.get(candidate);
|
|
109
|
+
if (oid === void 0 || currentOid !== void 0 && oid === currentOid) {
|
|
110
|
+
return candidate;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
return `${name}-${Date.now()}`;
|
|
114
|
+
}
|
|
115
|
+
function branchName(input) {
|
|
116
|
+
const type = branchType(input.type);
|
|
117
|
+
const convention = input.convention ?? DEFAULT_BRANCH_CONVENTION;
|
|
118
|
+
const slug = slugify(input.title);
|
|
119
|
+
const raw = applyConvention(convention, type, input.issueNumber, slug);
|
|
120
|
+
const truncated = truncateBranch(raw, BRANCH_MAX_LENGTH);
|
|
121
|
+
return collide(truncated, input.existingRefs, input.currentOid);
|
|
122
|
+
}
|
|
123
|
+
function parseBranch(name) {
|
|
124
|
+
const raw = name.trim();
|
|
125
|
+
const match = raw.match(/^([^/]+)\/(?:(\d+)(?:-(.*))?|(.*))$/);
|
|
126
|
+
if (match === null) {
|
|
127
|
+
return { type: null, issueNumber: null, slug: raw, raw };
|
|
128
|
+
}
|
|
129
|
+
const prefix = match[1] ?? "";
|
|
130
|
+
const numbered = match[2];
|
|
131
|
+
const numberedSlug = match[3] ?? "";
|
|
132
|
+
const unnumberedSlug = match[4] ?? "";
|
|
133
|
+
const type = prefix === LEGACY_PREFIX ? "issue" : isChangeType(prefix) ? prefix : null;
|
|
134
|
+
if (numbered !== void 0) {
|
|
135
|
+
return { type, issueNumber: Number(numbered), slug: numberedSlug, raw };
|
|
136
|
+
}
|
|
137
|
+
return { type, issueNumber: null, slug: unnumberedSlug, raw };
|
|
138
|
+
}
|
|
139
|
+
function archiveFolderName(branch) {
|
|
140
|
+
const parsed = parseBranch(branch);
|
|
141
|
+
if (parsed.issueNumber !== null && parsed.slug !== "") {
|
|
142
|
+
return `${parsed.issueNumber}-${parsed.slug}`.replace(/[<>:"|?*\\]/g, "_");
|
|
143
|
+
}
|
|
144
|
+
if (parsed.issueNumber !== null) {
|
|
145
|
+
return String(parsed.issueNumber);
|
|
146
|
+
}
|
|
147
|
+
return branch.replace(/^[^/]+\//, "").replace(/[<>:"|?*\\]/g, "_");
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
// src/conventions/git/change-type.ts
|
|
151
|
+
var ISSUE_TYPE_MAP = {
|
|
152
|
+
bug: "fix",
|
|
153
|
+
feature: "feat",
|
|
154
|
+
task: "chore",
|
|
155
|
+
epic: "chore",
|
|
156
|
+
idea: "chore",
|
|
157
|
+
research: "chore",
|
|
158
|
+
documentation: "docs"
|
|
159
|
+
};
|
|
160
|
+
var TITLE_PREFIX_MAP = {
|
|
161
|
+
bug: "fix",
|
|
162
|
+
fix: "fix",
|
|
163
|
+
feature: "feat",
|
|
164
|
+
enhancement: "feat",
|
|
165
|
+
architecture: "feat",
|
|
166
|
+
refactor: "refactor",
|
|
167
|
+
docs: "docs",
|
|
168
|
+
documentation: "docs",
|
|
169
|
+
chore: "chore",
|
|
170
|
+
perf: "perf",
|
|
171
|
+
test: "test",
|
|
172
|
+
ci: "ci"
|
|
173
|
+
};
|
|
174
|
+
function normalizeKey(value) {
|
|
175
|
+
return value.trim().toLowerCase();
|
|
176
|
+
}
|
|
177
|
+
function typeFromIssueType(issueType) {
|
|
178
|
+
const key = normalizeKey(issueType);
|
|
179
|
+
if (isChangeType(key)) return key;
|
|
180
|
+
return ISSUE_TYPE_MAP[key] ?? null;
|
|
181
|
+
}
|
|
182
|
+
function mergedTypeMap(overlay) {
|
|
183
|
+
const merged = { ...DEFAULT_LABEL_TYPE_MAP };
|
|
184
|
+
if (overlay === void 0 || overlay === null) return merged;
|
|
185
|
+
for (const [label, type] of Object.entries(overlay)) {
|
|
186
|
+
if (isChangeType(type)) {
|
|
187
|
+
merged[normalizeKey(label)] = type;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
return merged;
|
|
191
|
+
}
|
|
192
|
+
function typeFromLabels(labels, typeMap) {
|
|
193
|
+
for (const label of labels) {
|
|
194
|
+
const key = normalizeKey(label);
|
|
195
|
+
const mapped = typeMap[key] ?? typeMap[key.replace(/^type:/, "")];
|
|
196
|
+
if (mapped !== void 0) return mapped;
|
|
197
|
+
}
|
|
198
|
+
return null;
|
|
199
|
+
}
|
|
200
|
+
function typeFromTitle(title) {
|
|
201
|
+
const match = title.match(/^\s*\[([^\]]+)\]/);
|
|
202
|
+
if (match?.[1] === void 0) return null;
|
|
203
|
+
const key = normalizeKey(match[1]);
|
|
204
|
+
if (isChangeType(key)) return key;
|
|
205
|
+
return TITLE_PREFIX_MAP[key] ?? null;
|
|
206
|
+
}
|
|
207
|
+
function resolveChangeType(input) {
|
|
208
|
+
if (input.declaredType !== void 0 && input.declaredType !== null) {
|
|
209
|
+
return { type: input.declaredType, source: "declared" };
|
|
210
|
+
}
|
|
211
|
+
const labels = input.labels ?? [];
|
|
212
|
+
const typeMap = mergedTypeMap(input.typeMap);
|
|
213
|
+
const fromLabels = typeFromLabels(labels, typeMap);
|
|
214
|
+
const fromIssueType = input.issueType !== void 0 && input.issueType !== null && input.issueType !== "" ? typeFromIssueType(input.issueType) : null;
|
|
215
|
+
if (fromIssueType !== null) {
|
|
216
|
+
const issueKey = normalizeKey(input.issueType ?? "");
|
|
217
|
+
if (issueKey === "task" && fromLabels !== null) {
|
|
218
|
+
return { type: fromLabels, source: "label" };
|
|
219
|
+
}
|
|
220
|
+
if (fromLabels !== null && fromLabels !== fromIssueType) {
|
|
221
|
+
return {
|
|
222
|
+
type: fromIssueType,
|
|
223
|
+
source: "issue-type",
|
|
224
|
+
conflict: { issueType: fromIssueType, label: fromLabels }
|
|
225
|
+
};
|
|
226
|
+
}
|
|
227
|
+
return { type: fromIssueType, source: "issue-type" };
|
|
228
|
+
}
|
|
229
|
+
if (fromLabels !== null) {
|
|
230
|
+
return { type: fromLabels, source: "label" };
|
|
231
|
+
}
|
|
232
|
+
if (input.titleConvention !== null && input.title !== void 0) {
|
|
233
|
+
const fromTitle = typeFromTitle(input.title);
|
|
234
|
+
if (fromTitle !== null) {
|
|
235
|
+
return { type: fromTitle, source: "title" };
|
|
236
|
+
}
|
|
237
|
+
} else if (input.title !== void 0) {
|
|
238
|
+
const fromTitle = typeFromTitle(input.title);
|
|
239
|
+
if (fromTitle !== null) {
|
|
240
|
+
return { type: fromTitle, source: "title" };
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
return { type: "feat", source: "fallback" };
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
// src/conventions/git/commit.ts
|
|
247
|
+
var HEADER_MAX = 72;
|
|
248
|
+
var BODY_WIDTH = 72;
|
|
249
|
+
var STORY_ID = /^US-\d+$/i;
|
|
250
|
+
function wrap(text, width) {
|
|
251
|
+
const paragraphs = text.replace(/\r\n/g, "\n").split("\n");
|
|
252
|
+
return paragraphs.map((paragraph) => {
|
|
253
|
+
if (paragraph.trim() === "") return "";
|
|
254
|
+
const words = paragraph.split(/\s+/);
|
|
255
|
+
const lines = [];
|
|
256
|
+
let current = "";
|
|
257
|
+
for (const word of words) {
|
|
258
|
+
const next = current === "" ? word : `${current} ${word}`;
|
|
259
|
+
if (next.length > width && current !== "") {
|
|
260
|
+
lines.push(current);
|
|
261
|
+
current = word;
|
|
262
|
+
} else {
|
|
263
|
+
current = next;
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
if (current !== "") lines.push(current);
|
|
267
|
+
return lines.join("\n");
|
|
268
|
+
}).join("\n");
|
|
269
|
+
}
|
|
270
|
+
function sanitizeScope(scope) {
|
|
271
|
+
if (scope === void 0 || scope === null) return void 0;
|
|
272
|
+
const trimmed = scope.trim();
|
|
273
|
+
if (trimmed === "" || isForbiddenProviderToken(trimmed)) return void 0;
|
|
274
|
+
return trimmed;
|
|
275
|
+
}
|
|
276
|
+
function sanitizeType(type) {
|
|
277
|
+
return isForbiddenProviderToken(type) ? "chore" : type;
|
|
278
|
+
}
|
|
279
|
+
function headerLine(type, scope, breaking, subject) {
|
|
280
|
+
const bang = breaking ? "!" : "";
|
|
281
|
+
const scoped = scope === void 0 ? `${type}${bang}` : `${type}(${scope})${bang}`;
|
|
282
|
+
const cleaned = subject.replace(/\.$/, "").trim();
|
|
283
|
+
const prefix = `${scoped}: `;
|
|
284
|
+
const budget = HEADER_MAX - prefix.length;
|
|
285
|
+
const clipped = budget < 1 ? "" : cleaned.length > budget ? cleaned.slice(0, budget).trimEnd() : cleaned;
|
|
286
|
+
return `${prefix}${clipped}`;
|
|
287
|
+
}
|
|
288
|
+
function commitMessage(input) {
|
|
289
|
+
const type = sanitizeType(input.type);
|
|
290
|
+
const scope = sanitizeScope(input.scope);
|
|
291
|
+
const breaking = input.breaking !== void 0 && input.breaking !== null && input.breaking !== "";
|
|
292
|
+
const lines = [headerLine(type, scope, breaking, input.subject)];
|
|
293
|
+
if (input.body !== void 0 && input.body !== "") {
|
|
294
|
+
lines.push("", wrap(input.body, BODY_WIDTH));
|
|
295
|
+
}
|
|
296
|
+
const footers = [];
|
|
297
|
+
if (input.issueNumber !== void 0 && input.issueNumber !== null) {
|
|
298
|
+
footers.push(`Refs #${input.issueNumber}`);
|
|
299
|
+
}
|
|
300
|
+
if (input.storyId !== void 0 && input.storyId !== null && STORY_ID.test(input.storyId)) {
|
|
301
|
+
footers.push(`Story: ${input.storyId}`);
|
|
302
|
+
}
|
|
303
|
+
if (breaking) {
|
|
304
|
+
footers.push(`BREAKING CHANGE: ${input.breaking}`);
|
|
305
|
+
}
|
|
306
|
+
if (input.signoff === true) {
|
|
307
|
+
footers.push("Signed-off-by:");
|
|
308
|
+
} else if (typeof input.signoff === "string" && input.signoff !== "") {
|
|
309
|
+
footers.push(`Signed-off-by: ${input.signoff}`);
|
|
310
|
+
}
|
|
311
|
+
if (footers.length > 0) {
|
|
312
|
+
lines.push("", ...footers);
|
|
313
|
+
}
|
|
314
|
+
return lines.join("\n");
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
// src/conventions/git/pull-request.ts
|
|
318
|
+
var IMPACT = ["feat", "fix"];
|
|
319
|
+
function sanitizeScope2(scope) {
|
|
320
|
+
if (scope === void 0 || scope === null) return void 0;
|
|
321
|
+
const trimmed = scope.trim();
|
|
322
|
+
if (trimmed === "" || isForbiddenProviderToken(trimmed)) return void 0;
|
|
323
|
+
return trimmed;
|
|
324
|
+
}
|
|
325
|
+
function highestImpact(types) {
|
|
326
|
+
for (const type of IMPACT) {
|
|
327
|
+
if (types.includes(type)) return type;
|
|
328
|
+
}
|
|
329
|
+
return types[0] ?? "feat";
|
|
330
|
+
}
|
|
331
|
+
function scopesAgree(scopes) {
|
|
332
|
+
const unique2 = [
|
|
333
|
+
...new Set(scopes.map((scope) => sanitizeScope2(scope)).filter((scope) => scope !== void 0))
|
|
334
|
+
];
|
|
335
|
+
return unique2.length === 1 ? unique2[0] : void 0;
|
|
336
|
+
}
|
|
337
|
+
function pullRequestTitle(input) {
|
|
338
|
+
const type = input.types !== void 0 && input.types.length > 0 ? highestImpact(input.types) : input.type;
|
|
339
|
+
const scope = input.scopes !== void 0 && input.scopes.length > 0 ? scopesAgree(input.scopes) : sanitizeScope2(input.scope);
|
|
340
|
+
const subject = input.subject.replace(/\.$/, "").trim();
|
|
341
|
+
if (isForbiddenProviderToken(type)) {
|
|
342
|
+
return scope === void 0 ? `chore: ${subject}` : `chore(${scope}): ${subject}`;
|
|
343
|
+
}
|
|
344
|
+
return scope === void 0 ? `${type}: ${subject}` : `${type}(${scope}): ${subject}`;
|
|
345
|
+
}
|
|
346
|
+
function issueReferenceLines(input) {
|
|
347
|
+
return input.references.map((ref) => {
|
|
348
|
+
const closes = ref.container === true ? ref.allChildrenComplete === true : ref.complete;
|
|
349
|
+
return `${closes ? "Closes" : "Refs"} #${ref.number}`;
|
|
350
|
+
}).join("\n");
|
|
351
|
+
}
|
|
13
352
|
|
|
14
353
|
// src/policy/resolve.ts
|
|
15
354
|
import { isAbsolute, normalize, sep as sep2 } from "path";
|
|
@@ -58,6 +397,118 @@ function extractReferencedDocuments(content, fromPath) {
|
|
|
58
397
|
return found;
|
|
59
398
|
}
|
|
60
399
|
|
|
400
|
+
// src/policy/parsers/git.ts
|
|
401
|
+
var COMMITLINT_NAMES = [
|
|
402
|
+
".commitlintrc",
|
|
403
|
+
".commitlintrc.json",
|
|
404
|
+
".commitlintrc.yaml",
|
|
405
|
+
".commitlintrc.yml",
|
|
406
|
+
".commitlintrc.js",
|
|
407
|
+
".commitlintrc.cjs",
|
|
408
|
+
".commitlintrc.mjs",
|
|
409
|
+
".commitlintrc.ts",
|
|
410
|
+
"commitlint.config.js",
|
|
411
|
+
"commitlint.config.cjs",
|
|
412
|
+
"commitlint.config.mjs",
|
|
413
|
+
"commitlint.config.ts"
|
|
414
|
+
];
|
|
415
|
+
function unique(values) {
|
|
416
|
+
return [...new Set(values)];
|
|
417
|
+
}
|
|
418
|
+
function extractQuotedStrings(block) {
|
|
419
|
+
const matches = block.match(/['"]([a-z][a-z0-9-]*)['"]/g) ?? [];
|
|
420
|
+
return matches.map((token) => token.slice(1, -1));
|
|
421
|
+
}
|
|
422
|
+
function extractEnum(source, rule) {
|
|
423
|
+
const escaped = rule.replace("-", "\\-");
|
|
424
|
+
const match = source.match(new RegExp(`${escaped}[\\s\\S]{0,800}?\\[([\\s\\S]*?)\\]`, "i"));
|
|
425
|
+
if (match?.[1] === void 0) return [];
|
|
426
|
+
return extractQuotedStrings(match[1]).filter((value) => value !== "always" && value !== "never");
|
|
427
|
+
}
|
|
428
|
+
function parseCommitlintSource(source, path) {
|
|
429
|
+
const types = extractEnum(source, "type-enum").filter(isChangeType);
|
|
430
|
+
const scopes = extractEnum(source, "scope-enum");
|
|
431
|
+
const conventional = /conventional|commitlint/i.test(source) || types.length > 0;
|
|
432
|
+
return {
|
|
433
|
+
commitConvention: conventional ? "conventional" : null,
|
|
434
|
+
pullRequestTitleConvention: null,
|
|
435
|
+
allowedTypes: types.length > 0 ? unique(types) : null,
|
|
436
|
+
scopes: scopes.length > 0 ? unique(scopes) : null,
|
|
437
|
+
sources: [{ path, detail: conventional ? "commitlint" : "commitlint (unrecognised)" }]
|
|
438
|
+
};
|
|
439
|
+
}
|
|
440
|
+
function parsePackageCommitlint(pkg) {
|
|
441
|
+
if (pkg === null || typeof pkg !== "object" || Array.isArray(pkg)) return null;
|
|
442
|
+
const commitlint = pkg.commitlint;
|
|
443
|
+
if (commitlint === void 0 || commitlint === null) return null;
|
|
444
|
+
const source = JSON.stringify(commitlint);
|
|
445
|
+
return parseCommitlintSource(source, "package.json#commitlint");
|
|
446
|
+
}
|
|
447
|
+
function parseSemanticPrWorkflow(source, path) {
|
|
448
|
+
if (!/amannn\/action-semantic-pull-request/.test(source)) return null;
|
|
449
|
+
const typesBlock = source.match(/types:\s*[|>]?\s*\n((?:\s{2,}[a-z][a-z0-9-]*\s*\n)+)/i);
|
|
450
|
+
const scopesBlock = source.match(/scopes:\s*[|>]?\s*\n((?:\s{2,}[a-z][a-z0-9-]*\s*\n)+)/i);
|
|
451
|
+
const types = typesBlock?.[1]?.split("\n").map((line) => line.trim()).filter((line) => isChangeType(line)) ?? [];
|
|
452
|
+
const scopes = scopesBlock?.[1]?.split("\n").map((line) => line.trim()).filter((line) => /^[a-z][a-z0-9-]*$/.test(line)) ?? [];
|
|
453
|
+
return {
|
|
454
|
+
commitConvention: "conventional",
|
|
455
|
+
pullRequestTitleConvention: "conventional",
|
|
456
|
+
allowedTypes: types.length > 0 ? unique(types) : null,
|
|
457
|
+
scopes: scopes.length > 0 ? unique(scopes) : null,
|
|
458
|
+
sources: [{ path, detail: "amannn/action-semantic-pull-request" }]
|
|
459
|
+
};
|
|
460
|
+
}
|
|
461
|
+
function parseCommitlintText(source, path) {
|
|
462
|
+
return parseCommitlintSource(source, path);
|
|
463
|
+
}
|
|
464
|
+
function parsePackageJsonCommitlint(raw) {
|
|
465
|
+
try {
|
|
466
|
+
return parsePackageCommitlint(JSON.parse(raw));
|
|
467
|
+
} catch {
|
|
468
|
+
return null;
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
function parseReleasePlease(_raw, path) {
|
|
472
|
+
return {
|
|
473
|
+
commitConvention: "conventional",
|
|
474
|
+
pullRequestTitleConvention: null,
|
|
475
|
+
allowedTypes: null,
|
|
476
|
+
scopes: null,
|
|
477
|
+
sources: [{ path, detail: "release-please (Conventional Commits)" }]
|
|
478
|
+
};
|
|
479
|
+
}
|
|
480
|
+
function parseSemanticRelease(path) {
|
|
481
|
+
return {
|
|
482
|
+
commitConvention: "conventional",
|
|
483
|
+
pullRequestTitleConvention: null,
|
|
484
|
+
allowedTypes: null,
|
|
485
|
+
scopes: null,
|
|
486
|
+
sources: [{ path, detail: "semantic-release" }]
|
|
487
|
+
};
|
|
488
|
+
}
|
|
489
|
+
function parseChangesetConfig(path) {
|
|
490
|
+
return {
|
|
491
|
+
commitConvention: null,
|
|
492
|
+
pullRequestTitleConvention: null,
|
|
493
|
+
allowedTypes: null,
|
|
494
|
+
scopes: null,
|
|
495
|
+
sources: [{ path, detail: "changesets release flow" }]
|
|
496
|
+
};
|
|
497
|
+
}
|
|
498
|
+
function parseHuskyCommitMsg(path) {
|
|
499
|
+
return {
|
|
500
|
+
commitConvention: null,
|
|
501
|
+
pullRequestTitleConvention: null,
|
|
502
|
+
allowedTypes: null,
|
|
503
|
+
scopes: null,
|
|
504
|
+
sources: [{ path, detail: "husky commit-msg hook" }]
|
|
505
|
+
};
|
|
506
|
+
}
|
|
507
|
+
function parseSemanticPullRequestWorkflow(source, path) {
|
|
508
|
+
return parseSemanticPrWorkflow(source, path);
|
|
509
|
+
}
|
|
510
|
+
var COMMITLINT_FILE_NAMES = COMMITLINT_NAMES;
|
|
511
|
+
|
|
61
512
|
// src/policy/parsers/labels.ts
|
|
62
513
|
function parseLabels(payload) {
|
|
63
514
|
if (!Array.isArray(payload)) return [];
|
|
@@ -551,6 +1002,85 @@ async function discoverDocuments(root, scope) {
|
|
|
551
1002
|
}
|
|
552
1003
|
return { documents, sources };
|
|
553
1004
|
}
|
|
1005
|
+
function asPolicySources(discovered) {
|
|
1006
|
+
return discovered.sources.map((entry) => ({
|
|
1007
|
+
kind: "git-conventions",
|
|
1008
|
+
origin: "filesystem",
|
|
1009
|
+
path: entry.path,
|
|
1010
|
+
status: "found",
|
|
1011
|
+
detail: entry.detail
|
|
1012
|
+
}));
|
|
1013
|
+
}
|
|
1014
|
+
async function discoverGitConventions(root) {
|
|
1015
|
+
let merged = {
|
|
1016
|
+
commitConvention: null,
|
|
1017
|
+
pullRequestTitleConvention: null,
|
|
1018
|
+
allowedTypes: null,
|
|
1019
|
+
scopes: null,
|
|
1020
|
+
sources: []
|
|
1021
|
+
};
|
|
1022
|
+
const take = (extra) => {
|
|
1023
|
+
if (extra === null) return;
|
|
1024
|
+
merged = {
|
|
1025
|
+
commitConvention: merged.commitConvention ?? extra.commitConvention,
|
|
1026
|
+
pullRequestTitleConvention: merged.pullRequestTitleConvention ?? extra.pullRequestTitleConvention,
|
|
1027
|
+
allowedTypes: merged.allowedTypes ?? extra.allowedTypes,
|
|
1028
|
+
scopes: merged.scopes ?? extra.scopes,
|
|
1029
|
+
sources: [...merged.sources, ...extra.sources]
|
|
1030
|
+
};
|
|
1031
|
+
};
|
|
1032
|
+
const pkg = await readCapped(join(root, "package.json"));
|
|
1033
|
+
if (pkg !== null) {
|
|
1034
|
+
take(parsePackageJsonCommitlint(pkg.content));
|
|
1035
|
+
}
|
|
1036
|
+
for (const name of COMMITLINT_FILE_NAMES) {
|
|
1037
|
+
const found = await findFile(root, [name]);
|
|
1038
|
+
if (found === null) continue;
|
|
1039
|
+
const file = await readCapped(join(root, found));
|
|
1040
|
+
if (file === null) continue;
|
|
1041
|
+
take(parseCommitlintText(file.content, found));
|
|
1042
|
+
}
|
|
1043
|
+
for (const name of ["release-please-config.json", ".release-please-manifest.json"]) {
|
|
1044
|
+
const found = await findFile(root, [name]);
|
|
1045
|
+
if (found === null) continue;
|
|
1046
|
+
const file = await readCapped(join(root, found));
|
|
1047
|
+
if (file === null) continue;
|
|
1048
|
+
take(parseReleasePlease(file.content, found));
|
|
1049
|
+
}
|
|
1050
|
+
for (const name of [
|
|
1051
|
+
".releaserc",
|
|
1052
|
+
".releaserc.json",
|
|
1053
|
+
".releaserc.yaml",
|
|
1054
|
+
".releaserc.yml",
|
|
1055
|
+
"release.config.js"
|
|
1056
|
+
]) {
|
|
1057
|
+
const found = await findFile(root, [name]);
|
|
1058
|
+
if (found === null) continue;
|
|
1059
|
+
take(parseSemanticRelease(found));
|
|
1060
|
+
}
|
|
1061
|
+
const changeset = await findFile(join(root, ".changeset"), ["config.json"]);
|
|
1062
|
+
if (changeset !== null) {
|
|
1063
|
+
take(parseChangesetConfig(`.changeset/${changeset}`));
|
|
1064
|
+
}
|
|
1065
|
+
const husky = await findFile(join(root, ".husky"), ["commit-msg"]);
|
|
1066
|
+
if (husky !== null) {
|
|
1067
|
+
take(parseHuskyCommitMsg(`.husky/${husky}`));
|
|
1068
|
+
}
|
|
1069
|
+
const workflowDir = join(root, ".github", "workflows");
|
|
1070
|
+
for (const name of await listDirectory(workflowDir)) {
|
|
1071
|
+
if (!/\.ya?ml$/i.test(name)) continue;
|
|
1072
|
+
const file = await readCapped(join(workflowDir, name));
|
|
1073
|
+
if (file === null) continue;
|
|
1074
|
+
take(parseSemanticPullRequestWorkflow(file.content, `.github/workflows/${name}`));
|
|
1075
|
+
}
|
|
1076
|
+
return {
|
|
1077
|
+
commitConvention: merged.commitConvention,
|
|
1078
|
+
pullRequestTitleConvention: merged.pullRequestTitleConvention,
|
|
1079
|
+
allowedTypes: merged.allowedTypes,
|
|
1080
|
+
scopes: merged.scopes,
|
|
1081
|
+
sources: asPolicySources(merged)
|
|
1082
|
+
};
|
|
1083
|
+
}
|
|
554
1084
|
async function discoverBaseBranch(root, exec = defaultExec) {
|
|
555
1085
|
const options = { cwd: root, timeout: DISCOVERY_TIMEOUT_MS };
|
|
556
1086
|
try {
|
|
@@ -836,7 +1366,15 @@ function emptyPolicy(root, scope, enabled, sources) {
|
|
|
836
1366
|
enabled,
|
|
837
1367
|
issues: { templates: [], types: [], labels: [], titleConvention: null },
|
|
838
1368
|
pullRequests: { template: null, templates: [], baseBranch: null, titleConvention: null },
|
|
839
|
-
git: {
|
|
1369
|
+
git: {
|
|
1370
|
+
branchConvention: null,
|
|
1371
|
+
commitConvention: null,
|
|
1372
|
+
pullRequestTitleConvention: null,
|
|
1373
|
+
issueReference: null,
|
|
1374
|
+
typeMap: null,
|
|
1375
|
+
allowedTypes: null,
|
|
1376
|
+
scopes: null
|
|
1377
|
+
},
|
|
840
1378
|
docs: [],
|
|
841
1379
|
codeowners: null,
|
|
842
1380
|
sources
|
|
@@ -854,7 +1392,7 @@ function disabledSource(kind) {
|
|
|
854
1392
|
var DECLARATION_KINDS = {
|
|
855
1393
|
issues: "issue-templates",
|
|
856
1394
|
pullRequests: "pull-request-template",
|
|
857
|
-
git: "
|
|
1395
|
+
git: "git-conventions"
|
|
858
1396
|
};
|
|
859
1397
|
async function resolvePolicy(root, scope, options) {
|
|
860
1398
|
const warn = options.warn ?? printWarning;
|
|
@@ -870,12 +1408,15 @@ async function resolvePolicy(root, scope, options) {
|
|
|
870
1408
|
]);
|
|
871
1409
|
}
|
|
872
1410
|
const toggles = config.discovery;
|
|
873
|
-
const [templateDiscovery, prTemplates, documents, codeowners] = await Promise.all(
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
1411
|
+
const [templateDiscovery, prTemplates, documents, codeowners, gitConventions] = await Promise.all(
|
|
1412
|
+
[
|
|
1413
|
+
toggles.issueTemplates ? discoverIssueTemplates(root) : Promise.resolve({ templates: [], sources: [disabledSource("issue-templates")] }),
|
|
1414
|
+
toggles.pullRequestTemplate ? discoverPullRequestTemplates(root) : Promise.resolve({ templates: [], sources: [disabledSource("pull-request-template")] }),
|
|
1415
|
+
toggles.docs ? discoverDocuments(root, scope) : Promise.resolve({ documents: [], sources: [disabledSource("docs")] }),
|
|
1416
|
+
toggles.codeowners ? discoverCodeowners(root) : Promise.resolve({ content: null, sources: [disabledSource("codeowners")] }),
|
|
1417
|
+
discoverGitConventions(root)
|
|
1418
|
+
]
|
|
1419
|
+
);
|
|
879
1420
|
const wantsOrgTemplates = toggles.issueTemplates && templateDiscovery.templates.length === 0;
|
|
880
1421
|
const [baseBranch, slug] = await Promise.all([
|
|
881
1422
|
discoverBaseBranch(root, options.exec),
|
|
@@ -901,7 +1442,8 @@ async function resolvePolicy(root, scope, options) {
|
|
|
901
1442
|
...prTemplates.sources,
|
|
902
1443
|
...baseBranch.sources,
|
|
903
1444
|
...documents.sources,
|
|
904
|
-
...codeowners.sources
|
|
1445
|
+
...codeowners.sources,
|
|
1446
|
+
...gitConventions.sources
|
|
905
1447
|
];
|
|
906
1448
|
const discoveredPullRequests = {};
|
|
907
1449
|
if (baseBranch.baseBranch !== null) {
|
|
@@ -916,8 +1458,30 @@ async function resolvePolicy(root, scope, options) {
|
|
|
916
1458
|
discovered: discoveredPullRequests,
|
|
917
1459
|
project: config.pullRequests
|
|
918
1460
|
});
|
|
1461
|
+
const discoveredGit = {};
|
|
1462
|
+
if (gitConventions.commitConvention !== null) {
|
|
1463
|
+
discoveredGit.commitConvention = gitConventions.commitConvention;
|
|
1464
|
+
}
|
|
1465
|
+
if (gitConventions.pullRequestTitleConvention !== null) {
|
|
1466
|
+
discoveredGit.pullRequestTitleConvention = gitConventions.pullRequestTitleConvention;
|
|
1467
|
+
}
|
|
1468
|
+
if (gitConventions.allowedTypes !== null) {
|
|
1469
|
+
discoveredGit.allowedTypes = gitConventions.allowedTypes;
|
|
1470
|
+
}
|
|
1471
|
+
if (gitConventions.scopes !== null) {
|
|
1472
|
+
discoveredGit.scopes = gitConventions.scopes;
|
|
1473
|
+
}
|
|
919
1474
|
const git = mergeConfigLayers({
|
|
920
|
-
defaults: {
|
|
1475
|
+
defaults: {
|
|
1476
|
+
branchConvention: null,
|
|
1477
|
+
commitConvention: null,
|
|
1478
|
+
pullRequestTitleConvention: null,
|
|
1479
|
+
issueReference: null,
|
|
1480
|
+
typeMap: null,
|
|
1481
|
+
allowedTypes: null,
|
|
1482
|
+
scopes: null
|
|
1483
|
+
},
|
|
1484
|
+
discovered: discoveredGit,
|
|
921
1485
|
project: config.git
|
|
922
1486
|
});
|
|
923
1487
|
for (const group of ["issues", "pullRequests", "git"]) {
|
|
@@ -950,7 +1514,12 @@ async function resolvePolicy(root, scope, options) {
|
|
|
950
1514
|
},
|
|
951
1515
|
git: {
|
|
952
1516
|
branchConvention: git.branchConvention ?? null,
|
|
953
|
-
commitConvention: git.commitConvention ?? null
|
|
1517
|
+
commitConvention: git.commitConvention ?? null,
|
|
1518
|
+
pullRequestTitleConvention: git.pullRequestTitleConvention ?? null,
|
|
1519
|
+
issueReference: git.issueReference ?? null,
|
|
1520
|
+
typeMap: git.typeMap ?? null,
|
|
1521
|
+
allowedTypes: git.allowedTypes ?? gitConventions.allowedTypes,
|
|
1522
|
+
scopes: git.scopes ?? gitConventions.scopes
|
|
954
1523
|
},
|
|
955
1524
|
docs: documents.documents,
|
|
956
1525
|
codeowners: codeowners.content,
|
|
@@ -980,6 +1549,14 @@ async function loadRepositoryPolicy(options = {}) {
|
|
|
980
1549
|
}
|
|
981
1550
|
|
|
982
1551
|
export {
|
|
1552
|
+
DEFAULT_BRANCH_CONVENTION,
|
|
1553
|
+
isChangeType,
|
|
1554
|
+
branchName,
|
|
1555
|
+
archiveFolderName,
|
|
1556
|
+
resolveChangeType,
|
|
1557
|
+
commitMessage,
|
|
1558
|
+
pullRequestTitle,
|
|
1559
|
+
issueReferenceLines,
|
|
983
1560
|
loadRepositoryPolicy
|
|
984
1561
|
};
|
|
985
|
-
//# sourceMappingURL=chunk-
|
|
1562
|
+
//# sourceMappingURL=chunk-RVO7L4FX.js.map
|