@entro314labs/release-kit 2.9.1 → 2.9.3
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/package.json +3 -3
- package/release.mjs +45 -7
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@entro314labs/release-kit",
|
|
3
|
-
"version": "2.9.
|
|
3
|
+
"version": "2.9.3",
|
|
4
4
|
"description": "Single-file, zero-dependency release mechanism for JS/TS/Node projects: version bump, changelog roll, commit, annotated tag, push, publish, GitHub release",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"changelog",
|
|
@@ -49,8 +49,8 @@
|
|
|
49
49
|
"release": "node release.mjs"
|
|
50
50
|
},
|
|
51
51
|
"devDependencies": {
|
|
52
|
-
"oxfmt": "^0.
|
|
53
|
-
"oxlint": "^1.
|
|
52
|
+
"oxfmt": "^0.65.0",
|
|
53
|
+
"oxlint": "^1.80.0",
|
|
54
54
|
"semver": "^7.8.5"
|
|
55
55
|
},
|
|
56
56
|
"engines": {
|
package/release.mjs
CHANGED
|
@@ -748,10 +748,19 @@ function changelogFromCommits(commits, links = null, hidden = [], contributors =
|
|
|
748
748
|
|
|
749
749
|
const known = new Set(CHANGELOG_SECTIONS.map((s) => s.type))
|
|
750
750
|
const hiddenTypes = new Set(hidden)
|
|
751
|
+
// A dependency bump is conventionally written `chore(deps):` or `build(deps):` — the scope
|
|
752
|
+
// carries the meaning, and it is what dependabot, renovate and this tool's own drafter
|
|
753
|
+
// emit, because `deps:` is not in @commitlint/config-conventional's type-enum. Without
|
|
754
|
+
// this those bumps sit in Miscellaneous Chores and Build System while the Dependencies
|
|
755
|
+
// section stays empty. `fix(deps):` is left where it is: a fix is still a bug fix.
|
|
756
|
+
const isDependency = (c) =>
|
|
757
|
+
c.type === 'deps' || (c.scope === 'deps' && (c.type === 'chore' || c.type === 'build'))
|
|
751
758
|
for (const { type, section } of CHANGELOG_SECTIONS) {
|
|
752
759
|
if (hiddenTypes.has(type)) continue
|
|
753
|
-
const inSection = parsed.filter(
|
|
754
|
-
|
|
760
|
+
const inSection = parsed.filter((c) =>
|
|
761
|
+
type === 'deps'
|
|
762
|
+
? isDependency(c)
|
|
763
|
+
: !isDependency(c) && (c.type === type || (type === 'feat' && c.type === 'feature')),
|
|
755
764
|
)
|
|
756
765
|
if (!inSection.length) continue
|
|
757
766
|
lines.push(`### ${section}`, '')
|
|
@@ -913,7 +922,24 @@ const CHANGELOG_TYPES = CHANGELOG_SECTIONS.map((s) => s.type)
|
|
|
913
922
|
|
|
914
923
|
/** The drafter's types plus `feature`, the alias `changelogFromCommits` folds into feat. */
|
|
915
924
|
const KNOWN_TYPES = new Set([...CHANGELOG_TYPES, 'feature'])
|
|
916
|
-
|
|
925
|
+
|
|
926
|
+
/**
|
|
927
|
+
* The types this tool will write into somebody else's repository.
|
|
928
|
+
*
|
|
929
|
+
* Reading history is permissive on purpose — KNOWN_TYPES files whatever people wrote — but
|
|
930
|
+
* drafting is not, because a drafted subject has to survive the repository's own commit-msg
|
|
931
|
+
* hook. The near-universal gate is @commitlint/config-conventional, whose type-enum is
|
|
932
|
+
* exactly CHANGELOG_TYPES minus `deps`, and a drafted `deps: update dev tooling` aborted a
|
|
933
|
+
* release mid-commit with "type must be one of [build, chore, ci, ...]".
|
|
934
|
+
*
|
|
935
|
+
* Dependency work is still drafted and still reaches the Dependencies section: as
|
|
936
|
+
* `chore(deps):`, the scope dependabot and renovate emit, which `changelogFromCommits`
|
|
937
|
+
* routes there. Only the spelling the enum refuses is off the table.
|
|
938
|
+
*/
|
|
939
|
+
const WRITE_TYPES = CHANGELOG_TYPES.filter((type) => type !== 'deps')
|
|
940
|
+
|
|
941
|
+
/** The gate on a drafted subject — WRITE_TYPES, not KNOWN_TYPES. See WRITE_TYPES. */
|
|
942
|
+
const CONVENTIONAL_RE = new RegExp(`^(${WRITE_TYPES.join('|')})(\\([^)]+\\))?!?: .+`)
|
|
917
943
|
|
|
918
944
|
/**
|
|
919
945
|
* Check commit subjects against the grammar the rest of this file reads.
|
|
@@ -971,7 +997,9 @@ function draftCommitMessage() {
|
|
|
971
997
|
'Write a Conventional Commits message for these staged changes.',
|
|
972
998
|
'',
|
|
973
999
|
'Rules:',
|
|
974
|
-
`- Subject: "<type>(<optional scope>): <description>" where type is one of ${
|
|
1000
|
+
`- Subject: "<type>(<optional scope>): <description>" where type is one of ${WRITE_TYPES.join(', ')}.`,
|
|
1001
|
+
'- For a dependency update use the `deps` scope — `chore(deps): ...` — which the',
|
|
1002
|
+
' changelog files under Dependencies.',
|
|
975
1003
|
'- Subject in the imperative mood, no trailing period, under 72 characters.',
|
|
976
1004
|
'- Add a body only if the change needs explanation; separate it with a blank line.',
|
|
977
1005
|
'- Output the raw commit message and nothing else: no markdown fences, no preamble.',
|
|
@@ -1377,16 +1405,26 @@ const sectionOffsets = (text) => [...text.matchAll(/^## .*$/gm)].map((m) => m.in
|
|
|
1377
1405
|
*/
|
|
1378
1406
|
function insertChangelogSection(text, version, date, body) {
|
|
1379
1407
|
const entry = `## [${version}] - ${date}\n\n${body}\n`
|
|
1380
|
-
|
|
1408
|
+
const offsets = sectionOffsets(text)
|
|
1409
|
+
let comparable = false
|
|
1410
|
+
for (const offset of offsets) {
|
|
1381
1411
|
const heading = /^## \[?v?([\d.]+(?:-[\w.]+)?)\]?/m.exec(
|
|
1382
1412
|
text.slice(offset, text.indexOf('\n', offset)),
|
|
1383
1413
|
)
|
|
1384
|
-
//
|
|
1385
|
-
|
|
1414
|
+
// Headings that carry no version — [Unreleased], and the date headings a changelog
|
|
1415
|
+
// that never adopted semver is made of — are not positions this can order against.
|
|
1416
|
+
if (!heading || !parseVersion(heading[1])) continue
|
|
1417
|
+
comparable = true
|
|
1386
1418
|
if (compareVersions(version, heading[1]) > 0) {
|
|
1387
1419
|
return `${text.slice(0, offset)}${entry}\n${text.slice(offset)}`
|
|
1388
1420
|
}
|
|
1389
1421
|
}
|
|
1422
|
+
// Falling out of the loop means every version section is newer, so the release belongs
|
|
1423
|
+
// at the foot. With nothing to compare against it belongs at the head instead: appending
|
|
1424
|
+
// to a date-headed changelog would file the release below its oldest entry.
|
|
1425
|
+
if (!comparable && offsets.length) {
|
|
1426
|
+
return `${text.slice(0, offsets[0])}${entry}\n${text.slice(offsets[0])}`
|
|
1427
|
+
}
|
|
1390
1428
|
const trimmed = text.trimEnd()
|
|
1391
1429
|
return `${trimmed}\n\n${entry}`
|
|
1392
1430
|
}
|