relion 0.43.0 → 0.44.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/README.md +32 -29
- package/dist/cli.js +11 -10
- package/package.json +9 -6
package/README.md
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
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
|
-
<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=
|
|
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=
|
|
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=
|
|
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=
|
|
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=A3BAFF&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/cli.js?label=Size&logo=hackthebox&logoColor=c97026&style=flat-square&color=A3BAFF&labelColor=303145" alt="runtime size"/></a>
|
|
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=A3BAFF&labelColor=303145" alt="license"></a>
|
|
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=A3BAFF&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
15
|
<a href="#%EF%B8%8F-usage">Usage</a> •
|
|
16
|
-
<a href="#%EF%B8%8F-workflow
|
|
16
|
+
<a href="#%EF%B8%8F-release-workflow">Release Workflow</a> •
|
|
17
17
|
<a href="#-changelog-generation">Changelog Generation</a>
|
|
18
18
|
</b></p>
|
|
19
19
|
<br>
|
|
@@ -24,19 +24,23 @@
|
|
|
24
24
|
```bash
|
|
25
25
|
$ bunx relion -h
|
|
26
26
|
|
|
27
|
-
Usage: relion [options]
|
|
28
|
-
|
|
29
27
|
Options:
|
|
30
|
-
-b <files> Files to bump version in
|
|
31
|
-
-v <version> Release version
|
|
32
|
-
-t <prefix> Tag prefix
|
|
33
|
-
-d Dry run
|
|
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]
|
|
34
33
|
|
|
35
34
|
Examples:
|
|
36
|
-
|
|
37
|
-
|
|
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
|
|
38
37
|
```
|
|
39
38
|
|
|
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
|
+
|
|
40
44
|
<details><summary>Example output of running <code>bunx relion</code>:</summary>
|
|
41
45
|
|
|
42
46
|
```
|
|
@@ -57,12 +61,12 @@ About to create a tag: 'git tag v0.43.0 -m "chore(release): v0.43.0"'
|
|
|
57
61
|
```
|
|
58
62
|
</details>
|
|
59
63
|
|
|
60
|
-
## ♻️ Workflow
|
|
64
|
+
## ♻️ Release Workflow
|
|
61
65
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
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
|
|
66
70
|
|
|
67
71
|
<details><summary>Generated release context example (*):</summary>
|
|
68
72
|
|
|
@@ -87,19 +91,18 @@ Previously, if commits contained both features and breaking changes, features wo
|
|
|
87
91
|
```
|
|
88
92
|
</details>
|
|
89
93
|
|
|
90
|
-
##
|
|
94
|
+
## 📋 Changelog Generation
|
|
91
95
|
|
|
92
|
-
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.
|
|
93
97
|
|
|
94
|
-
|
|
98
|
+
Example workflow using GitHub Copilot:
|
|
95
99
|
|
|
96
|
-
1. Set up
|
|
100
|
+
1. Set up the instruction and prompt:
|
|
97
101
|
- [.github/instructions/changelog-format.instructions.md](.github/instructions/changelog-format.instructions.md)
|
|
98
102
|
- [.github/prompts/generate-changelog.prompt.md](.github/prompts/generate-changelog.prompt.md)
|
|
99
|
-
2. Run Relion to generate `RELEASE.md`
|
|
100
|
-
3. Review the release context
|
|
101
|
-
4. Run
|
|
102
|
-
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
|
|
103
106
|
|
|
104
107
|
<details><summary>Generated changelog example (from the (*) release context using the instruction and prompt above; Gemini 3 Pro)</summary>
|
|
105
108
|
|
package/dist/cli.js
CHANGED
|
@@ -1,17 +1,18 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
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
|
|
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
3
|
---
|
|
4
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`)},
|
|
6
|
-
('' to continue / 's' to skip)`),await
|
|
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=>{let t=e.bump.filter(n);await u(`About to bump version in files: ${t.join(`, `)}`,e.yes)&&t.forEach(t=>{let n=f.find(e=>e.filePattern.test(t));if(!n)return console.warn(`No matching bumper found for file '${t}', skipping...`);let a=r(t,`utf8`),o=n.bump(a,e.newVersion);e.dryRun||i(t,o,`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]
|
|
7
7
|
|
|
8
8
|
Options:
|
|
9
|
-
-b <files> Files to bump version in
|
|
10
|
-
-v <version> Release version
|
|
11
|
-
-t <prefix> Tag prefix
|
|
12
|
-
-d Dry run
|
|
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
|
-
`),process.exit(0));const
|
|
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,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "relion",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.44.1",
|
|
4
4
|
"description": "🏷️ Release Workflow Helper",
|
|
5
5
|
"author": "kh4f <kh4f.dev@gmail.com>",
|
|
6
6
|
"license": "MIT",
|
|
@@ -18,16 +18,19 @@
|
|
|
18
18
|
"lint": "eslint",
|
|
19
19
|
"release": "bun src/cli"
|
|
20
20
|
},
|
|
21
|
-
"dependencies": {
|
|
21
|
+
"dependencies": {
|
|
22
|
+
"semver": "^7.7.4"
|
|
23
|
+
},
|
|
22
24
|
"devDependencies": {
|
|
23
25
|
"@eslint/js": "^10.0.1",
|
|
24
26
|
"@stylistic/eslint-plugin": "^5.10.0",
|
|
25
|
-
"@types/
|
|
27
|
+
"@types/bun": "^1.3.11",
|
|
28
|
+
"@types/node": "^25.5.0",
|
|
26
29
|
"@types/semver": "^7.7.1",
|
|
27
|
-
"eslint": "^10.0
|
|
30
|
+
"eslint": "^10.1.0",
|
|
28
31
|
"jiti": "^2.6.1",
|
|
29
|
-
"tsdown": "^0.21.
|
|
32
|
+
"tsdown": "^0.21.4",
|
|
30
33
|
"typescript": "^5.9.3",
|
|
31
|
-
"typescript-eslint": "^8.57.
|
|
34
|
+
"typescript-eslint": "^8.57.1"
|
|
32
35
|
}
|
|
33
36
|
}
|