relion 0.42.1 → 0.44.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 +44 -126
- package/dist/cli.js +13 -14
- package/package.json +9 -8
- package/dist/index.d.ts +0 -62
- package/dist/index.js +0 -4
package/README.md
CHANGED
|
@@ -1,152 +1,72 @@
|
|
|
1
1
|
<div align="center">
|
|
2
2
|
<picture>
|
|
3
|
-
<source media="(prefers-color-scheme: dark)" srcset=".github/logo-
|
|
4
|
-
<img alt="logo" src=".github/logo-
|
|
3
|
+
<source media="(prefers-color-scheme: dark)" srcset=".github/logo-dark.png">
|
|
4
|
+
<img alt="logo" src=".github/logo-light.png">
|
|
5
5
|
</picture>
|
|
6
6
|
<br>
|
|
7
7
|
<a href="https://www.npmjs.com/package/relion"><img src="https://img.shields.io/npm/v/relion?label=npm&logo=npm&style=flat-square&color=B2BFFF&labelColor=303145" alt="npm version"/></a>
|
|
8
|
-
<a href="https://www.npmjs.com/package/relion"><img src="https://img.badgesize.io/https:/unpkg.com/relion/dist/
|
|
8
|
+
<a href="https://www.npmjs.com/package/relion"><img src="https://img.badgesize.io/https:/unpkg.com/relion/dist/cli.js?label=Size&logo=hackthebox&logoColor=c97026&style=flat-square&color=B2BFFF&labelColor=303145" alt="runtime size"/></a>
|
|
9
9
|
<a href="https://github.com/kh4f/relion/blob/master/LICENSE"><img src="https://img.shields.io/github/license/kh4f/relion?style=flat-square&label=%F0%9F%9B%A1%EF%B8%8F%20License&color=B2BFFF&labelColor=303145" alt="license"></a>
|
|
10
10
|
<a href="https://github.com/kh4f/relion/issues?q=is%3Aissue+is%3Aopen+label%3Abug"><img src="https://img.shields.io/github/issues/kh4f/relion/bug?label=%F0%9F%90%9B%20Bugs&style=flat-square&color=B2BFFF&labelColor=303145" alt="open bugs"></a>
|
|
11
11
|
<br><br>
|
|
12
|
-
<b>A
|
|
12
|
+
<b>A zero‑config npm lib for automating the release workflow:<br></b> version bumping, release commit & tag creation, and AI‑assisted changelog generation
|
|
13
13
|
<br><br>
|
|
14
14
|
<p><b>
|
|
15
|
-
<a href="
|
|
16
|
-
<a href="#%EF%B8%8F-
|
|
17
|
-
<a href="#-api-usage">API</a> •
|
|
18
|
-
<a href="#%EF%B8%8F-workflow-steps">Workflow Steps</a> •
|
|
15
|
+
<a href="#%EF%B8%8F-usage">Usage</a> •
|
|
16
|
+
<a href="#%EF%B8%8F-release-workflow">Release Workflow</a> •
|
|
19
17
|
<a href="#-changelog-generation">Changelog Generation</a>
|
|
20
18
|
</b></p>
|
|
21
19
|
<br>
|
|
22
20
|
</div>
|
|
23
21
|
|
|
24
|
-
##
|
|
22
|
+
## 🕹️ Usage
|
|
25
23
|
|
|
26
24
|
```bash
|
|
27
|
-
|
|
28
|
-
bunx relion # or run directly
|
|
29
|
-
```
|
|
30
|
-
|
|
31
|
-
## 🕹️ CLI Usage
|
|
32
|
-
|
|
33
|
-
```bash
|
|
34
|
-
$ bun relion -h
|
|
35
|
-
|
|
36
|
-
Usage: relion [options]
|
|
25
|
+
$ bunx relion -h
|
|
37
26
|
|
|
38
27
|
Options:
|
|
39
|
-
-
|
|
40
|
-
-
|
|
41
|
-
-
|
|
42
|
-
-
|
|
43
|
-
-
|
|
44
|
-
-m <file> Specify manifest file
|
|
45
|
-
-d Run in dry run mode
|
|
46
|
-
-h Show the help message
|
|
28
|
+
-b <files> Files to bump the version in ['package.json']
|
|
29
|
+
-v <version> Release version [calculated from commits]
|
|
30
|
+
-t <prefix> Tag prefix [v]
|
|
31
|
+
-d Dry run [false]
|
|
32
|
+
-y Skip prompts [false]
|
|
47
33
|
|
|
48
34
|
Examples:
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
- `bun relion -m Cargo.toml` — use Cargo.toml as manifest
|
|
52
|
-
- `bun relion` — run all release steps
|
|
35
|
+
bunx relion -b src/manifest.json Bump a custom file
|
|
36
|
+
bunx relion -d -v 1.2.3 Dry run with a custom version
|
|
53
37
|
```
|
|
54
38
|
|
|
55
|
-
|
|
39
|
+
Notes:
|
|
40
|
+
- `package.json` is **always included** in the bump list if exists
|
|
41
|
+
- most files are bumped with a [generic pattern](https://regex101.com/r/t570Gh/1); `.rc` files use a dedicated one
|
|
42
|
+
- changes are **not staged automatically** before committing
|
|
43
|
+
|
|
44
|
+
<details><summary>Example output of running <code>bunx relion</code>:</summary>
|
|
56
45
|
|
|
57
|
-
```
|
|
46
|
+
```
|
|
58
47
|
Project: relion
|
|
59
48
|
Repo: github.com/kh4f/relion
|
|
60
|
-
Current tag: v0.
|
|
61
|
-
Current version: 0.
|
|
62
|
-
Parsed commits:
|
|
63
|
-
New version: 0.
|
|
64
|
-
New tag: v0.
|
|
65
|
-
Commit message: 'chore(release): v0.37.0'
|
|
49
|
+
Current tag: v0.42.1
|
|
50
|
+
Current version: 0.42.1
|
|
51
|
+
Parsed commits: 26
|
|
52
|
+
New version: 0.43.0
|
|
53
|
+
New tag: v0.43.0
|
|
66
54
|
------------------------------
|
|
67
55
|
|
|
56
|
+
('' to continue / 's' to skip)
|
|
68
57
|
About to write context to 'RELEASE.md'
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
About to
|
|
72
|
-
Press Enter to continue ('s' to skip):
|
|
73
|
-
|
|
74
|
-
About to commit changes: 'git commit -m "chore(release): v0.37.0"'
|
|
75
|
-
Press Enter to continue ('s' to skip):
|
|
76
|
-
|
|
77
|
-
About to create a tag: 'git tag v0.37.0 -m "chore(release): v0.37.0"'
|
|
78
|
-
Press Enter to continue ('s' to skip):
|
|
58
|
+
About to bump version in files: package.json
|
|
59
|
+
About to commit changes: 'git commit -m "chore(release): v0.43.0"'
|
|
60
|
+
About to create a tag: 'git tag v0.43.0 -m "chore(release): v0.43.0"'
|
|
79
61
|
```
|
|
80
62
|
</details>
|
|
81
63
|
|
|
82
|
-
##
|
|
83
|
-
|
|
84
|
-
```ts
|
|
85
|
-
import relion from 'relion';
|
|
86
|
-
|
|
87
|
-
relion({
|
|
88
|
-
flow: ['context', 'bump', 'commit', 'tag'],
|
|
89
|
-
newVersion: '1.2.3',
|
|
90
|
-
bump: [
|
|
91
|
-
'package.json', // uses default bumper
|
|
92
|
-
// custom bumper (equivalent to the default bumper implementation)
|
|
93
|
-
{
|
|
94
|
-
file: 'manifest.json',
|
|
95
|
-
pattern: /("version": )".*"/,
|
|
96
|
-
replacement: '$1"{{newVersion}}"'
|
|
97
|
-
}
|
|
98
|
-
],
|
|
99
|
-
contextFile: 'RELEASE.md',
|
|
100
|
-
commitMessage: 'chore(release): {{tag}}',
|
|
101
|
-
tagPrefix: 'v',
|
|
102
|
-
dryRun: false,
|
|
103
|
-
});
|
|
104
|
-
```
|
|
105
|
-
|
|
106
|
-
### Options
|
|
107
|
-
|
|
108
|
-
- `manifest`: manifest file (default: auto-detects `package.json` or `Cargo.toml`)
|
|
109
|
-
- `flow`: release workflow steps (`'context' | 'bump' | 'commit' | 'tag'`) (default: all steps)
|
|
110
|
-
- `newVersion`: set the new version explicitly
|
|
111
|
-
- `bump`: files or custom bumpers for version update (default: [`'package.json', 'Cargo.toml'`])
|
|
112
|
-
- `contextFile`: path to release context output file (default: `'RELEASE.md'`)
|
|
113
|
-
- `commitMessage`: release commit message template (default: `'chore(release): {{tag}}'`)
|
|
114
|
-
- `tagPrefix`: release tag prefix (default: `'v'`)
|
|
115
|
-
- `dryRun`: run in dry mode (no modifications)
|
|
116
|
-
|
|
117
|
-
> For detailed option descriptions, see [src/types.d.ts](src/types.d.ts).
|
|
118
|
-
|
|
119
|
-
### Configuration via `package.json`
|
|
120
|
-
|
|
121
|
-
Relion can also be configured via `relion` field in `package.json`:
|
|
122
|
-
|
|
123
|
-
```jsonc
|
|
124
|
-
{
|
|
125
|
-
// ...
|
|
126
|
-
"relion": {
|
|
127
|
-
"commitMessage": "release(relion): {{tag}}",
|
|
128
|
-
"tagPrefix": "",
|
|
129
|
-
"bump": ["package.json",
|
|
130
|
-
{
|
|
131
|
-
"file": "manifest.json",
|
|
132
|
-
"pattern": "/(\"version\": )\".*\"/",
|
|
133
|
-
"replacement": "$1\"{{newVersion}}\""
|
|
134
|
-
}
|
|
135
|
-
],
|
|
136
|
-
// ...
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
```
|
|
140
|
-
|
|
141
|
-
> [!NOTE]
|
|
142
|
-
> CLI flags override `package.json` configuration.
|
|
64
|
+
## ♻️ Release Workflow
|
|
143
65
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
- **Commit**: creates a release commit
|
|
149
|
-
- **Tag**: creates an annotated release tag
|
|
66
|
+
1. **Context**: generates a `RELEASE.md` file with upcoming release metadata and commit log
|
|
67
|
+
2. **Bump**: updates version in specified files
|
|
68
|
+
3. **Commit**: creates a release commit
|
|
69
|
+
4. **Tag**: creates an annotated release tag
|
|
150
70
|
|
|
151
71
|
<details><summary>Generated release context example (*):</summary>
|
|
152
72
|
|
|
@@ -155,7 +75,7 @@ Relion can also be configured via `relion` field in `package.json`:
|
|
|
155
75
|
tag: v0.33.0
|
|
156
76
|
prevTag: v0.32.1
|
|
157
77
|
date: Jan 10, 2026
|
|
158
|
-
repoURL:
|
|
78
|
+
repoURL: github.com/kh4f/relion
|
|
159
79
|
---
|
|
160
80
|
|
|
161
81
|
## Commit Log
|
|
@@ -168,23 +88,21 @@ Previously, if commits contained both features and breaking changes, features wo
|
|
|
168
88
|
|
|
169
89
|
- Implement `mergeConfigs` to support merging config profiles in `config-merger.ts`
|
|
170
90
|
- Export `mergeConfigs` from `src/index.ts`
|
|
171
|
-
------------------------------
|
|
172
91
|
```
|
|
173
92
|
</details>
|
|
174
93
|
|
|
175
|
-
##
|
|
94
|
+
## 📋 Changelog Generation
|
|
176
95
|
|
|
177
|
-
Relion doesn’t format the changelog itself — it
|
|
96
|
+
Relion doesn’t format the changelog itself — instead, it generates a release context that you can turn into a polished changelog using AI.
|
|
178
97
|
|
|
179
|
-
|
|
98
|
+
Example workflow using GitHub Copilot:
|
|
180
99
|
|
|
181
|
-
1. Set up
|
|
100
|
+
1. Set up the instruction and prompt:
|
|
182
101
|
- [.github/instructions/changelog-format.instructions.md](.github/instructions/changelog-format.instructions.md)
|
|
183
102
|
- [.github/prompts/generate-changelog.prompt.md](.github/prompts/generate-changelog.prompt.md)
|
|
184
|
-
2. Run
|
|
185
|
-
3. Review the release context
|
|
186
|
-
4. Run
|
|
187
|
-
5. Copilot produces a polished changelog entry based on the release context
|
|
103
|
+
2. Run Relion to generate `RELEASE.md`
|
|
104
|
+
3. Review the release context
|
|
105
|
+
4. Run `/generate-changelog` in VS Code Copilot chat
|
|
188
106
|
|
|
189
107
|
<details><summary>Generated changelog example (from the (*) release context using the instruction and prompt above; Gemini 3 Pro)</summary>
|
|
190
108
|
|
package/dist/cli.js
CHANGED
|
@@ -1,19 +1,18 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import e from"
|
|
2
|
+
import{execSync as e,spawnSync as t}from"node:child_process";import{existsSync as n,readFileSync as r,writeFileSync as i}from"node:fs";import{createInterface as a}from"node:readline";import o from"semver";const s=()=>{let t=e(`git config --get remote.origin.url`,{encoding:`utf8`}).trim(),n=/(github\.com.*?)(\.git)?$/.exec(t)?.[1]??``;return{url:n,name:n.split(`/`).at(-1)??``}},c=t=>e(`git log ${t?`${t}..`:``} --format="%h %B---" .`,{encoding:`utf8`}).trim().split(`---`).filter(Boolean).map(e=>/^(.+?) (.+)/s.exec(e.trim())).map(e=>({hash:e?.[1]??``,message:e?.[2].trim()??``})),l=(e,t)=>{let n=e.some(e=>e.message.includes(`BREAKING CHANGE`))?t.startsWith(`0.`)?`minor`:`major`:e.some(e=>/feat(\(.*?\))?:/.test(e.message))?`minor`:`patch`;return o.inc(t,n)??(()=>{throw Error(`Failed to increment version '${t}' with release type '${n}'`)})()},u=async(e,t=!1)=>{if(t)return!0;let n=a({input:process.stdin,output:process.stdout});return await new Promise(t=>{n.question(e,e=>{n.close(),t(e.trim()!==`s`)})})},d={bump:[`package.json`],newVersion:``,tagPrefix:`v`,dryRun:!1,yes:!1},f=[{filePattern:/\.rc$/,bump:(e,t)=>e.replace(/(\b(FileVersion|ProductVersion)\b.*?)\d[\w.+-]*/g,`$1${t}`).replace(/(\b(FILEVERSION|PRODUCTVERSION)\b.*?)\d[\w,+-]*/g,`$1${(/^\d+\.\d+\.\d+/.exec(t)?.[0]??``).replace(/\./g,`,`)+`,0`}`)},{filePattern:/.*/,bump:(e,t)=>e.replace(/(\bversion\b.*?)\d[\w.+-]*/,`$1${t}`)}],p=async(e,t,n,r,a)=>{if(!await u(`About to write context to 'RELEASE.md'`,e.yes)||e.dryRun)return;let o=``,s=`---\ntag: ${r}\nprevTag: ${n}\ndate: ${new Date().toLocaleString(`en-US`,{month:`short`,day:`numeric`,year:`numeric`})}\nrepoURL: ${a}
|
|
3
|
+
---
|
|
4
|
+
`;o+=s+`
|
|
5
|
+
`;let c=t.map(e=>`[${e.hash}] ${e.message}`).join(`\n${`-`.repeat(30)}\n`);o+=`## Commit Log\n\n\`\`\`\n${c}\n\`\`\``,i(`RELEASE.md`,o,`utf8`)},m=async e=>{await u(`About to bump version in files: ${e.bump.join(`, `)}`,e.yes)&&e.bump.forEach(t=>{if(!n(t))return console.warn(`File '${t}' does not exist, skipping...`);let a=f.find(e=>e.filePattern.test(t));if(!a)return console.warn(`No matching bumper found for file '${t}', skipping...`);let o=r(t,`utf8`),s=a.bump(o,e.newVersion);e.dryRun||i(t,s,`utf8`)})},h=async(t,n)=>{let r=`git commit -m "${n}"`;await u(`About to commit changes: '${r}'`,t.yes)&&(t.dryRun||e(r,{stdio:`inherit`}))},g=async(t,n,r)=>{let i=`git tag ${n} -m "${r}"`;await u(`About to create a tag: '${i}'`,t.yes)&&(t.dryRun||e(i,{stdio:`inherit`}))},_=async e=>{let n=s();console.log(`Project: ${n.name}`),console.log(`Repo: ${n.url}`);let r={...d,...e,bump:[...d.bump,...e.bump??[]]},i=t(`git`,[`describe`,`--match`,`${r.tagPrefix}[0-9]*.[0-9]*.[0-9]*`,`--abbrev=0`],{encoding:`utf8`}).stdout.trim();console.log(`Current tag: ${i}`);let a=/\d+\.\d+\.\d+.*/.exec(i)?.[0]??`0.0.0`;console.log(`Current version: ${a}`);let o=c(i);console.log(`Parsed commits: ${o.length}`),r.newVersion||=l(o,a),console.log(`New version: ${r.newVersion}`);let u=`${r.tagPrefix}${r.newVersion}`;console.log(`New tag: ${u}`);let f=`chore(release): ${u}`;console.log(`Commit message: '${f}'`),console.log(`-`.repeat(30)),console.log(`
|
|
6
|
+
('' to continue / 's' to skip)`),await p(r,o,i,u,n.url),await m(r),await h(r,f),await g(r,u,f)},v=process.argv.slice(2).join(` `);v.includes(`-h`)&&(console.log(`Usage: relion [options]
|
|
3
7
|
|
|
4
8
|
Options:
|
|
5
|
-
-
|
|
6
|
-
-
|
|
7
|
-
-
|
|
8
|
-
-
|
|
9
|
-
-
|
|
10
|
-
-m <file> Specify manifest file
|
|
11
|
-
-d Run in dry run mode
|
|
12
|
-
-h Show the help message
|
|
9
|
+
-b <files> Files to bump the version in ['package.json']
|
|
10
|
+
-v <version> Release version [calculated from commits]
|
|
11
|
+
-t <prefix> Tag prefix [v]
|
|
12
|
+
-d Dry run [false]
|
|
13
|
+
-y Skip prompts [false]
|
|
13
14
|
|
|
14
15
|
Examples:
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
- \`pnpm relion\` — run all release steps
|
|
19
|
-
`),process.exit(0));let n=[/-\w*f/.test(t)&&`context`,/-\w*b/.test(t)&&`bump`,/-\w*c/.test(t)&&`commit`,/-\w*t/.test(t)&&`tag`].filter(Boolean);n.length||(n=[`context`,`bump`,`commit`,`tag`]);const r=/-v (\S+)/.exec(t)?.[1],i=/-m (\S+)/.exec(t)?.[1],a=/-\w*d/.test(t);e({flow:n,...r&&{newVersion:r},...i&&{manifest:i},...a&&{dryRun:a}}).catch(e=>{console.error(e),process.exit(1)});export{};
|
|
16
|
+
bunx relion -b src/manifest.json Bump a custom file
|
|
17
|
+
bunx relion -d -v 1.2.3 Dry run with a custom version
|
|
18
|
+
`),process.exit(0));const y=/-b (.+?)( -|$)/.exec(v)?.[1].split(` `),b=/-v (\S+)/.exec(v)?.[1],x=/-t (\S+)/.exec(v)?.[1],S=/-\w*d/.test(v),C=/-\w*y/.test(v);_({...y&&{bump:y},...b&&{newVersion:b},...x&&{tagPrefix:x},dryRun:S,yes:C}).catch(e=>{console.error(e),process.exit(1)});export{};
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "relion",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "🏷️
|
|
3
|
+
"version": "0.44.0",
|
|
4
|
+
"description": "🏷️ Release Workflow Helper",
|
|
5
5
|
"author": "kh4f <kh4f.dev@gmail.com>",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"repository": "https://github.com/kh4f/relion",
|
|
@@ -10,9 +10,7 @@
|
|
|
10
10
|
"keywords": ["relion", "release", "release-automation", "release-workflow", "release-helper", "release-workflow-helper"],
|
|
11
11
|
"files": ["dist"],
|
|
12
12
|
"type": "module",
|
|
13
|
-
"main": "dist/index.js",
|
|
14
13
|
"bin": "dist/cli.js",
|
|
15
|
-
"types": "dist/index.d.ts",
|
|
16
14
|
"scripts": {
|
|
17
15
|
"build": "tsdown",
|
|
18
16
|
"build:watch": "tsdown --watch",
|
|
@@ -20,16 +18,19 @@
|
|
|
20
18
|
"lint": "eslint",
|
|
21
19
|
"release": "bun src/cli"
|
|
22
20
|
},
|
|
23
|
-
"dependencies": {
|
|
21
|
+
"dependencies": {
|
|
22
|
+
"semver": "^7.7.4"
|
|
23
|
+
},
|
|
24
24
|
"devDependencies": {
|
|
25
25
|
"@eslint/js": "^10.0.1",
|
|
26
26
|
"@stylistic/eslint-plugin": "^5.10.0",
|
|
27
|
-
"@types/
|
|
27
|
+
"@types/bun": "^1.3.11",
|
|
28
|
+
"@types/node": "^25.5.0",
|
|
28
29
|
"@types/semver": "^7.7.1",
|
|
29
30
|
"eslint": "^10.0.3",
|
|
30
31
|
"jiti": "^2.6.1",
|
|
31
|
-
"tsdown": "^0.21.
|
|
32
|
+
"tsdown": "^0.21.4",
|
|
32
33
|
"typescript": "^5.9.3",
|
|
33
|
-
"typescript-eslint": "^8.
|
|
34
|
+
"typescript-eslint": "^8.57.1"
|
|
34
35
|
}
|
|
35
36
|
}
|
package/dist/index.d.ts
DELETED
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
//#region src/types.d.ts
|
|
2
|
-
interface Config {
|
|
3
|
-
/** Manifest file path. Auto-detects `package.json` or `Cargo.toml` if omitted. */
|
|
4
|
-
manifest?: string;
|
|
5
|
-
/**
|
|
6
|
-
* Release workflow steps to execute (e.g. bump, context, commit, tag)
|
|
7
|
-
* @default []
|
|
8
|
-
*/
|
|
9
|
-
flow?: Step[];
|
|
10
|
-
/**
|
|
11
|
-
* Explicitly set the version for the upcoming release. If not provided, the version will be determined automatically based on conventional commit messages.
|
|
12
|
-
* @default ''
|
|
13
|
-
*/
|
|
14
|
-
newVersion?: string;
|
|
15
|
-
/**
|
|
16
|
-
* Files or bumpers for version update. Each item is either:
|
|
17
|
-
* - a Bumper object specifying `file`, `pattern`, and `replacement`
|
|
18
|
-
* - a file name for which a default bumper exists (currently only 'package.json', 'Cargo.toml')
|
|
19
|
-
*
|
|
20
|
-
* If a file doesn't exist, it will be skipped silently.
|
|
21
|
-
*
|
|
22
|
-
* @default ['package.json', 'Cargo.toml']
|
|
23
|
-
*/
|
|
24
|
-
bump?: (Bumper | string)[];
|
|
25
|
-
/**
|
|
26
|
-
* Path to the release context output file
|
|
27
|
-
* @default 'RELEASE.md'
|
|
28
|
-
*/
|
|
29
|
-
contextFile?: string;
|
|
30
|
-
/**
|
|
31
|
-
* Release commit message template
|
|
32
|
-
* @default 'chore(release): {{tag}}'
|
|
33
|
-
*/
|
|
34
|
-
commitMessage?: string;
|
|
35
|
-
/**
|
|
36
|
-
* Release tag prefix
|
|
37
|
-
* @default 'v'
|
|
38
|
-
*/
|
|
39
|
-
tagPrefix?: string;
|
|
40
|
-
/**
|
|
41
|
-
* Run in dry mode without making any changes
|
|
42
|
-
* @default false
|
|
43
|
-
*/
|
|
44
|
-
dryRun?: boolean;
|
|
45
|
-
}
|
|
46
|
-
type Step = 'bump' | 'context' | 'commit' | 'tag';
|
|
47
|
-
interface Bumper {
|
|
48
|
-
/** Path or array of paths to the file(s) to bump version in */
|
|
49
|
-
file: string | string[];
|
|
50
|
-
/** Pattern to locate the version string (RegExp or a stringified RegExp) */
|
|
51
|
-
pattern: RegExp | string;
|
|
52
|
-
/** Replacement string for the version (use `{{newVersion}}` as a placeholder) */
|
|
53
|
-
replacement: string;
|
|
54
|
-
}
|
|
55
|
-
//#endregion
|
|
56
|
-
//#region src/relion.d.ts
|
|
57
|
-
declare function relion(userCfg?: Config): Promise<void>;
|
|
58
|
-
//#endregion
|
|
59
|
-
//#region src/index.d.ts
|
|
60
|
-
declare const defineConfig: (config: Config) => Config;
|
|
61
|
-
//#endregion
|
|
62
|
-
export { relion as default, defineConfig };
|
package/dist/index.js
DELETED
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
import{existsSync as e,readFileSync as t,writeFileSync as n}from"node:fs";import{execSync as r,spawnSync as i}from"node:child_process";import{createInterface as a}from"node:readline";import o from"semver";const s=()=>{let e=r(`git config --get remote.origin.url`,{encoding:`utf8`}).trim(),t=/(github\.com.*?)(\.git)?$/.exec(e)?.[1]??``;return{url:t,name:t.split(`/`).at(-1)??``}},c=e=>{let n=t(e,`utf8`),r=/name.*"(.*?)"/.exec(n)?.[1];if(!r)throw Error(`Manifest is missing 'name' field`);let i=/repository.*"(.*?)"/.exec(n)?.[1];if(!i)throw Error(`Manifest is missing 'repository' field`);let a=e.endsWith(`.json`)?/relion.*({.*?})/s.exec(n)?.[1]:void 0;return{name:r,url:i,relion:a?JSON.parse(a):void 0}},l=e=>r(`git log ${e?`${e}..`:``} --format="%h %B---" .`,{encoding:`utf8`}).trim().split(`---`).filter(Boolean).map(e=>/^(.+?) (.+)/s.exec(e.trim())).map(e=>({hash:e?.[1]??``,message:e?.[2].trim()??``})),u=(e,t)=>{let n=e.some(e=>e.message.includes(`BREAKING CHANGE`))?t.startsWith(`0.`)?`minor`:`major`:e.some(e=>/feat(\(.*?\))?:/.test(e.message))?`minor`:`patch`;return o.inc(t,n)??(()=>{throw Error(`Failed to increment version '${t}' with release type '${n}'`)})()},d=async()=>{let e=a({input:process.stdin,output:process.stdout});return await new Promise(t=>{e.question(`Press Enter to continue ('s' to skip): `,n=>{e.close(),t(n.trim()!==`s`)})})},f=e=>{let t=/^\/(.+)\/(\w*)$/.exec(e);return t?new RegExp(t[1],t[2]):new RegExp(e)},p=[`context`,`bump`,`commit`,`tag`],m={file:[`package.json`,`Cargo.toml`],pattern:/(\bversion\b.*?)\d[\w.+-]*/,replacement:`$1{{newVersion}}`},h=[`package.json`,`Cargo.toml`],g={flow:p,newVersion:``,bump:h,contextFile:`RELEASE.md`,commitMessage:`chore(release): {{tag}}`,tagPrefix:`v`,dryRun:!1},_=async(e,t,r,i,a)=>{if(console.log(`\nAbout to write context to '${e.contextFile}'`),!await d()||e.dryRun)return;let o=``,s=`---\ntag: ${i}\nprevTag: ${r}\ndate: ${new Date().toLocaleString(`en-US`,{month:`short`,day:`numeric`,year:`numeric`})}\nrepoURL: ${a}
|
|
2
|
-
---
|
|
3
|
-
`;o+=s+`
|
|
4
|
-
`;let c=t.map(e=>`[${e.hash}] ${e.message}`).join(`\n${`-`.repeat(30)}\n`);o+=`## Commit Log\n\n\`\`\`\n${c}\n\`\`\``,n(e.contextFile,o,`utf8`)},v=async r=>{let i=r.bump.map(e=>typeof e==`string`?{...m,file:e}:e).filter(t=>[t.file].flat().every(t=>e(t)));console.log(`\nAbout to bump versions in files: ${i.map(e=>[e.file].flat()).flat().join(`, `)}`),await d()&&i.forEach(e=>{typeof e.pattern==`string`&&(e.pattern=f(e.pattern)),[e.file].flat().forEach(i=>{let a=t(i,`utf8`).replace(e.pattern,e.replacement.replace(`{{newVersion}}`,r.newVersion));r.dryRun||n(i,a,`utf8`)})})},y=async e=>{let t=`git commit -m "${e.commitMessage}"`;console.log(`\nAbout to commit changes: '${t}'`),await d()&&(e.dryRun||r(t,{stdio:`inherit`}))},b=async(e,t,n)=>{let i=`git tag ${n} -m "${e.commitMessage}"`;console.log(`\nAbout to create a tag: '${i}'`),await d()&&(e.dryRun||r(i,{stdio:`inherit`}))};async function x(t){let n;if(t?.manifest&&!e(t.manifest))throw Error(`Specified manifest file '${t.manifest}' does not exist`);let r=t?.manifest??h.find(e);r?(console.log(`Manifest file: ${r}`),n=c(r)):(console.log(`No manifest file found, using repository info`),n=s()),console.log(`Project: ${n.name}`),console.log(`Repo: ${n.url}`),t={...n.relion,...t};let a={...g,...t};!t.tagPrefix&&n.name.startsWith(`@`)&&(a.tagPrefix=`${n.name}@`);let o=i(`git`,[`describe`,`--match`,`${a.tagPrefix}[0-9]*.[0-9]*.[0-9]*`,`--abbrev=0`],{encoding:`utf8`}).stdout.trim();console.log(`Current tag: ${o}`);let d=/\d+\.\d+\.\d+.*/.exec(o)?.[0]??`0.0.0`;console.log(`Current version: ${d}`);let f=l(o);console.log(`Parsed commits: ${f.length}`),a.newVersion||=u(f,d),console.log(`New version: ${a.newVersion}`);let m=`${a.tagPrefix}${a.newVersion}`;console.log(`New tag: ${m}`),a.commitMessage=a.commitMessage.replace(`{{tag}}`,m),console.log(`Commit message: '${a.commitMessage}'`),console.log(`-`.repeat(30));for(let e of p.filter(e=>a.flow.includes(e)))await{context:()=>_(a,f,o,m,n.url),bump:()=>v(a),commit:()=>y(a),tag:()=>b(a,o,m)}[e]()}const S=e=>e;export{x as default,S as defineConfig};
|