relion 0.44.2 → 0.45.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.
Files changed (3) hide show
  1. package/README.md +13 -13
  2. package/dist/cli.js +4 -4
  3. package/package.json +5 -5
package/README.md CHANGED
@@ -4,10 +4,10 @@
4
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=BAC4E2&labelColor=303145" alt="npm version"/></a>&nbsp;
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=BAC4E2&labelColor=303145" alt="bundle size"/></a>&nbsp;
9
- <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=BAC4E2&labelColor=303145" alt="open bugs"></a>&nbsp;
10
- <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=BAC4E2&labelColor=303145" alt="license"></a>
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=A4BFFF&labelColor=303145" alt="npm version"/></a>&nbsp;
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=A4BFFF&labelColor=303145" alt="bundle size"/></a>&nbsp;
9
+ <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=A4BFFF&labelColor=303145" alt="open bugs"></a>&nbsp;
10
+ <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=A4BFFF&labelColor=303145" alt="license"></a>
11
11
  <br><br>
12
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>
@@ -16,7 +16,6 @@
16
16
  <a href="#%EF%B8%8F-release-workflow">Release Workflow</a>&nbsp; •&nbsp;
17
17
  <a href="#-changelog-generation">Changelog Generation</a>
18
18
  </b></p>
19
- <br>
20
19
  </div>
21
20
 
22
21
  ## 🕹️ Usage
@@ -36,10 +35,8 @@ Examples:
36
35
  bunx relion -d -v 1.2.3 Dry run with a custom version
37
36
  ```
38
37
 
39
- Notes:
40
38
  - `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
39
+ - to create a tag without a prefix, use `-t ''`
43
40
 
44
41
  <details><summary>Example output of running <code>bunx relion</code>:</summary>
45
42
 
@@ -63,9 +60,12 @@ About to create a tag: 'git tag v0.43.0 -m "chore(release): v0.43.0"'
63
60
 
64
61
  ## ♻️ Release Workflow
65
62
 
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
63
+ 1. **Context**: generates a `RELEASE.md` file with upcoming release metadata and commit log
64
+ The log is [automatically filtered](tests/context.test.ts) to exclude non-user-facing commits.
65
+ 2. **Bump**: updates version in specified files
66
+ Most files are bumped with a [generic pattern](https://regex101.com/r/t570Gh/1); `.rc` files use a dedicated one.
67
+ 3. **Commit**: creates a release commit
68
+ Changes are **not staged automatically** before committing, unless `-y` is passed.
69
69
  4. **Tag**: creates an annotated release tag
70
70
 
71
71
  <details><summary>Generated release context example (*):</summary>
@@ -117,8 +117,8 @@ Example workflow using GitHub Copilot:
117
117
  ```
118
118
  </details>
119
119
 
120
- </br>
120
+ <br>
121
121
 
122
122
  <div align="center">
123
123
  <b>MIT License © 2025-2026 <a href="https://github.com/kh4f">kh4f</a></b>
124
- </div>
124
+ </div>
package/dist/cli.js CHANGED
@@ -1,9 +1,9 @@
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(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}
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`,commitsExclude:[/^(ci|build|test)\(/,/^chore\(deps\)(?!!)/],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(e.yes||!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`)},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]
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=`${t.yes?`git add -A && `:``}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),u=o.filter(e=>!r.commitsExclude.some(t=>t.test(e.message)));console.log(`Parsed commits: ${u.length}`),r.newVersion||=l(o,a),console.log(`New version: ${r.newVersion}`);let f=`${r.tagPrefix}${r.newVersion}`;console.log(`New tag: ${f}`);let _=`chore(release): ${f}`;console.log(`Commit message: '${_}'`),console.log(`-`.repeat(30)),console.log(`
6
+ ('' to continue / 's' to skip)`),await p(r,u,i,f,n.url),await m(r),await h(r,_),await g(r,f,_)},v=process.argv.slice(2).join(` `);v.includes(`-h`)&&(console.log(`Usage: relion [options]
7
7
 
8
8
  Options:
9
9
  -b <files> Files to bump the version in ['package.json']
@@ -15,4 +15,4 @@ Options:
15
15
  Examples:
16
16
  bunx relion -b src/manifest.json Bump a custom file
17
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{};
18
+ `),process.exit(0));const y=/-b (.+?)( -|$)/.exec(v)?.[1].split(` `),b=/-v (\S+)/.exec(v)?.[1];let x=/-t (\S+)/.exec(v)?.[1];x===`''`&&(x=``);const 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.44.2",
3
+ "version": "0.45.0",
4
4
  "description": "🏷️ Release Workflow Helper",
5
5
  "author": "kh4f <kh4f.dev@gmail.com>",
6
6
  "license": "MIT",
@@ -16,6 +16,7 @@
16
16
  "build:watch": "tsdown --watch",
17
17
  "build:prod": "tsdown --prod",
18
18
  "lint": "eslint",
19
+ "test": "bun test",
19
20
  "release": "bun src/cli"
20
21
  },
21
22
  "dependencies": {
@@ -25,12 +26,11 @@
25
26
  "@eslint/js": "^10.0.1",
26
27
  "@stylistic/eslint-plugin": "^5.10.0",
27
28
  "@types/bun": "^1.3.11",
28
- "@types/node": "^25.5.0",
29
29
  "@types/semver": "^7.7.1",
30
30
  "eslint": "^10.1.0",
31
31
  "jiti": "^2.6.1",
32
- "tsdown": "^0.21.5",
33
- "typescript": "^5.9.3",
34
- "typescript-eslint": "^8.57.2"
32
+ "tsdown": "^0.21.7",
33
+ "typescript": "^6.0.2",
34
+ "typescript-eslint": "^8.58.0"
35
35
  }
36
36
  }