relion 0.19.0 → 0.21.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/dist/cli.js +1 -1
- package/dist/index.d.ts +12 -10
- package/dist/index.js +8 -8
- package/package.json +10 -10
package/dist/cli.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{resolve as e}from"node:path";import{pathToFileURL as t}from"node:url";import n from"./index.js";import{cli as r}from"cleye";const i=async n=>{try{return(await import(t(e(process.cwd(),n)).href)).default}catch(e){throw Error(`Error loading config: ${e.message}`)}};import.meta.main&&await a();async function a(e,t){typeof e==`string`&&(e=e.split(` `)),e&&=[e].flat();let a=r({name:`relion`,flags:{config:{alias:`c`,type:String,description:`Path to the config file`,default:`relion.config.ts`},bump:{alias:`b`,type:Boolean,description:`Bump the version`,default:!1},changelog:{alias:`l`,type:Boolean,description:`Generate a changelog`,default:!1},commit:{alias:`m`,type:Boolean,description:`Create a commit`,default:!1},tag:{alias:`t`,type:Boolean,description:`Create a tag`,default:!1},profile:{alias:`p`,type:String,description:`Use config profile`},dry:{alias:`d`,type:Boolean,description:`Run without making any changes`,default:!1},latest:{alias:`L`,type:Boolean,description:`Use the latest-release commit range in changelog`,default:!1}}},void 0,e?[...e]:process.argv.slice(2));if(a)return t??=await i(a.flags.config),t.bump||=a.flags.bump,t.changelog||=a.flags.changelog,t.commit||=a.flags.commit,t.tag||=a.flags.tag,t.profile??=a.flags.profile,t.dryRun??=a.flags.dry,a.flags.latest&&t.changelog&&(t.changelog===!0&&(t.changelog={}),t.changelog.commitRange=`latest-release`),{inputConfig:t,...n(t)}}export{a as runCli};
|
|
1
|
+
import{resolve as e}from"node:path";import{pathToFileURL as t}from"node:url";import n from"./index.js";import{cli as r}from"cleye";const i=async n=>{try{return(await import(t(e(process.cwd(),n)).href)).default}catch(e){throw Error(`Error loading config: ${e.message}`)}};import.meta.main&&await a();async function a(e,t){typeof e==`string`&&(e=e.split(` `)),e&&=[e].flat();let a=r({name:`relion`,flags:{config:{alias:`c`,type:String,description:`Path to the config file`,default:`relion.config.ts`},bump:{alias:`b`,type:Boolean,description:`Bump the version`,default:!1},changelog:{alias:`l`,type:Boolean,description:`Generate a changelog`,default:!1},commit:{alias:`m`,type:Boolean,description:`Create a commit`,default:!1},tag:{alias:`t`,type:Boolean,description:`Create a tag`,default:!1},profile:{alias:`p`,type:String,description:`Use config profile`},dry:{alias:`d`,type:Boolean,description:`Run without making any changes`,default:!1},latest:{alias:`L`,type:Boolean,description:`Use the latest-release commit range in changelog`,default:!1}}},void 0,e?[...e]:process.argv.slice(2));if(a)return t??=await i(a.flags.config),t.bump||=a.flags.bump,t.changelog||=a.flags.changelog,t.commit||=a.flags.commit,t.tag||=a.flags.tag,t.profile??=a.flags.profile,t.dryRun??=a.flags.dry,a.flags.latest&&t.changelog&&(t.changelog===!0&&(t.changelog={}),t.changelog.commitRange=`latest-release`),{inputConfig:t,...await n(t)}}export{a as runCli};
|
package/dist/index.d.ts
CHANGED
|
@@ -11,6 +11,7 @@ interface UserConfig {
|
|
|
11
11
|
newTagFormat?: string;
|
|
12
12
|
versionSource?: 'versionSourceFile' | 'latest-release-tag';
|
|
13
13
|
versionSourceFile?: string | Bumper;
|
|
14
|
+
commitsScope?: string;
|
|
14
15
|
releaseType?: ReleaseType;
|
|
15
16
|
zeroMajorBreakingIsMinor?: boolean;
|
|
16
17
|
context?: Context;
|
|
@@ -47,6 +48,7 @@ interface ChangelogOptions {
|
|
|
47
48
|
maxLinesPerRelease?: number;
|
|
48
49
|
helpers?: HelperDeclareSpec;
|
|
49
50
|
partials?: Record<string, string | ((fallback: string) => string)>;
|
|
51
|
+
review?: boolean;
|
|
50
52
|
}
|
|
51
53
|
type CompleteChangelogOptions = Required<ChangelogOptions>;
|
|
52
54
|
interface ResolvedChangelogOptions extends Omit<CompleteChangelogOptions, 'partials'> {
|
|
@@ -92,7 +94,7 @@ interface RepoInfo {
|
|
|
92
94
|
homepage?: string;
|
|
93
95
|
}
|
|
94
96
|
interface Context {
|
|
95
|
-
commits?: (ParsedCommit | RawCommit)[];
|
|
97
|
+
commits?: (ParsedCommit | RawCommit | string)[];
|
|
96
98
|
currentVersion?: string;
|
|
97
99
|
currentTag?: string;
|
|
98
100
|
newVersion?: string;
|
|
@@ -135,7 +137,7 @@ declare enum RefType {
|
|
|
135
137
|
}
|
|
136
138
|
//#endregion
|
|
137
139
|
//#region src/types/commit.d.ts
|
|
138
|
-
|
|
140
|
+
interface RawCommit {
|
|
139
141
|
hash?: string;
|
|
140
142
|
message: string;
|
|
141
143
|
tagRefs?: string;
|
|
@@ -147,7 +149,7 @@ type RawCommit = string | {
|
|
|
147
149
|
committerTs?: string;
|
|
148
150
|
gpgSigCode?: GpgSigCode;
|
|
149
151
|
gpgSigKeyId?: string;
|
|
150
|
-
}
|
|
152
|
+
}
|
|
151
153
|
interface ParsedCommit extends CommitMessage {
|
|
152
154
|
hash: string;
|
|
153
155
|
tags?: string[];
|
|
@@ -206,27 +208,27 @@ declare const defaultChangelogSections: {
|
|
|
206
208
|
readonly breaking: {
|
|
207
209
|
readonly title: "⚠️ BREAKING CHANGES";
|
|
208
210
|
readonly commitType: "breaking";
|
|
209
|
-
readonly
|
|
211
|
+
readonly show: "always";
|
|
210
212
|
};
|
|
211
213
|
readonly feat: {
|
|
212
214
|
readonly title: "✨ Features";
|
|
213
215
|
readonly commitType: "feat";
|
|
214
|
-
readonly
|
|
216
|
+
readonly show: "always";
|
|
215
217
|
};
|
|
216
218
|
readonly fix: {
|
|
217
219
|
readonly title: "🩹 Fixes";
|
|
218
220
|
readonly commitType: "fix";
|
|
219
|
-
readonly
|
|
221
|
+
readonly show: "always";
|
|
220
222
|
};
|
|
221
223
|
readonly perf: {
|
|
222
224
|
readonly title: "⚡ Performance";
|
|
223
225
|
readonly commitType: "perf";
|
|
224
|
-
readonly
|
|
226
|
+
readonly show: "always";
|
|
225
227
|
};
|
|
226
228
|
readonly revert: {
|
|
227
229
|
readonly title: "♻️ Reverts";
|
|
228
230
|
readonly commitType: "revert";
|
|
229
|
-
readonly
|
|
231
|
+
readonly show: "always";
|
|
230
232
|
};
|
|
231
233
|
readonly refactor: {
|
|
232
234
|
readonly title: "🚜 Refactoring";
|
|
@@ -277,7 +279,7 @@ interface TypeGroupDefinition {
|
|
|
277
279
|
title: string;
|
|
278
280
|
commitType: 'breaking' | '*' | (string & {}) | string[];
|
|
279
281
|
filter?: (commit: ResolvedCommit) => boolean;
|
|
280
|
-
|
|
282
|
+
show?: 'always' | 'limit-or-breaking' | 'only-breaking' | 'never';
|
|
281
283
|
}
|
|
282
284
|
type TypeGroupsMap = Record<string, TypeGroupDefinition>;
|
|
283
285
|
interface ScopeGroup {
|
|
@@ -317,7 +319,7 @@ interface RelionResult {
|
|
|
317
319
|
}
|
|
318
320
|
//#endregion
|
|
319
321
|
//#region src/relion.d.ts
|
|
320
|
-
declare function relion(userConfig: UserConfig): RelionResult
|
|
322
|
+
declare function relion(userConfig: UserConfig): Promise<RelionResult>;
|
|
321
323
|
//#endregion
|
|
322
324
|
//#region src/utils/sections-selector.d.ts
|
|
323
325
|
declare const sectionsSelector: SectionsSelector;
|
package/dist/index.js
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import{existsSync as e,readFileSync as t,writeFileSync as n}from"node:fs";import r from"handlebars";import i from"semver";import{createHash as a}from"node:crypto";import{execSync as o}from"node:child_process";const
|
|
1
|
+
import{existsSync as e,readFileSync as t,writeFileSync as n}from"node:fs";import r from"handlebars";import i from"semver";import{createHash as a}from"node:crypto";import{execSync as o}from"node:child_process";import s from"node:readline";const c={bump:!1,changelog:!1,commit:!1,tag:!1,versionSource:`versionSourceFile`,versionSourceFile:`./package.json`,newTagFormat:`v{{version}}`,commitsScope:`.`,prevReleaseTagPattern:/^v?(?<version>\d+\.\d+\.\d+)/,zeroMajorBreakingIsMinor:!0,dryRun:!1,logLevel:`info`,context:{commitHyperlink:!0,refHyperlink:!0,footerChangelogUrl:!1},commitsParser:{headerPattern:/^(?<type>\w+)(?:\((?<scope>.+)\))?(?<bang>!)?: (?<subject>.+)/s,breakingChangesPattern:/BREAKING CHANGES?:\s*(?<content>.+)/s,breakingChangeListPattern:/- (.+)/g,tagPattern:/tag: (?<tag>.*?)[,)]/g,coAuthorPattern:/Co-authored-by: (?<name>.+?) <(?<email>.+)>/g,signerPattern:/Signed-off-by: (?<name>.+?) <(?<email>.+)>/g,ghEmailPattern:/^(?:\d+\+)?(?<username>.+)@users\.noreply\.github\.com$/,remoteUrlPattern:/^(https:\/\/|git@)(?<host>[^/:]+)[/:](?<owner>.+?)\/(?<name>.+?)(?:\..*)?$/,refPattern:/^(?<action>.+?) (?<labels>.+)$/gm,refLabelPattern:/(?:(?<owner>\S+?)\/(?<repo>\S+?))?#(?<number>\d+)/g,refActionPattern:/^(Fixes|Closes|Refs)/i,dateSource:`authorDate`,dateFormat:`US`,revertCommitBodyPattern:/^This reverts commit (?<hash>.{7})/m}},l={breaking:{title:`⚠️ BREAKING CHANGES`,commitType:`breaking`,show:`always`},feat:{title:`✨ Features`,commitType:`feat`,show:`always`},fix:{title:`🩹 Fixes`,commitType:`fix`,show:`always`},perf:{title:`⚡ Performance`,commitType:`perf`,show:`always`},revert:{title:`♻️ Reverts`,commitType:`revert`,show:`always`},refactor:{title:`🚜 Refactoring`,commitType:`refactor`},build:{title:`📦 Build`,commitType:`build`},docs:{title:`📚 Documentation`,commitType:`docs`},style:{title:`🎨 Style`,commitType:`style`},test:{title:`🧪 Tests`,commitType:`test`},ci:{title:`🚀 CI`,commitType:`ci`},types:{title:`🏷️ Types`,commitType:`types`},deps:{title:`🧩 Dependencies`,commitType:`chore`,filter:e=>!!e.scope?.includes(`deps`)},chore:{title:`🛠️ Chores`,commitType:`chore`},misc:{title:`⚙️ Miscellaneous`,commitType:`*`,filter:e=>e.type!==`release`&&e.scope!==`release`}},u={output:`CHANGELOG.md`,commitRange:`unreleased`,sections:l,header:`# Changelog
|
|
2
2
|
|
|
3
3
|
|
|
4
|
-
`,prevReleaseHeaderPattern:/^##.*?\d+\.\d+\.\d+/m,groupCommitsByScope:!0,maxLinesPerRelease:20,helpers:{eq:(e,t)=>e===t,repeat:(e,t)=>e.repeat(t),isArray:e=>Array.isArray(e),isSingle:e=>e.length===1,or:(...e)=>e.slice(0,-1).some(Boolean),not:e=>!e,tagToUrlFragment:e=>`--${e.replace(` `,`-`).replace(/\./g,``)}-`},partials:{br:`
|
|
4
|
+
`,prevReleaseHeaderPattern:/^##.*?\d+\.\d+\.\d+/m,groupCommitsByScope:!0,maxLinesPerRelease:20,review:!1,helpers:{eq:(e,t)=>e===t,repeat:(e,t)=>e.repeat(t),isArray:e=>Array.isArray(e),isSingle:e=>e.length===1,or:(...e)=>e.slice(0,-1).some(Boolean),not:e=>!e,tagToUrlFragment:e=>`--${e.replace(` `,`-`).replace(/\./g,``)}-`},partials:{br:`
|
|
5
5
|
`,scope:`{{#if scope}}**{{scope}}**: {{/if}}`,commit:`{{{subject}}} {{" "}}
|
|
6
6
|
{{~#if @root.commitHyperlink~}}
|
|
7
7
|
[\`{{hash}}\`]({{@root.repo.homepage}}/commit/{{hash}})
|
|
8
8
|
{{~else~}}
|
|
9
9
|
{{hash}}
|
|
10
10
|
{{~/if~}}
|
|
11
|
-
{{~#if breakingChanges}}
|
|
11
|
+
{{~#if breakingChanges}} ⚠️{{>breakingChangesIndicator}}{{/if}}
|
|
12
12
|
{{~#if refs}} {{>refs}}{{/if}}`,compareLink:`{{repo.homepage~}}
|
|
13
13
|
{{#if prevRelease.tag~}}
|
|
14
14
|
/compare/{{prevRelease.tag}}...
|
|
@@ -22,16 +22,16 @@ import{existsSync as e,readFileSync as t,writeFileSync as n}from"node:fs";import
|
|
|
22
22
|
{{raw}}
|
|
23
23
|
{{~/if}}
|
|
24
24
|
{{~#if @last}}){{else}}, {{/if}}
|
|
25
|
-
{{~/each}}`,changelogUrl:`{{repo.homepage}}/blob/main/CHANGELOG.md#{{tagToUrlFragment tag}}`,breakingChangesIndicator:`<sup>[{{breakingChangeIndex}}]</sup>`}},
|
|
25
|
+
{{~/each}}`,changelogUrl:`{{repo.homepage}}/blob/main/CHANGELOG.md#{{tagToUrlFragment tag}}`,breakingChangesIndicator:`<sup>[{{breakingChangeIndex}}]</sup>`}},d={message:`chore(release): {{newTag}}`,signOff:!1,gpgSign:!1,stageAll:!0,extraArgs:null},f={name:`{{newTag}}`,message:d.message,gpgSign:!1,force:!1,extraArgs:null},p=[{file:/package\.json$/,pattern:/(^.*?"version".*?")(.*?)(")/s,replacement:`$1{{newVersion}}$3`},{file:/package-lock\.json$/,pattern:/(^.*?"version".*?"|"packages".*?"".*"version".*?")(.*?)(")/gs,replacement:`$1{{newVersion}}$3`}],m=e=>C(v(_(g(h(e))))),h=e=>{let t=e.profile;if(!t)return e;let n=e[`_${t}`];if(!n)throw Error(`Profile "${t}" not found in configuration.`);let r=(t,...r)=>{let i=e=>Object.prototype.toString.call(e)===`[object Object]`,a=(e,t)=>{let n=i(e),r=i(t);return n&&r?{...e,...t}:t??e},o=e[t],s=n[t],c=a(o,s);if(c!==void 0)return r.forEach(e=>{c[e]=a(o?.[e],s?.[e])}),c};return{...e,...n,commitsParser:r(`commitsParser`),changelog:r(`changelog`,`partials`,`helpers`),commit:r(`commit`),tag:r(`tag`),context:r(`context`)}},g=e=>{let t=(e,t,n,...r)=>{if(t==null||t===!1)return!1;if(t===!0)return n;if(typeof t!=`object`)throw Error(`Invalid value for ${e}. It should be a boolean or an object.`);let i={...n,...t};return r.forEach(e=>i[e]={...n[e],...t[e]}),i};return{...c,...e,commitsParser:{...c.commitsParser,...e.commitsParser},changelog:t(`changelog`,e.changelog,u,`partials`,`helpers`),commit:t(`commit`,e.commit,d),tag:t(`tag`,e.tag,f),context:{...c.context,...e.context}}},_=e=>{let t=e=>{let t=p.find(t=>t.file.test(e));if(t)return{...t,file:e};throw Error(`File ${e} doesn't match any default versioned files. Please provide a custom pattern for this file.`)},n=e=>{if(e===!1)return!1;if(e===!0)return[r];if(Array.isArray(e))return e.map(e=>typeof e==`string`?t(e):e);throw Error(`Invalid value for bump. It should be a boolean or an array.`)},r=typeof e.versionSourceFile==`string`?t(e.versionSourceFile):e.versionSourceFile;return{...e,versionSourceFile:r,bump:n(e.bump),changelog:e.changelog===!1?!1:{...e.changelog,compiledPartials:Q(e.changelog.partials)}}},v=e=>{let t=e.context??{},n=H(e.commitsParser.remoteUrlPattern),r=t.currentVersion??(e.versionSource===`latest-release-tag`?T(G(e.prevReleaseTagPattern)[0],e.prevReleaseTagPattern)??`0.0.0`:w(e.versionSourceFile));J(`Current version (from ${e.versionSource===`latest-release-tag`?`latest release tag`:`'${e.versionSourceFile.file}'`}): '${r}'`);let i=t.currentTag??G(e.prevReleaseTagPattern)[0],a=t.newVersion??E(e,r,e.commitsScope),o=t.newTag??(e.newTagPrefix===void 0?e.newTagFormat.replace(`{{version}}`,a):e.newTagPrefix+a),s=e.changelog?e.changelog.commitRange:`unreleased`,c=y(t.commits?t.commits.map(t=>typeof t==`object`&&`message`in t||typeof t==`string`?N(t,e.commitsParser,e.prevReleaseTagPattern):t).filter(e=>e!=null):M(s,e.commitsParser,e.prevReleaseTagPattern,e.commitsScope),o,e.commitsParser.revertCommitBodyPattern),l=e.changelog?b(c,e.changelog.sections,e.prevReleaseTagPattern,e.changelog.groupCommitsByScope,e.changelog.maxLinesPerRelease):null,{commits:u,...d}=t;return{...e,context:{currentVersion:r,currentTag:i,newVersion:a,newTag:o,commits:c,releases:l,...d,repo:{...n,...e.context?.repo}}}},y=(e,t,n)=>{let r=0,i=[];return e.map(a=>{let o=null,s=e.findIndex(e=>e.type===`revert`&&n.exec(e.body??``)?.groups?.hash===a.hash),c=s===-1?void 0:e[s];if(c&&(o=c.associatedReleaseTag===a.associatedReleaseTag?`inTheSameRelease`:`inOtherRelease`),o===`inTheSameRelease`){i.push(s);return}return{...a,associatedReleaseTag:a.associatedReleaseTag??t,isReverted:a.isReverted??o,breakingChangeIndex:a.breakingChanges?++r:void 0}}).filter((e,t)=>!!e&&!i.includes(t))},b=(e,t,n,r,i)=>{i??=u.maxLinesPerRelease;let a={};return e.forEach(e=>{let t=e.associatedReleaseTag;t in a?a[t].commits.push(e):a[t]={tag:t,version:T(t,n),date:e.date,commits:[e]}}),Object.values(a).map(({commits:e,...n})=>{let a=x(e,t,r);if(Object.keys(a).length===0)return;let o=0,s=!1,c={};for(let[e,t]of Object.entries(a))t.show??=`limit-or-breaking`,o+t.commits.length>i&&Object.keys(c).length&&(s=!0),t.show!==`never`&&(t.show===`only-breaking`||t.show===`limit-or-breaking`&&s?(t.commits=t.commits.filter(e=>!!e.breakingChanges),t.commits.length&&(t.scopeGroups=S(t.commits),c[e]=t,o+=t.commits.length)):(t.show===`always`||!s)&&(c[e]=t,o+=t.commits.length));return{...n,commitTypeGroups:c}}).filter(e=>!!e)},x=(e,t,n)=>{let r=Object.fromEntries(Object.entries(t).map(([e,{filter:t,...n}])=>[e,{...n,commits:[]}]));e.forEach(e=>{let n=!!e.breakingChanges,i=!1,a=!1;for(let o in t){if(t[o].filter&&!t[o].filter(e))continue;let s=[t[o].commitType].flat();if(n&&!a&&s.includes(`breaking`)){r[o].commits.push(e),a=!0;continue}if(!i&&(s.includes(e.type)||s.includes(`*`))&&(r[o].commits.push(e),i=!0),i&&(!n||a))return}});let i=Object.entries(r).filter(([e,t])=>t.commits.length);return Object.fromEntries(n?i.map(([e,t])=>[e,{...t,scopeGroups:S(t.commits)}]):i)},S=e=>{let t={};return e.forEach(e=>{let n=e.scope??``;t[n]??=[],t[n].push(e)}),Object.entries(t).map(([e,t])=>({scope:e,commits:t}))},C=e=>({...e,commit:e.commit?{...e.commit,message:r.compile(e.commit.message)(e.context)}:e.commit,tag:e.tag?{...e.tag,name:r.compile(e.tag.name)(e.context),message:r.compile(e.tag.message)(e.context)}:e.tag}),w=e=>{let n=t(e.file,`utf8`),r=e.pattern.exec(n)?.[2];if(!r)throw Error(`Version not found in '${e.file}' with pattern '${e.pattern}'`);if(!i.valid(r))throw Error(`Invalid version format in '${e.file}': '${r}'`);return r},T=(e,t)=>t.exec(e)?.groups?.version,E=(e,t,n)=>{if(e.context?.newVersion){if(!i.valid(e.context.newVersion))throw Error(`Invalid release version format: '${e.context.newVersion}'`);return e.context.newVersion}let r;e.releaseType?r=e.releaseType:(r=D(M(`unreleased`,e.commitsParser,e.prevReleaseTagPattern,n)),e.zeroMajorBreakingIsMinor&&i.major(t)===0&&r===`major`&&(r=`minor`));let a=O(t,r);return J(`Determined new version: '${a}' (release type: '${r}')`),a},D=e=>e.some(e=>e.breakingChanges)?`major`:e.some(e=>e.type===`feat`)?`minor`:`patch`,O=(e,t)=>i.inc(e,t)??(()=>{throw Error(`Failed to calculate new version from '${e}' with release type '${t}'`)})();let k=function(e){return e.G=`valid`,e.B=`bad`,e.U=`valid, unknown validity`,e.X=`valid, expired`,e.Y=`valid, made by expired key`,e.R=`valid, made by revoked key`,e.E=`cannot check (missing key)`,e.N=`no signature`,e}({});const A=new Map;let j;const M=(e,t,n,r)=>{n??=c.prevReleaseTagPattern;let i=Array.isArray(e)?e:U(e,n,r),a=t??c.commitsParser,o=i.map(e=>N(e,a,n)).filter(e=>e!==null);return j=void 0,o},N=(e,t,n)=>{t??=c.commitsParser,n??=c.prevReleaseTagPattern,typeof e==`string`&&(e={message:e});let{tagRefs:r,hash:i=P(e.message)}=e;if(A.has(i))return A.get(i)??null;let a=e.message.trim();if(!a)throw Error(`Message is missing for commit: ${JSON.stringify(e)}`);let o;try{o=F(a,t)}catch(e){return Y(`Error parsing commit '${i}':`,e.message),null}let{type:s,scope:l,subject:u,body:d,breakingChanges:f,footer:p}=o,m=r?[...r.matchAll(t.tagPattern)].map(e=>e.groups?.tag??``):[],h=p?[...p.matchAll(t.signerPattern)].map(e=>e.groups):[],g=[],_=e=>{g.some(t=>t.email===e.email)||g.push(e)},v=e.authorName&&e.authorEmail?L({name:e.authorName,email:e.authorEmail},h):void 0;v&&_(v);let y=e.committerName&&e.committerEmail?L({name:e.committerName,email:e.committerEmail},h):void 0;y&&_(y),(p?[...p.matchAll(t.coAuthorPattern)].map(e=>e.groups).map(e=>L(e,h)):[]).forEach(e=>_(e));let b=R(p??``,t),x=e.gpgSigCode?{code:e.gpgSigCode,label:k[e.gpgSigCode],keyId:e.gpgSigKeyId}:void 0,S=e[t.dateSource===`committerDate`?`committerTs`:`authorTs`];typeof S==`string`&&(S=z(new Date(S*1e3),t.dateFormat));let C=m.find(e=>n.exec(e)),w=C??j;w&&(j=w);let T={hash:i,type:s,scope:l,subject:u,body:d,breakingChanges:f,footer:p,committer:y,gpgSig:x,date:S,releaseTag:C,associatedReleaseTag:w,tags:m.length?m:void 0,authors:g.length?g:void 0,refs:b.length?b:void 0};return i&&!A.has(i)&&A.set(i,T),T},P=e=>`fake_`+a(`sha256`).update(e,`utf8`).digest(`hex`).slice(0,7),F=(e,t)=>{let[n,...r]=e.split(`
|
|
26
26
|
|
|
27
|
-
`),i=t.headerPattern.exec(n);if(!i?.groups)throw Error(`Commit header '${n}' doesn't match expected format`);let{type:a,scope:o,bang:s,subject:c}=i.groups,l,u=r.find(e=>t.breakingChangesPattern.test(e));u?(l=
|
|
27
|
+
`),i=t.headerPattern.exec(n);if(!i?.groups)throw Error(`Commit header '${n}' doesn't match expected format`);let{type:a,scope:o,bang:s,subject:c}=i.groups,l,u=r.find(e=>t.breakingChangesPattern.test(e));u?(l=I(u,t),r.splice(r.indexOf(u),1)):s&&(l=c);let d=r.findIndex(e=>e.match(t.refActionPattern)??e.match(t.coAuthorPattern)??e.match(t.signerPattern)),[f,p]=d===-1?[r.join(`
|
|
28
28
|
|
|
29
29
|
`),``]:[r.slice(0,d).join(`
|
|
30
30
|
|
|
31
31
|
`),r.slice(d).join(`
|
|
32
32
|
|
|
33
|
-
`)];return{type:a,scope:o||void 0,subject:c,body:f||void 0,breakingChanges:l,footer:p||void 0}},
|
|
34
|
-
`).filter(t=>e.test(t));return
|
|
33
|
+
`)];return{type:a,scope:o||void 0,subject:c,body:f||void 0,breakingChanges:l,footer:p||void 0}},I=(e,t)=>{let n=t.breakingChangesPattern.exec(e)?.groups?.content;if(!n)throw Error(`Failed to extract breaking changes content from '${e}' using pattern "${t.breakingChangesPattern}"`);let r=[...n.matchAll(t.breakingChangeListPattern)];return r.length?r.map(e=>e[1]):n},L=(e,t)=>{let n=t.some(t=>t.email===e.email&&t.name===e.name);return{...e,hasSignedOff:n,ghLogin:e.name,ghUrl:`https://github.com/${e.name}`}},R=(e,t)=>[...e.matchAll(t.refPattern)].map(e=>e.groups).filter(e=>t.refActionPattern.test(e.action)).flatMap(e=>[...e.labels.matchAll(t.refLabelPattern)].map(e=>({label:e.groups,raw:e.input})).filter(({label:e})=>!!e.number).map(({label:t,raw:n})=>({raw:n,action:e.action,owner:t.owner,repo:t.repo,number:t.number}))),z=(e,t)=>{let n=e=>e.toString().padStart(2,`0`);if(t===`US`)return e.toLocaleString(`en-US`,{month:`short`,day:`numeric`,year:`numeric`});if(t===`ISO`)return e.toISOString().split(`T`)[0];let r={YYYY:e.getUTCFullYear().toString(),MM:n(e.getUTCMonth()+1),DD:n(e.getUTCDate()),HH:n(e.getUTCHours()),mm:n(e.getUTCMinutes()),ss:n(e.getUTCSeconds())};return t.replace(/YYYY|MM|DD|HH|mm|ss/g,e=>r[e])},B=/##COMMIT##\n#HASH# (?<hash>.+)?\n#MSG# (?<message>[\s\S]*?)\n#REFS#\s+(?<tagRefs>.+)?\n#AUTHOR-NAME# (?<authorName>.+)?\n#AUTHOR-EMAIL# (?<authorEmail>.+)?\n#AUTHOR-DATE# (?<authorTs>.+)?\n#COMMITTER-NAME# (?<committerName>.+)?\n#COMMITTER-EMAIL# (?<committerEmail>.+)?\n#COMMITTER-DATE# (?<committerTs>.+)?\n#GPGSIG-CODE# (?<gpgSigCode>.+)?\n#GPGSIG-KEYID# (?<gpgSigKeyId>.+)?/g,V=new Map,H=e=>{let t=o(`git remote get-url origin`,{encoding:`utf8`}).trim(),n=e.exec(t);if(!n?.groups)throw Error(`Couldn't parse remote URL: `+t);let{host:r,owner:i,name:a}=n.groups;return{host:r,owner:i,name:a,homepage:`https://${r}/${i}/${a}`}},U=(e,t,n)=>{let r=W(),i=G(t),a=``,s=``,c=``;if(e===`all`)a=`{{firstCommit}}`,s=`HEAD`;else if(e===`unreleased`)a=i[0]??`{{firstCommit}}`,s=`HEAD`;else if(e===`latest-release`)a=i[1]??`{{firstCommit}}`,s=i[0]??`HEAD`;else if(typeof e==`object`){let t=i.indexOf(e.releaseTag);if(t===-1)throw Error(`Release tag '${e.releaseTag}' not found`);a=i[t+1]??`{{firstCommit}}`,s=i[t]}else c=e;return a&&s&&(c=a===`{{firstCommit}}`?`"${a}^!" ${s}`:`"${a}..${s}"`),c=c.replace(`{{firstCommit}}`,r),[...o(`git log ${c} --pretty="##COMMIT##%n#HASH# %h%n#MSG# %B%n#REFS# %d%n#AUTHOR-NAME# %an%n#AUTHOR-EMAIL# %ae%n#AUTHOR-DATE# %at%n#COMMITTER-NAME# %cn%n#COMMITTER-EMAIL# %ce%n#COMMITTER-DATE# %ct%n#GPGSIG-CODE# %G?%n#GPGSIG-KEYID# %GK%n" -- ${n??`.`}`,{encoding:`utf8`}).matchAll(B)].map(e=>e.groups)},W=()=>o(`git rev-list --max-parents=0 HEAD`,{encoding:`utf8`}).trim(),G=e=>{e??=c.prevReleaseTagPattern;let t=e.toString();if(V.has(t))return V.get(t)??[];let n=o(`git tag --sort=-creatordate`,{encoding:`utf8`}).split(`
|
|
34
|
+
`).filter(t=>e.test(t));return V.set(t,n),n};let K=`info`;const q=e=>K=e,J=(...e)=>{K!==`silent`&&console.log(...e)},Y=(...e)=>{K===`info`&&console.warn(...e)},X={...l,pick(...e){return Object.fromEntries(e.map(e=>[e,this[e]]))},omit(...e){let t=new Set(e);return Object.fromEntries(Object.entries(this).filter(([e])=>!t.has(e)))},modify(e,t){return{...this,[e]:t(this[e])}}};var Z=`{{~#>header~}}
|
|
35
35
|
##   [\` 📦 {{tag}} \`]({{>compareLink}}){{>br}}
|
|
36
36
|
{{/header}}
|
|
37
37
|
|
|
@@ -73,4 +73,4 @@ import{existsSync as e,readFileSync as t,writeFileSync as n}from"node:fs";import
|
|
|
73
73
|
|
|
74
74
|
{{~#>footer~}}
|
|
75
75
|
#####    {{#if footerChangelogUrl}}[_Release Changelog_]({{>changelogUrl}})  •  {{/if}}[_All Release Commits_]({{>compareLink}})  •  _{{date}}_{{>br}}{{>br}}
|
|
76
|
-
{{/footer}}`;const
|
|
76
|
+
{{/footer}}`;const Q=e=>{let t=Object.fromEntries(Object.entries(e).map(([e,t])=>[e,typeof t==`function`?$(e,t):t]));return Object.fromEntries(Object.entries(t).map(([e,t])=>[e,r.compile(t)]))},$=(e,t)=>{let n=RegExp(`${e}.*?}}\\s*(.*?){{~?/${e}`,`s`).exec(Z)?.[1];if(!n)throw Error(`Partial "${e}" not found in the release template.`);return t(n)},ee=async e=>{let t=s.createInterface({input:process.stdin,output:process.stdout});await new Promise(n=>{t.question(e,()=>{t.close(),n()})})},te=e=>{if(!e.bump)return null;let r=e.bump,i=e.context.newVersion;r.forEach(r=>{let a=t(r.file,`utf8`).replace(r.pattern,r.replacement.replace(`{{newVersion}}`,i));e.dryRun||n(r.file,a,`utf8`),J(`Updated version in '${r.file}' to '${i}'`)})},ne=async e=>{if(!e.changelog)return null;let t=e.changelog,n=e.context.releases;if(!n)return null;let i=G(e.prevReleaseTagPattern),a=r.create();a.registerPartial(t.compiledPartials),a.registerHelper(t.helpers);let o=t.header;return n.forEach((t,r)=>{let s=n[r+1];if(!s){let n=i.indexOf(t.tag);if(n!==-1){let t=i[n+1];s={tag:t,version:t&&T(t,e.prevReleaseTagPattern)}}else s={tag:e.context.currentTag,version:e.context.currentVersion}}let c={...t,...e.context,prevRelease:s},l=a.compile(Z)(c);o+=l}),t.output===`stdout`||e.dryRun?(J(`Generated changelog:`),console.log(o)):(J(`Writing changelog to file '${t.output}'`),re(t.output,o,t.prevReleaseHeaderPattern)),t.review&&t.output!==`stdout`&&(e.commit||e.tag)&&await ee(`Please review the changelog and press Enter to continue...`),o},re=(r,i,a)=>{let o=e(r)?t(r,{encoding:`utf8`}):``,s=o.search(a);n(r,i+o.slice(s),{encoding:`utf8`})},ie=e=>{if(!e.commit)return null;let t=e.commit,n=[t.stageAll&&`git add -A &&`,`git commit -m "${t.message}"`,t.signOff&&`-s`,t.gpgSign&&`-S`,t.extraArgs].filter(Boolean).join(` `);return J(`Committing with command: '${n}'`),e.dryRun||o(n,{stdio:`inherit`}),n},ae=e=>{if(!e.tag)return null;let t=e.tag,n=[`git tag -a ${t.name}`,`-m "${t.message}"`,t.gpgSign&&`-s`,t.force&&`-f`,t.extraArgs].filter(Boolean).join(` `);return J(`Tagging with command: '${n}'`),e.dryRun||o(n,{stdio:`inherit`}),n};async function oe(e){q((e.logLevel??(!!e.profile&&e[`_${e.profile}`]?.logLevel))||`info`);let t=m(e);return te(t),{resolvedConfig:t,generatedChangelog:await ne(t),commitCommand:ie(t),tagCommand:ae(t)}}const se=e=>e;export{oe as default,se as defineConfig,X as sectionsSelector};
|
package/package.json
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "relion",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "Release workflow helper
|
|
3
|
+
"version": "0.21.0",
|
|
4
|
+
"description": "Release workflow helper.",
|
|
5
5
|
"author": "Kh4f <kh4f.dev@gmail.com>",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"engines": {
|
|
8
|
-
"node": "^24.
|
|
8
|
+
"node": "^24.10.0"
|
|
9
9
|
},
|
|
10
10
|
"repository": "https://github.com/kh4f/relion",
|
|
11
11
|
"bugs": "https://github.com/kh4f/relion/issues",
|
|
@@ -33,21 +33,21 @@
|
|
|
33
33
|
"dependencies": {
|
|
34
34
|
"cleye": "^1.3.4",
|
|
35
35
|
"handlebars": "^4.7.8",
|
|
36
|
-
"semver": "^7.7.
|
|
36
|
+
"semver": "^7.7.3"
|
|
37
37
|
},
|
|
38
38
|
"devDependencies": {
|
|
39
|
-
"@eslint/js": "^9.
|
|
39
|
+
"@eslint/js": "^9.37.0",
|
|
40
40
|
"@stylistic/eslint-plugin": "^5.4.0",
|
|
41
|
-
"@types/node": "^24.
|
|
41
|
+
"@types/node": "^24.7.1",
|
|
42
42
|
"@types/semver": "^7.7.1",
|
|
43
|
-
"eslint": "^9.
|
|
43
|
+
"eslint": "^9.37.0",
|
|
44
44
|
"globals": "^16.4.0",
|
|
45
45
|
"lint-staged": "^16.2.3",
|
|
46
46
|
"simple-git-hooks": "^2.13.1",
|
|
47
47
|
"tsdown": "^0.15.6",
|
|
48
48
|
"tsx": "^4.20.6",
|
|
49
49
|
"typescript": "^5.9.3",
|
|
50
|
-
"typescript-eslint": "^8.
|
|
50
|
+
"typescript-eslint": "^8.46.0",
|
|
51
51
|
"vitest": "^3.2.4"
|
|
52
52
|
},
|
|
53
53
|
"simple-git-hooks": {
|
|
@@ -64,8 +64,8 @@
|
|
|
64
64
|
"lint:fix": "eslint --fix",
|
|
65
65
|
"test": "vitest run",
|
|
66
66
|
"test:watch": "vitest",
|
|
67
|
-
"release": "pnpm relion",
|
|
68
|
-
"release:github": "pnpm relion
|
|
67
|
+
"release": "pnpm relion -p local",
|
|
68
|
+
"release:github": "pnpm relion -p github",
|
|
69
69
|
"relion": "tsx scripts/relion-runner"
|
|
70
70
|
}
|
|
71
71
|
}
|