@existdb/repo-xml-changelog-generator 0.0.0-stage → 1.0.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/LICENSE +10 -0
- package/README.md +129 -2
- package/index.js +100 -0
- package/lib/changelog.js +141 -0
- package/package.json +57 -4
package/LICENSE
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
GNU LESSER GENERAL PUBLIC LICENSE
|
|
2
|
+
Version 2.1, February 1999
|
|
3
|
+
|
|
4
|
+
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
|
|
5
|
+
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
6
|
+
Everyone is permitted to copy and distribute verbatim copies
|
|
7
|
+
of this license document, but changing it is not allowed.
|
|
8
|
+
|
|
9
|
+
[This work is licensed under the GNU Lesser General Public License,
|
|
10
|
+
version 2.1 or later. Full text at https://www.gnu.org/licenses/lgpl-2.1.txt.]
|
package/README.md
CHANGED
|
@@ -1,3 +1,130 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @existdb/repo-xml-changelog-generator
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
A [semantic-release](https://github.com/semantic-release/semantic-release) plugin that injects a new `<change>` entry into an [EXPath package descriptor](https://expath.org/spec/pkg) (typically `repo.xml.tmpl` for eXist-db XAR packages) based on the Conventional Commits between the previous release tag and the current release.
|
|
4
|
+
|
|
5
|
+
## What problem this solves
|
|
6
|
+
|
|
7
|
+
eXist-db apps and libraries that already use [semantic-release](https://github.com/semantic-release/semantic-release) for automated tagging and GitHub Releases still need to keep the in-XAR EXPath `<change>` history up to date. Previously, every adopter (monex, function-documentation, semver.xq) maintained its own copy of an `update-repo-changelog.js` script invoked via `@semantic-release/exec`. This plugin productizes that script into a single, configurable semantic-release plugin so the script doesn't need to be copy-pasted into every repo.
|
|
8
|
+
|
|
9
|
+
## Install
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npm install --save-dev @existdb/repo-xml-changelog-generator
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Usage
|
|
16
|
+
|
|
17
|
+
Add to your `.releaserc` plugin chain. Place it after the commit-analyzer / release-notes-generator (so `lastRelease` and `nextRelease` are populated) and before any plugin that builds the XAR (so the injected change is included in the built artifact):
|
|
18
|
+
|
|
19
|
+
```jsonc
|
|
20
|
+
{
|
|
21
|
+
"branches": ["master"],
|
|
22
|
+
"plugins": [
|
|
23
|
+
["@semantic-release/commit-analyzer", { "preset": "conventionalcommits" }],
|
|
24
|
+
["@semantic-release/release-notes-generator", { "preset": "conventionalcommits" }],
|
|
25
|
+
|
|
26
|
+
// 1) bump the version in-memory on the CI runner
|
|
27
|
+
["@semantic-release/exec", {
|
|
28
|
+
"prepareCmd": "npm version ${nextRelease.version} --no-git-tag-version --allow-same-version"
|
|
29
|
+
}],
|
|
30
|
+
|
|
31
|
+
// 2) inject the <change> entry into repo.xml.tmpl
|
|
32
|
+
"@existdb/repo-xml-changelog-generator",
|
|
33
|
+
|
|
34
|
+
// 3) build the XAR (now sees both the bumped version + the injected <change>)
|
|
35
|
+
["@semantic-release/exec", { "publishCmd": "npm run build" }],
|
|
36
|
+
|
|
37
|
+
// 4) tag + GitHub Release + asset upload via REST
|
|
38
|
+
["@semantic-release/github", {
|
|
39
|
+
"assets": [{ "path": "dist/*.xar", "label": "EXPath Package (XAR)" }]
|
|
40
|
+
}]
|
|
41
|
+
]
|
|
42
|
+
}
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
**Do not** include `@semantic-release/git` in the plugin chain. The mutation this plugin performs is in-memory on the CI runner; the on-disk `repo.xml.tmpl` in your default branch stays at its development-placeholder state, and the per-release changelog history lives in git tags + GitHub Releases. See [Design rationale](#design-rationale) below.
|
|
46
|
+
|
|
47
|
+
## Configuration
|
|
48
|
+
|
|
49
|
+
| Option | Type | Default | Notes |
|
|
50
|
+
|--------|------|---------|-------|
|
|
51
|
+
| `tmplPath` | string | `'repo.xml.tmpl'` | Path to the EXPath repo descriptor template, relative to `cwd`. |
|
|
52
|
+
|
|
53
|
+
```jsonc
|
|
54
|
+
["@existdb/repo-xml-changelog-generator", { "tmplPath": "src/repo.xml.tmpl" }]
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## What it does
|
|
58
|
+
|
|
59
|
+
### `verifyConditions` (runs early, before any release work)
|
|
60
|
+
|
|
61
|
+
- Confirms `tmplPath` exists.
|
|
62
|
+
- Confirms the descriptor contains a `<changelog xmlns="http://exist-db.org/xquery/repo">` element.
|
|
63
|
+
|
|
64
|
+
If either check fails, semantic-release aborts before doing anything. This is the right place to surface configuration mistakes, not the middle of a release.
|
|
65
|
+
|
|
66
|
+
### `prepare` (runs after version is computed)
|
|
67
|
+
|
|
68
|
+
For each conventional commit since `context.lastRelease.gitTag`:
|
|
69
|
+
|
|
70
|
+
- Skip non-typed commits (those that don't match the Conventional Commits grammar).
|
|
71
|
+
- Group by type using `conventional-changelog-conventionalcommits`.
|
|
72
|
+
- Render each commit as `Prefix: scope: subject` where Prefix is one of:
|
|
73
|
+
- `New` (for `feat:`)
|
|
74
|
+
- `Fix` (for `fix:`)
|
|
75
|
+
- `Improvement` (for `perf:`)
|
|
76
|
+
- `Revert` (for `revert:`)
|
|
77
|
+
- or the literal type for other categories.
|
|
78
|
+
- Render breaking changes as `Breaking change: <text>` from `BREAKING CHANGE:` footers.
|
|
79
|
+
|
|
80
|
+
The rendered items are wrapped in a `<change version="X.Y.Z"><ul xmlns="http://www.w3.org/1999/xhtml">…</ul></change>` and inserted at the **top** of the existing `<changelog>` element (most recent first).
|
|
81
|
+
|
|
82
|
+
### Edge cases
|
|
83
|
+
|
|
84
|
+
| Situation | Behavior |
|
|
85
|
+
|-----------|----------|
|
|
86
|
+
| No `lastRelease.gitTag` (first release) | Skip injection. Log a note. Curate the initial `<change>` entry manually in the template. |
|
|
87
|
+
| No conventional commits since last tag | Skip injection. Log "no notable commits". |
|
|
88
|
+
| Configured `tmplPath` doesn't exist | `verifyConditions` aborts the release with a clear error. |
|
|
89
|
+
| `<changelog>` element missing | `verifyConditions` aborts with instructions to add an empty `<changelog/>`. |
|
|
90
|
+
| `lastRelease.gitTag` is e.g. `1.2.3` but the actual tag is `v1.2.3` | Both forms are tried; the first one that resolves wins. |
|
|
91
|
+
|
|
92
|
+
## Design rationale
|
|
93
|
+
|
|
94
|
+
### Why in-memory, not push-back?
|
|
95
|
+
|
|
96
|
+
The default approach for many semantic-release setups is to use `@semantic-release/git` to commit the mutated files (`package.json`, `CHANGELOG.md`, etc.) back to the default branch. For eXist-db org repos with branch protection that requires PRs, this means the GitHub Actions token can't push the release commit — you need a PAT or a GitHub App to bypass protection. That's operational overhead (PAT rotation, App installation per repo, secret management).
|
|
97
|
+
|
|
98
|
+
The alternative — used by `@existdb/xst`, `@existdb/node-exist`, `@existdb/gulp-exist`, and (since 2026-05-19) `eXist-db/monex` and `eXist-db/function-documentation` — is to **pin the default-branch version to `0.0.0-development` permanently**, do all the version + changelog work in-memory on the CI runner, and let the built XAR carry the real version. No push-back, no token plumbing, branch protection works as intended.
|
|
99
|
+
|
|
100
|
+
This plugin is designed for that workflow. (It would also work alongside `@semantic-release/git`, but the apps in the org don't need that path.)
|
|
101
|
+
|
|
102
|
+
### Why not just publish the existing script as-is?
|
|
103
|
+
|
|
104
|
+
Because every adopter would still have to copy it into their repo and invoke it via `@semantic-release/exec` prepareCmd. The plugin form:
|
|
105
|
+
|
|
106
|
+
- Hooks into semantic-release's lifecycle directly (gets `lastRelease`, `nextRelease`, `logger`, `cwd` natively).
|
|
107
|
+
- Adds proper `verifyConditions` so misconfiguration is caught early.
|
|
108
|
+
- Lets adopters install it as an npm dependency instead of vendoring a 170-line script.
|
|
109
|
+
- Centralizes future improvements (e.g. cross-link PRs/issues, support `expath-pkg.xml.tmpl` version sync, support custom commit-type → prefix mappings).
|
|
110
|
+
|
|
111
|
+
### Why a Node plugin, not an XQuery one?
|
|
112
|
+
|
|
113
|
+
semantic-release itself is a Node tool and runs in Node. The plugin API is Node-native. Reimplementing in XQuery would mean either (a) standing up a separate XQuery runtime in CI just to run the changelog hook, or (b) calling out to it via HTTP/shell. Both add complexity for no user-visible benefit. The plugin's output (the `<change>` element it emits) is the data that lives in the XQuery world — the producer can be in any language.
|
|
114
|
+
|
|
115
|
+
## Releasing this package
|
|
116
|
+
|
|
117
|
+
This plugin releases itself with semantic-release, eating its own dog food. Merges to `main` run the [CI workflow](.github/workflows/release.yml): the test matrix runs, then `semantic-release` analyzes the Conventional Commits, computes the next version, publishes to npm (`@existdb` scope), and creates the GitHub Release. The in-tree `version` stays pinned at `0.0.0-development`; the real version is set in-memory at release time (the same no-push pattern this plugin advocates for adopters).
|
|
118
|
+
|
|
119
|
+
Commit messages are linted against [Conventional Commits](https://www.conventionalcommits.org/) via commitlint — locally through a husky `commit-msg` hook, and in CI on every pull request.
|
|
120
|
+
|
|
121
|
+
## Acknowledgements
|
|
122
|
+
|
|
123
|
+
- The core changelog logic was originally written for [eXist-db/semver.xq#69](https://github.com/eXist-db/semver.xq/pull/69) and adopted in [eXist-db/monex](https://github.com/eXist-db/monex) and [eXist-db/function-documentation](https://github.com/eXist-db/function-documentation). This plugin is a refactor of that proven logic.
|
|
124
|
+
- @line-o pointed out that the no-push pattern matches what `@existdb/xst`, `@existdb/node-exist`, and `@existdb/gulp-exist` already do. That feedback shaped this plugin's design.
|
|
125
|
+
|
|
126
|
+
This plugin corresponds to §5.3 of a broader release-strategy proposal being circulated among the eXist-db devs for automating EXPath package releases.
|
|
127
|
+
|
|
128
|
+
## License
|
|
129
|
+
|
|
130
|
+
LGPL-2.1-or-later (matching the eXist-db org convention).
|
package/index.js
ADDED
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @existdb/repo-xml-changelog-generator
|
|
3
|
+
*
|
|
4
|
+
* semantic-release plugin that injects a new `<change>` entry into an EXPath
|
|
5
|
+
* package descriptor (typically `repo.xml.tmpl`) based on the Conventional
|
|
6
|
+
* Commits between the previous release tag and the current release.
|
|
7
|
+
*
|
|
8
|
+
* Lifecycle hooks:
|
|
9
|
+
*
|
|
10
|
+
* verifyConditions(pluginConfig, context)
|
|
11
|
+
* Confirms the configured descriptor file exists and contains a
|
|
12
|
+
* `<changelog xmlns="http://exist-db.org/xquery/repo">` element. Fails
|
|
13
|
+
* fast (before the release is computed) with an actionable error if not.
|
|
14
|
+
*
|
|
15
|
+
* prepare(pluginConfig, context)
|
|
16
|
+
* Reads conventional commits since `context.lastRelease.gitTag`, builds
|
|
17
|
+
* a list of human-readable change items, and inserts a new `<change
|
|
18
|
+
* version="X.Y.Z">` element with those items at the top of `<changelog>`.
|
|
19
|
+
* Writes the descriptor back to disk. The mutation is in-memory on the
|
|
20
|
+
* CI runner — pair with @semantic-release/github (REST-based release
|
|
21
|
+
* creation) and DO NOT use @semantic-release/git, so the on-disk file
|
|
22
|
+
* in master stays at its dev-placeholder state. See README for details.
|
|
23
|
+
*
|
|
24
|
+
* Config options (all optional):
|
|
25
|
+
*
|
|
26
|
+
* tmplPath: string (default: 'repo.xml.tmpl')
|
|
27
|
+
* Path to the EXPath repo descriptor template, relative to cwd.
|
|
28
|
+
*/
|
|
29
|
+
|
|
30
|
+
import { existsSync } from 'fs'
|
|
31
|
+
import { join } from 'path'
|
|
32
|
+
import { buildChangeItems, insertChangeEntry } from './lib/changelog.js'
|
|
33
|
+
|
|
34
|
+
const REPO_NS = 'http://exist-db.org/xquery/repo'
|
|
35
|
+
|
|
36
|
+
function resolveTmplPath (pluginConfig, context) {
|
|
37
|
+
return join(context.cwd ?? process.cwd(), pluginConfig.tmplPath ?? 'repo.xml.tmpl')
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
async function readChangelogContainer (tmplPath) {
|
|
41
|
+
const { readFileSync } = await import('fs')
|
|
42
|
+
const { DOMParser } = await import('@xmldom/xmldom')
|
|
43
|
+
const tmpl = readFileSync(tmplPath, 'utf8')
|
|
44
|
+
const doc = new DOMParser().parseFromString(tmpl, 'text/xml')
|
|
45
|
+
return doc.getElementsByTagNameNS(REPO_NS, 'changelog').item(0)
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export async function verifyConditions (pluginConfig, context) {
|
|
49
|
+
const { logger } = context
|
|
50
|
+
const tmplPath = resolveTmplPath(pluginConfig, context)
|
|
51
|
+
|
|
52
|
+
if (!existsSync(tmplPath)) {
|
|
53
|
+
throw new Error(
|
|
54
|
+
`[repo-xml-changelog-generator] Template not found: ${tmplPath}\n` +
|
|
55
|
+
`Set the \`tmplPath\` plugin option if your descriptor lives elsewhere.`
|
|
56
|
+
)
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const changelog = await readChangelogContainer(tmplPath)
|
|
60
|
+
if (!changelog) {
|
|
61
|
+
throw new Error(
|
|
62
|
+
`[repo-xml-changelog-generator] No <changelog xmlns="${REPO_NS}"> element found in ${tmplPath}.\n` +
|
|
63
|
+
`Add an empty <changelog/> child inside <meta> to enable change-entry injection.`
|
|
64
|
+
)
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
logger.log(`[repo-xml-changelog-generator] verified ${tmplPath}`)
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export async function prepare (pluginConfig, context) {
|
|
71
|
+
const { logger, lastRelease, nextRelease } = context
|
|
72
|
+
const tmplPath = resolveTmplPath(pluginConfig, context)
|
|
73
|
+
|
|
74
|
+
if (!lastRelease?.gitTag) {
|
|
75
|
+
logger.log(
|
|
76
|
+
'[repo-xml-changelog-generator] No previous release tag — skipping changelog injection. ' +
|
|
77
|
+
'(First-release entries should be curated manually in repo.xml.tmpl.)'
|
|
78
|
+
)
|
|
79
|
+
return
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
const items = await buildChangeItems({
|
|
83
|
+
prevTag: lastRelease.gitTag,
|
|
84
|
+
version: nextRelease.version,
|
|
85
|
+
cwd: context.cwd
|
|
86
|
+
})
|
|
87
|
+
|
|
88
|
+
if (items.length === 0) {
|
|
89
|
+
logger.log(`[repo-xml-changelog-generator] No notable commits since ${lastRelease.gitTag} — skipping.`)
|
|
90
|
+
return
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
insertChangeEntry({
|
|
94
|
+
tmplPath,
|
|
95
|
+
version: nextRelease.version,
|
|
96
|
+
items
|
|
97
|
+
})
|
|
98
|
+
|
|
99
|
+
logger.log(`[repo-xml-changelog-generator] inserted ${items.length} change item(s) for ${nextRelease.version} into ${tmplPath}`)
|
|
100
|
+
}
|
package/lib/changelog.js
ADDED
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Core changelog logic, factored out of the plugin entry so it can be
|
|
3
|
+
* exercised by unit tests with mock git input.
|
|
4
|
+
*
|
|
5
|
+
* Lifted from eXist-db/semver.xq's update-repo-changelog.js and adapted
|
|
6
|
+
* to the semantic-release plugin shape (read tags from arguments, not
|
|
7
|
+
* CLI flags; resolve paths against an explicit cwd).
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { execSync } from 'child_process'
|
|
11
|
+
import { readFileSync, writeFileSync } from 'fs'
|
|
12
|
+
import { DOMParser, XMLSerializer } from '@xmldom/xmldom'
|
|
13
|
+
import { CommitParser } from 'conventional-commits-parser'
|
|
14
|
+
import { writeChangelogString } from 'conventional-changelog-writer'
|
|
15
|
+
import conventionalChangelogConventionalCommits from 'conventional-changelog-conventionalcommits'
|
|
16
|
+
|
|
17
|
+
const REPO_NS = 'http://exist-db.org/xquery/repo'
|
|
18
|
+
const HTML_NS = 'http://www.w3.org/1999/xhtml'
|
|
19
|
+
|
|
20
|
+
const SECTION_PREFIX = {
|
|
21
|
+
Features: 'New',
|
|
22
|
+
'Bug Fixes': 'Fix',
|
|
23
|
+
'Performance Improvements': 'Improvement',
|
|
24
|
+
Reverts: 'Revert'
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const XML_MAIN_TEMPLATE =
|
|
28
|
+
'{{#each noteGroups}}' +
|
|
29
|
+
'{{#each notes}}' +
|
|
30
|
+
'<li>Breaking change: {{text}}</li>\n' +
|
|
31
|
+
'{{/each}}' +
|
|
32
|
+
'{{/each}}' +
|
|
33
|
+
'{{#each commitGroups}}' +
|
|
34
|
+
'{{#each commits}}' +
|
|
35
|
+
'{{#unless isBreaking}}<li>{{prefix}}: {{#if scope}}{{scope}}: {{/if}}{{subject}}</li>\n{{/unless}}' +
|
|
36
|
+
'{{/each}}' +
|
|
37
|
+
'{{/each}}'
|
|
38
|
+
|
|
39
|
+
function tagExists (tag, cwd) {
|
|
40
|
+
try {
|
|
41
|
+
execSync(`git rev-parse "${tag}"`, { stdio: 'pipe', cwd })
|
|
42
|
+
return true
|
|
43
|
+
} catch {
|
|
44
|
+
return false
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function getRawCommits ({ prevTag, cwd }) {
|
|
49
|
+
const ref = tagExists(prevTag, cwd) ? prevTag
|
|
50
|
+
: tagExists(`v${prevTag}`, cwd) ? `v${prevTag}`
|
|
51
|
+
: null
|
|
52
|
+
if (!ref) throw new Error(`[repo-xml-changelog-generator] Tag not found: ${prevTag} or v${prevTag}`)
|
|
53
|
+
|
|
54
|
+
const hashes = execSync(`git log ${ref}..HEAD --format=%H`, { encoding: 'utf8', cwd })
|
|
55
|
+
.trim().split('\n').filter(Boolean)
|
|
56
|
+
|
|
57
|
+
return hashes.map(hash =>
|
|
58
|
+
execSync(`git log -1 --format=%B ${hash}`, { encoding: 'utf8', cwd }).trim()
|
|
59
|
+
)
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export async function buildChangeItems ({ prevTag, version, cwd }) {
|
|
63
|
+
const rawCommits = getRawCommits({ prevTag, cwd })
|
|
64
|
+
if (rawCommits.length === 0) return []
|
|
65
|
+
|
|
66
|
+
const { parser: parserOpts, writer: writerOpts } = await conventionalChangelogConventionalCommits()
|
|
67
|
+
const commitParser = new CommitParser(parserOpts)
|
|
68
|
+
|
|
69
|
+
const parsed = rawCommits.map(msg => commitParser.parse(msg)).filter(c => c.type)
|
|
70
|
+
if (parsed.length === 0) return []
|
|
71
|
+
|
|
72
|
+
const presetTransform = writerOpts.transform
|
|
73
|
+
const writerOptions = {
|
|
74
|
+
...writerOpts,
|
|
75
|
+
mainTemplate: XML_MAIN_TEMPLATE,
|
|
76
|
+
headerPartial: '',
|
|
77
|
+
commitPartial: '',
|
|
78
|
+
footerPartial: '',
|
|
79
|
+
transform (commit, context) {
|
|
80
|
+
const transformed = presetTransform(commit, context)
|
|
81
|
+
if (!transformed) return null
|
|
82
|
+
if (transformed.notes.length > 0) {
|
|
83
|
+
transformed.isBreaking = true
|
|
84
|
+
return transformed
|
|
85
|
+
}
|
|
86
|
+
transformed.prefix = SECTION_PREFIX[transformed.type] ?? transformed.type
|
|
87
|
+
return transformed
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
const output = await writeChangelogString(parsed, { version }, writerOptions)
|
|
92
|
+
|
|
93
|
+
const doc = new DOMParser().parseFromString(
|
|
94
|
+
`<ul xmlns="${HTML_NS}">${output}</ul>`,
|
|
95
|
+
'text/xml'
|
|
96
|
+
)
|
|
97
|
+
const liNodes = doc.getElementsByTagNameNS(HTML_NS, 'li')
|
|
98
|
+
const items = []
|
|
99
|
+
for (let i = 0; i < liNodes.length; i++) {
|
|
100
|
+
const text = liNodes.item(i).textContent
|
|
101
|
+
if (text) items.push(text)
|
|
102
|
+
}
|
|
103
|
+
return items
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
export function insertChangeEntry ({ tmplPath, version, items }) {
|
|
107
|
+
const tmpl = readFileSync(tmplPath, 'utf8')
|
|
108
|
+
const doc = new DOMParser().parseFromString(tmpl, 'text/xml')
|
|
109
|
+
|
|
110
|
+
const changelog = doc.getElementsByTagNameNS(REPO_NS, 'changelog').item(0)
|
|
111
|
+
if (!changelog) throw new Error(`[repo-xml-changelog-generator] <changelog> not found in ${tmplPath}`)
|
|
112
|
+
|
|
113
|
+
const change = doc.createElementNS(REPO_NS, 'change')
|
|
114
|
+
change.setAttribute('version', version)
|
|
115
|
+
change.appendChild(doc.createTextNode('\n '))
|
|
116
|
+
|
|
117
|
+
const ul = doc.createElementNS(HTML_NS, 'ul')
|
|
118
|
+
for (const item of items) {
|
|
119
|
+
ul.appendChild(doc.createTextNode('\n '))
|
|
120
|
+
const li = doc.createElementNS(HTML_NS, 'li')
|
|
121
|
+
li.textContent = item
|
|
122
|
+
ul.appendChild(li)
|
|
123
|
+
}
|
|
124
|
+
ul.appendChild(doc.createTextNode('\n '))
|
|
125
|
+
|
|
126
|
+
change.appendChild(ul)
|
|
127
|
+
change.appendChild(doc.createTextNode('\n '))
|
|
128
|
+
|
|
129
|
+
let firstChange = null
|
|
130
|
+
for (let i = 0; i < changelog.childNodes.length; i++) {
|
|
131
|
+
if (changelog.childNodes.item(i).nodeType === 1) {
|
|
132
|
+
firstChange = changelog.childNodes.item(i)
|
|
133
|
+
break
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
changelog.insertBefore(change, firstChange)
|
|
138
|
+
changelog.insertBefore(doc.createTextNode('\n '), firstChange)
|
|
139
|
+
|
|
140
|
+
writeFileSync(tmplPath, new XMLSerializer().serializeToString(doc))
|
|
141
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,59 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@existdb/repo-xml-changelog-generator",
|
|
3
|
-
"version": "
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "1.0.1",
|
|
4
|
+
"description": "semantic-release plugin: inject conventional-commit changelog entries into EXPath package repo.xml descriptors (eXist-db / BaseX / MarkLogic XAR packages)",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "index.js",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": "./index.js"
|
|
9
|
+
},
|
|
10
|
+
"files": [
|
|
11
|
+
"index.js",
|
|
12
|
+
"lib/",
|
|
13
|
+
"README.md",
|
|
14
|
+
"LICENSE"
|
|
15
|
+
],
|
|
16
|
+
"scripts": {
|
|
17
|
+
"test": "node --test 'test/**/*.test.js'",
|
|
18
|
+
"prepare": "husky || true"
|
|
19
|
+
},
|
|
20
|
+
"keywords": [
|
|
21
|
+
"semantic-release",
|
|
22
|
+
"semantic-release-plugin",
|
|
23
|
+
"expath",
|
|
24
|
+
"exist-db",
|
|
25
|
+
"xar",
|
|
26
|
+
"changelog"
|
|
27
|
+
],
|
|
28
|
+
"author": "Joe Wicentowski",
|
|
29
|
+
"license": "LGPL-2.1-or-later",
|
|
30
|
+
"repository": {
|
|
31
|
+
"type": "git",
|
|
32
|
+
"url": "git+https://github.com/eXist-db/repo-xml-changelog-generator.git"
|
|
33
|
+
},
|
|
34
|
+
"bugs": {
|
|
35
|
+
"url": "https://github.com/eXist-db/repo-xml-changelog-generator/issues"
|
|
36
|
+
},
|
|
37
|
+
"homepage": "https://github.com/eXist-db/repo-xml-changelog-generator#readme",
|
|
38
|
+
"publishConfig": {
|
|
39
|
+
"access": "public"
|
|
40
|
+
},
|
|
41
|
+
"engines": {
|
|
42
|
+
"node": ">=22"
|
|
43
|
+
},
|
|
44
|
+
"peerDependencies": {
|
|
45
|
+
"semantic-release": ">=22"
|
|
46
|
+
},
|
|
47
|
+
"dependencies": {
|
|
48
|
+
"@xmldom/xmldom": "^0.9.12",
|
|
49
|
+
"conventional-changelog-conventionalcommits": "^9.0.0",
|
|
50
|
+
"conventional-changelog-writer": "^8.0.0",
|
|
51
|
+
"conventional-commits-parser": "^6.0.0"
|
|
52
|
+
},
|
|
53
|
+
"devDependencies": {
|
|
54
|
+
"@commitlint/cli": "^19.0.0",
|
|
55
|
+
"@commitlint/config-conventional": "^19.0.0",
|
|
56
|
+
"husky": "^9.0.0",
|
|
57
|
+
"semantic-release": "^25.0.9"
|
|
58
|
+
}
|
|
59
|
+
}
|