relion 0.9.0 → 0.10.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/index.d.ts +16 -22
- package/dist/index.js +20 -8
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -40,7 +40,7 @@ type BumpFiles = (string | VersionedFile)[];
|
|
|
40
40
|
interface ChangelogOptions {
|
|
41
41
|
output?: 'stdout' | (string & {});
|
|
42
42
|
commitRange?: CommitRange;
|
|
43
|
-
sections?:
|
|
43
|
+
sections?: TypeGroupsMap;
|
|
44
44
|
header?: string;
|
|
45
45
|
prevReleaseHeaderPattern?: RegExp;
|
|
46
46
|
helpers?: HelperDeclareSpec;
|
|
@@ -79,7 +79,7 @@ interface CommitsParser {
|
|
|
79
79
|
remoteUrlPattern?: RegExp;
|
|
80
80
|
signerPattern?: RegExp;
|
|
81
81
|
dateSource?: 'authorDate' | 'committerDate';
|
|
82
|
-
dateFormat?: string;
|
|
82
|
+
dateFormat?: 'US' | 'ISO' | (string & {});
|
|
83
83
|
revertCommitBodyPattern?: RegExp;
|
|
84
84
|
}
|
|
85
85
|
type CompleteCommitsParser = Required<CommitsParser>;
|
|
@@ -100,18 +100,11 @@ interface Context {
|
|
|
100
100
|
}
|
|
101
101
|
interface ResolvedContext extends Required<Context> {
|
|
102
102
|
commits: ResolvedCommit[];
|
|
103
|
-
releases:
|
|
103
|
+
releases: ReleaseWithTypeGroups[] | null;
|
|
104
104
|
}
|
|
105
105
|
type CommitRange = 'all' | 'unreleased' | 'latest-release' | {
|
|
106
106
|
versionTag: string;
|
|
107
|
-
} | {
|
|
108
|
-
from: 'firstCommit' | (string & {});
|
|
109
|
-
} | {
|
|
110
|
-
to: 'HEAD' | (string & {});
|
|
111
|
-
} | {
|
|
112
|
-
from: 'firstCommit' | (string & {});
|
|
113
|
-
to: 'HEAD' | (string & {});
|
|
114
|
-
};
|
|
107
|
+
} | (string & {});
|
|
115
108
|
type ReleaseType = 'major' | 'minor' | 'patch';
|
|
116
109
|
interface VersionedFile {
|
|
117
110
|
filePath: string;
|
|
@@ -159,14 +152,15 @@ interface ParsedCommit extends CommitMessage {
|
|
|
159
152
|
refs?: Reference[];
|
|
160
153
|
gpgSig?: GpgSig;
|
|
161
154
|
date?: string;
|
|
162
|
-
|
|
155
|
+
releaseTag?: string;
|
|
156
|
+
associatedReleaseTag?: string;
|
|
163
157
|
isReverted?: 'inTheSameRelease' | 'inOtherRelease' | null;
|
|
164
158
|
}
|
|
165
159
|
interface ParsedCommitWithReleaseTag extends ParsedCommit {
|
|
166
|
-
associatedReleaseTag:
|
|
160
|
+
associatedReleaseTag: NonNullable<ParsedCommit['associatedReleaseTag']>;
|
|
167
161
|
}
|
|
168
162
|
interface ResolvedCommit extends ParsedCommitWithReleaseTag {
|
|
169
|
-
isReverted: '
|
|
163
|
+
isReverted: NonNullable<ParsedCommit['isReverted']> | null;
|
|
170
164
|
}
|
|
171
165
|
interface CommitMessage {
|
|
172
166
|
type: string;
|
|
@@ -271,26 +265,26 @@ declare const defaultChangelogSections: {
|
|
|
271
265
|
};
|
|
272
266
|
//#endregion
|
|
273
267
|
//#region src/types/changelog.d.ts
|
|
274
|
-
interface
|
|
268
|
+
interface TypeGroupDefinition {
|
|
275
269
|
title: string;
|
|
276
270
|
commitType: 'breaking' | '*' | (string & {}) | string[];
|
|
277
271
|
filter?: (commit: ResolvedCommit) => boolean;
|
|
278
272
|
}
|
|
279
|
-
type
|
|
280
|
-
interface
|
|
273
|
+
type TypeGroupsMap = Record<string, TypeGroupDefinition>;
|
|
274
|
+
interface FilledTypeGroup extends Omit<TypeGroupDefinition, 'filter'> {
|
|
281
275
|
commits: ResolvedCommit[];
|
|
282
276
|
}
|
|
283
|
-
type
|
|
277
|
+
type FilledTypeGroupMap = Record<string, FilledTypeGroup>;
|
|
284
278
|
interface ReleaseWithFlatCommits {
|
|
285
279
|
tag: string;
|
|
286
280
|
version?: string;
|
|
287
281
|
date?: string;
|
|
288
282
|
commits: ResolvedCommit[];
|
|
289
283
|
}
|
|
290
|
-
interface
|
|
291
|
-
commitTypeGroups:
|
|
284
|
+
interface ReleaseWithTypeGroups extends Omit<ReleaseWithFlatCommits, 'commits'> {
|
|
285
|
+
commitTypeGroups: FilledTypeGroupMap;
|
|
292
286
|
}
|
|
293
|
-
interface ReleaseContext extends
|
|
287
|
+
interface ReleaseContext extends ReleaseWithTypeGroups, ResolvedContext {
|
|
294
288
|
prevTag?: string;
|
|
295
289
|
prevVersion?: string;
|
|
296
290
|
}
|
|
@@ -307,4 +301,4 @@ declare const defineConfig: (config: UserConfig) => UserConfig;
|
|
|
307
301
|
//#region src/utils/sections-selector.d.ts
|
|
308
302
|
declare const changelogSectionsSelector: ChangelogSectionsSelector;
|
|
309
303
|
//#endregion
|
|
310
|
-
export { BumpFiles, ChangelogOptions,
|
|
304
|
+
export { BumpFiles, ChangelogOptions, ChangelogSectionsSelector, CommitMessage, CommitOptions, CommitRange, CommitsParser, CompleteChangelogOptions, CompleteCommitOptions, CompleteCommitsParser, CompleteTagOptions, Context, ContextualConfig, Contributor, DefaultChangelogSections, DefaultVersionedFile, FalseOrComplete, FilledTypeGroup, FilledTypeGroupMap, GithubUserInfo, GpgSig, GpgSigCode, MergedConfig, ParsedCommit, RawCommit, RawReference, RefLabel, Reference, ReleaseContext, ReleaseType, ReleaseWithFlatCommits, ReleaseWithTypeGroups, RepoInfo, ResolvedChangelogOptions, ResolvedCommit, ResolvedConfig, ResolvedContext, TagOptions, TransformedConfig, TypeGroupDefinition, TypeGroupsMap, UserConfig, VersionedFile, changelogSectionsSelector, relion as default, defineConfig };
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
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 s={bump:!1,changelog:!1,commit:!1,tag:!1,versionSourceFile:`./package.json`,newTagFormat:`v{{newVersion}}`,prevReleaseTagPattern:/^v?(?<version>\d+\.\d+\.\d+)/,zeroMajorBreakingIsMinor:!0,dryRun:!1,silent:!1,context:{commitHyperlink:!0,refHyperlink:!0},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:`
|
|
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 s={bump:!1,changelog:!1,commit:!1,tag:!1,versionSourceFile:`./package.json`,newTagFormat:`v{{newVersion}}`,prevReleaseTagPattern:/^v?(?<version>\d+\.\d+\.\d+)/,zeroMajorBreakingIsMinor:!0,dryRun:!1,silent:!1,context:{commitHyperlink:!0,refHyperlink:!0},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}},c={breaking:{title:`⚠️ BREAKING CHANGES`,commitType:`breaking`},feat:{title:`✨ Features`,commitType:`feat`},fix:{title:`🩹 Fixes`,commitType:`fix`},perf:{title:`⚡ Performance`,commitType:`perf`},refactor:{title:`🚜 Refactoring`,commitType:`refactor`},docs:{title:`📚 Documentation`,commitType:`docs`},style:{title:`🎨 Style`,commitType:`style`},build:{title:`📦 Build`,commitType:`build`},ci:{title:`🚀 CI`,commitType:`ci`},revert:{title:`♻️ Reverts`,commitType:`revert`},types:{title:`🏷️ Types`,commitType:`types`},deps:{title:`🧩 Dependencies`,commitType:`chore`,filter:e=>!!e.scope?.includes(`deps`)},chore:{title:`🛠️ Chores`,commitType:`chore`},test:{title:`🧪 Tests`,commitType:`test`},misc:{title:`⚙️ Miscellaneous`,commitType:`*`,filter:e=>e.type!==`release`}},l={output:`CHANGELOG.md`,commitRange:`unreleased`,sections:c,header:`# Changelog
|
|
2
2
|
|
|
3
3
|
|
|
4
|
-
`,prevReleaseHeaderPattern:/^##.*?\d+\.\d+\.\d+/m,helpers:{eq:(e,t)=>e===t,repeat:(e,t)=>e.repeat(t)},partials:{}},u={message:`release({{repo.name}}): {{newTag}}`,signOff:!1,gpgSign:!1,stageAll:!0,extraArgs:``},d={name:`{{newTag}}`,message:`release({{repo.name}}): {{newTag}}`,gpgSign:!1,force:!1,extraArgs:``},f=[{filePathRegex:/package\.json$/,versionPattern:/(^.*?"version".*?")(.*?)(")/s},{filePathRegex:/package-lock\.json$/,versionPattern:/(^.*?"version".*?"|"packages".*?"".*"version".*?")(.*?)(")/gs}],p=async e=>{let t=m(e),n=h(t),r=g(n),i=await _(r),a=S(i);return a},m=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);if(n&&r)return{...e,...t};if(!n&&r)return t;if(n&&!r)return 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`)}},h=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{...s,...e,commitsParser:{...s.commitsParser,...e.commitsParser},changelog:t(`changelog`,e.changelog,l,`partials`,`helpers`),commit:t(`commit`,e.commit,u),tag:t(`tag`,e.tag,d)}},g=e=>{let t=e=>{let t=f.find(t=>t.filePathRegex.test(e));if(t)return{filePath:e,versionPattern:t.versionPattern};throw Error(`File ${e} doesn't match any default versioned files. Please provide a custom version pattern for this file.`)},n=e=>{if(e===!1)return!1;if(e===!0)return[i];if(Array.isArray(e))return[i,...e.map(e=>typeof e==`string`?t(e):e)];throw Error(`Invalid value for bump. It should be a boolean or an array.`)},i=typeof e.versionSourceFile==`string`?t(e.versionSourceFile):e.versionSourceFile;return{...e,versionSourceFile:i,bump:n(e.bump),changelog:e.changelog===!1?!1:{...e.changelog,compiledPartials:Object.fromEntries(Object.entries(e.changelog.partials).map(([e,t])=>[e,r.compile(t)]))}}},_=async e=>{let t=e.context??{},n=B(e.commitsParser.remoteUrlPattern);t.repo={...n,...t.repo};let r=e.changelog?e.changelog.commitRange:`unreleased`,i=e.context?.commits?(await Promise.all(e.context.commits.map(async t=>typeof t==`object`&&`message`in t||typeof t==`string`?await M(t,e.commitsParser,e.prevReleaseTagPattern):t))).filter(e=>e!=null):await j(r,e.commitsParser,e.prevReleaseTagPattern);t.currentVersion??=w(e.versionSourceFile),t.currentTag??=U(e.prevReleaseTagPattern)[0],t.newVersion??=await T(e,t.currentVersion),t.newTag??=C(e.newTagFormat,t),t.commits=v(i,t.newTag,e.commitsParser.revertCommitBodyPattern);let a={...e,context:t};return t.releases=e.changelog?y(t.commits,e.changelog.sections,a):null,a},v=(e,t,n)=>{let r=(e,t)=>e.map(e=>({...e,associatedReleaseTag:e.associatedReleaseTag??t})),i=e=>e.map(t=>{let r=null,i=e.find(e=>e.type===`revert`&&n.exec(e.body??``)?.groups?.hash===t.hash);return i&&(r=i.associatedReleaseTag===t.associatedReleaseTag?`inTheSameRelease`:`inOtherRelease`),{...t,isReverted:t.isReverted??r}}),a=r(e,t),o=i(a);return o},y=(e,t,n)=>{let r={};return e.forEach(e=>{let t=e.associatedReleaseTag;t in r?r[t].commits.push(e):r[t]={tag:t,version:n.prevReleaseTagPattern.exec(t)?.groups?.version,date:e.date,commits:[e]}}),Object.values(r).map(e=>b(e,t)).filter(e=>Object.keys(e.commitTypeGroups).length)},b=(e,t)=>{let{commits:n,...r}=e;return{...r,commitTypeGroups:x(n,t)}},x=(e,t)=>{let n=Object.fromEntries(Object.entries(t).map(([e,t])=>[e,{...t,commits:[]}]));return e.forEach(e=>{let r=!!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(r&&!a&&s.includes(`breaking`)){n[o].commits.push(e),a=!0;continue}if(!i&&(s.includes(e.type)||s.includes(`*`))&&(n[o].commits.push(e),i=!0),i&&(!r||a))return}}),Object.keys(n).forEach(e=>{n[e].commits.length||delete n[e]}),n},S=e=>({...e,commit:e.commit?{...e.commit,message:C(e.commit.message,e.context)}:e.commit,tag:e.tag?{...e.tag,name:C(e.tag.name,e.context),message:C(e.tag.message,e.context)}:e.tag}),C=(e,t)=>{let n=r.compile(e);return n(t)},w=e=>{let n=t(e.filePath,`utf8`),r=e.versionPattern.exec(n)?.[2];if(!r)throw Error(`Version not found in '${e.filePath}' with pattern '${e.versionPattern}'`);if(!i.valid(r))throw Error(`Invalid version format in '${e.filePath}': '${r}'`);return K(`Current version from '${e.filePath}': '${r}'`),r},T=async(e,t)=>{if(e.releaseVersion){if(!i.valid(e.releaseVersion))throw Error(`Invalid release version format: '${e.releaseVersion}'`);return e.releaseVersion}let n;if(e.releaseType)n=e.releaseType;else{let r=await j(`unreleased`,e.commitsParser,e.prevReleaseTagPattern);n=E(r),e.zeroMajorBreakingIsMinor&&i.major(t)===0&&n===`major`&&(n=`minor`)}let r=D(t,n);return K(`Determined new version: '${r}' (release type: '${n}')`),r},E=e=>{let t=e.some(e=>e.breakingChanges);if(t)return`major`;let n=e.some(e=>e.type===`feat`);return n?`minor`:`patch`},D=(e,t)=>i.inc(e,t)??(()=>{throw Error(`Failed to calculate new version from '${e}' with release type '${t}'`)})();let O=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 k={};let A
|
|
4
|
+
`,prevReleaseHeaderPattern:/^##.*?\d+\.\d+\.\d+/m,helpers:{eq:(e,t)=>e===t,repeat:(e,t)=>e.repeat(t),isArray:e=>Array.isArray(e)},partials:{}},u={message:`release({{repo.name}}): {{newTag}}`,signOff:!1,gpgSign:!1,stageAll:!0,extraArgs:``},d={name:`{{newTag}}`,message:`release({{repo.name}}): {{newTag}}`,gpgSign:!1,force:!1,extraArgs:``},f=[{filePathRegex:/package\.json$/,versionPattern:/(^.*?"version".*?")(.*?)(")/s},{filePathRegex:/package-lock\.json$/,versionPattern:/(^.*?"version".*?"|"packages".*?"".*"version".*?")(.*?)(")/gs}],p=async e=>{let t=m(e),n=h(t),r=g(n),i=await _(r),a=S(i);return a},m=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);if(n&&r)return{...e,...t};if(!n&&r)return t;if(n&&!r)return 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`)}},h=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{...s,...e,commitsParser:{...s.commitsParser,...e.commitsParser},changelog:t(`changelog`,e.changelog,l,`partials`,`helpers`),commit:t(`commit`,e.commit,u),tag:t(`tag`,e.tag,d)}},g=e=>{let t=e=>{let t=f.find(t=>t.filePathRegex.test(e));if(t)return{filePath:e,versionPattern:t.versionPattern};throw Error(`File ${e} doesn't match any default versioned files. Please provide a custom version pattern for this file.`)},n=e=>{if(e===!1)return!1;if(e===!0)return[i];if(Array.isArray(e))return[i,...e.map(e=>typeof e==`string`?t(e):e)];throw Error(`Invalid value for bump. It should be a boolean or an array.`)},i=typeof e.versionSourceFile==`string`?t(e.versionSourceFile):e.versionSourceFile;return{...e,versionSourceFile:i,bump:n(e.bump),changelog:e.changelog===!1?!1:{...e.changelog,compiledPartials:Object.fromEntries(Object.entries(e.changelog.partials).map(([e,t])=>[e,r.compile(t)]))}}},_=async e=>{let t=e.context??{},n=B(e.commitsParser.remoteUrlPattern);t.repo={...n,...t.repo};let r=e.changelog?e.changelog.commitRange:`unreleased`,i=e.context?.commits?(await Promise.all(e.context.commits.map(async t=>typeof t==`object`&&`message`in t||typeof t==`string`?await M(t,e.commitsParser,e.prevReleaseTagPattern):t))).filter(e=>e!=null):await j(r,e.commitsParser,e.prevReleaseTagPattern);t.currentVersion??=w(e.versionSourceFile),t.currentTag??=U(e.prevReleaseTagPattern)[0],t.newVersion??=await T(e,t.currentVersion),t.newTag??=C(e.newTagFormat,t),t.commits=v(i,t.newTag,e.commitsParser.revertCommitBodyPattern);let a={...e,context:t};return t.releases=e.changelog?y(t.commits,e.changelog.sections,a):null,a},v=(e,t,n)=>{let r=(e,t)=>e.map(e=>({...e,associatedReleaseTag:e.associatedReleaseTag??t})),i=e=>e.map(t=>{let r=null,i=e.find(e=>e.type===`revert`&&n.exec(e.body??``)?.groups?.hash===t.hash);return i&&(r=i.associatedReleaseTag===t.associatedReleaseTag?`inTheSameRelease`:`inOtherRelease`),{...t,isReverted:t.isReverted??r}}),a=r(e,t),o=i(a);return o},y=(e,t,n)=>{let r={};return e.forEach(e=>{let t=e.associatedReleaseTag;t in r?r[t].commits.push(e):r[t]={tag:t,version:n.prevReleaseTagPattern.exec(t)?.groups?.version,date:e.date,commits:[e]}}),Object.values(r).map(e=>b(e,t)).filter(e=>Object.keys(e.commitTypeGroups).length)},b=(e,t)=>{let{commits:n,...r}=e;return{...r,commitTypeGroups:x(n,t)}},x=(e,t)=>{let n=Object.fromEntries(Object.entries(t).map(([e,t])=>[e,{...t,commits:[]}]));return e.forEach(e=>{let r=!!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(r&&!a&&s.includes(`breaking`)){n[o].commits.push(e),a=!0;continue}if(!i&&(s.includes(e.type)||s.includes(`*`))&&(n[o].commits.push(e),i=!0),i&&(!r||a))return}}),Object.keys(n).forEach(e=>{n[e].commits.length||delete n[e]}),n},S=e=>({...e,commit:e.commit?{...e.commit,message:C(e.commit.message,e.context)}:e.commit,tag:e.tag?{...e.tag,name:C(e.tag.name,e.context),message:C(e.tag.message,e.context)}:e.tag}),C=(e,t)=>{let n=r.compile(e);return n(t)},w=e=>{let n=t(e.filePath,`utf8`),r=e.versionPattern.exec(n)?.[2];if(!r)throw Error(`Version not found in '${e.filePath}' with pattern '${e.versionPattern}'`);if(!i.valid(r))throw Error(`Invalid version format in '${e.filePath}': '${r}'`);return K(`Current version from '${e.filePath}': '${r}'`),r},T=async(e,t)=>{if(e.releaseVersion){if(!i.valid(e.releaseVersion))throw Error(`Invalid release version format: '${e.releaseVersion}'`);return e.releaseVersion}let n;if(e.releaseType)n=e.releaseType;else{let r=await j(`unreleased`,e.commitsParser,e.prevReleaseTagPattern);n=E(r),e.zeroMajorBreakingIsMinor&&i.major(t)===0&&n===`major`&&(n=`minor`)}let r=D(t,n);return K(`Determined new version: '${r}' (release type: '${n}')`),r},E=e=>{let t=e.some(e=>e.breakingChanges);if(t)return`major`;let n=e.some(e=>e.type===`feat`);return n?`minor`:`patch`},D=(e,t)=>i.inc(e,t)??(()=>{throw Error(`Failed to calculate new version from '${e}' with release type '${t}'`)})();let O=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 k={};let A;const j=async(e,t,n)=>{let r=Array.isArray(e)?e:V(e,n),i=t,a=(await Promise.all(r.map(async e=>M(e,i,n)))).filter(e=>e!==null);return A=void 0,a},M=async(e,t,n)=>{typeof e==`string`&&(e={message:e});let{tagRefs:r,hash:i=N(e.message)}=e;if(i in k)return k[i];let a=e.message.trim();if(!a)throw Error(`Message is missing for commit: ${JSON.stringify(e)}`);let o;try{o=P(a,t)}catch(e){return console.warn(`Error parsing commit '${i}':`,e.message),null}let{type:s,scope:c,subject:l,body:u,breakingChanges:d,footer:f}=o,p=r?[...r.matchAll(t.tagPattern)].map(e=>e.groups?.tag??``):[],m=f?[...f.matchAll(t.signerPattern)].map(e=>e.groups):[],h=[],g=e=>{h.some(t=>t.email===e.email)||h.push(e)},_=e.authorName&&e.authorEmail?I({name:e.authorName,email:e.authorEmail},m):void 0;_&&g(_);let v=e.committerName&&e.committerEmail?I({name:e.committerName,email:e.committerEmail},m):void 0;v&&g(v);let y=f?[...f.matchAll(t.coAuthorPattern)].map(e=>e.groups).map(e=>I(e,m)):[];y.forEach(e=>g(e));let b=await L(f??``,t),x=e.gpgSigCode?{code:e.gpgSigCode,label:O[e.gpgSigCode],keyId:e.gpgSigKeyId}:void 0,S=e[t.dateSource===`committerDate`?`committerTs`:`authorTs`];typeof S==`string`&&(S=R(new Date(S*1e3),t.dateFormat));let C=p.find(e=>n.exec(e)),w=C??A;w&&(A=w);let T={hash:i,type:s,scope:c,subject:l,body:u,breakingChanges:d,footer:f,committer:v,gpgSig:x,date:S,releaseTag:C,associatedReleaseTag:w,tags:p.length?p:void 0,authors:h.length?h:void 0,refs:b.length?b:void 0};return i&&!(i in k)&&(k[i]=T),T},N=e=>`fake_`+a(`sha256`).update(e,`utf8`).digest(`hex`).slice(0,7),P=(e,t)=>{let[n,...r]=e.split(`
|
|
5
5
|
|
|
6
6
|
`),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=F(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(`
|
|
7
7
|
|
|
@@ -9,7 +9,7 @@ import{existsSync as e,readFileSync as t,writeFileSync as n}from"node:fs";import
|
|
|
9
9
|
|
|
10
10
|
`),r.slice(d).join(`
|
|
11
11
|
|
|
12
|
-
`)];return{type:a,scope:o||void 0,subject:c,body:f||void 0,breakingChanges:l,footer:p||void 0}},F=(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},I=(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}`}},L=async(e,t)=>await Promise.all([...e.matchAll(t.refPattern)].map(e=>e.groups).filter(e=>t.refActionPattern.test(e.action)).flatMap(e=>[...e.labels.matchAll(t.refLabelPattern)].map(e=>e.groups).filter(e=>!!e.number).map(t=>({action:e.action,owner:t.owner,repo:t.repo,number:t.number})))),R=(e,t)=>{let n=e=>e.toString().padStart(2,`0`)
|
|
12
|
+
`)];return{type:a,scope:o||void 0,subject:c,body:f||void 0,breakingChanges:l,footer:p||void 0}},F=(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},I=(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}`}},L=async(e,t)=>await Promise.all([...e.matchAll(t.refPattern)].map(e=>e.groups).filter(e=>t.refActionPattern.test(e.action)).flatMap(e=>[...e.labels.matchAll(t.refLabelPattern)].map(e=>e.groups).filter(e=>!!e.number).map(t=>({action:e.action,owner:t.owner,repo:t.repo,number:t.number})))),R=(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])},z=/##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,B=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,s=`https://${r}/${i}/${a}`;return{host:r,owner:i,name:a,homepage:s}},V=(e,t)=>{let n=H(),r=U(t),i=``,a=``,s=``;if(e===`all`)i=`{{firstCommit}}`,a=`HEAD`;else if(e===`unreleased`)i=r[0]??`{{firstCommit}}`,a=`HEAD`;else if(e===`latest-release`)i=r[1]??`{{firstCommit}}`,a=r[0]??`HEAD`;else if(typeof e==`object`){let t=r.indexOf(e.versionTag);if(t===-1)throw Error(`Version tag '${e.versionTag}' not found`);i=r[t+1]??`{{firstCommit}}`,a=r[t]}else s=e;i&&a&&(s=i===`{{firstCommit}}`?`"${i}^!" ${a}`:`"${i}..${a}"`),s=s.replace(`{{firstCommit}}`,n);let c=o(`git log ${s} --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"`,{encoding:`utf8`});return[...c.matchAll(z)].map(e=>e.groups)},H=()=>o(`git rev-list --max-parents=0 HEAD`,{encoding:`utf8`}).trim(),U=e=>{let t=o(`git tag --sort=-creatordate`,{encoding:`utf8`});return t.split(`
|
|
13
13
|
`).filter(t=>e.test(t))};let W=!1;const G=e=>W=e,K=(...e)=>{W||console.log(...e)},q={...c,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)))}},J=e=>{if(!e.bump)return;let r=e.bump,i=e.context.newVersion;r.forEach(r=>{let a=t(r.filePath,`utf8`),o=a.replace(r.versionPattern,`$1${i}$3`);e.dryRun||n(r.filePath,o,`utf8`),K(`Updated version in '${r.filePath}' to '${i}'`)})};var Y=`{{#>header}}
|
|
14
14
|
##   [\` 📦 {{tag}} \`]({{repo.homepage}}/{{#if prevTag}}compare/{{prevTag}}...{{tag}}{{else}}commits/{{tag}}{{/if}})
|
|
15
15
|
|
|
@@ -17,18 +17,30 @@ import{existsSync as e,readFileSync as t,writeFileSync as n}from"node:fs";import
|
|
|
17
17
|
{{#each commitTypeGroups}}
|
|
18
18
|
### {{{repeat ' ' 5}}}{{title}}
|
|
19
19
|
{{#if (eq @key 'breaking')}}
|
|
20
|
-
{{#each commits}}
|
|
21
|
-
|
|
22
|
-
{{
|
|
20
|
+
{{#each commits}}
|
|
21
|
+
{{#if (isArray breakingChanges)}}
|
|
22
|
+
{{~#each breakingChanges~}}
|
|
23
|
+
- {{{this}}}
|
|
24
|
+
{{/each}}
|
|
25
|
+
{{else~}}
|
|
26
|
+
- {{{breakingChanges}}}
|
|
27
|
+
{{/if}}
|
|
28
|
+
{{/each}}
|
|
23
29
|
{{else}}
|
|
24
30
|
{{#each commits}}
|
|
25
|
-
|
|
31
|
+
- {{#if scope}}**{{scope}}**: {{/if}}{{{subject}}} {{#if ../../commitHyperlink}}[\`{{hash}}\`]({{../../repo.homepage}}/commit/{{hash}}){{else}}{{hash}}{{/if}}
|
|
26
32
|
{{/each}}
|
|
27
33
|
{{/if}}
|
|
28
34
|
|
|
29
35
|
{{/each}}
|
|
30
36
|
{{#>footer}}
|
|
31
|
-
#####    [_All Release Commits_]
|
|
37
|
+
#####    [_All Release Commits_]
|
|
38
|
+
{{~#if prevTag~}}
|
|
39
|
+
({{repo.homepage}}/compare/{{prevTag}}...{{tag}})
|
|
40
|
+
{{~else~}}
|
|
41
|
+
({{repo.homepage}}/commits/{{tag}})
|
|
42
|
+
{{~/if}}
|
|
43
|
+
{{" "}}  •  _{{date}}_
|
|
32
44
|
|
|
33
45
|
|
|
34
46
|
{{/footer}}`;const X=e=>{if(!e.changelog)return;let t=e.changelog,n=e.context.releases;if(!n)return;let i=U(e.prevReleaseTagPattern);r.registerPartial(t.compiledPartials),r.registerHelper(t.helpers);let a=t.header;n.forEach((t,r)=>{let o=n[r+1],s,c;if(o)s=o.tag,c=$(s,e.prevReleaseTagPattern);else{let n=i.indexOf(t.tag);n===-1?(s=e.context.currentTag,c=$(s,e.prevReleaseTagPattern)):(s=i[n+1],c=s&&$(s,e.prevReleaseTagPattern))}let l={...t,...e.context,prevTag:s,prevVersion:c},u=Q(Y,l);a+=u}),t.output===`stdout`?(K(`Generated changelog:`),console.log(a)):(K(`Writing changelog to file '${t.output}'`),e.dryRun||Z(t.output,a,t.prevReleaseHeaderPattern))},Z=(r,i,a)=>{let o=e(r)?t(r,{encoding:`utf8`}):``,s=o.search(a),c=o.slice(s),l=i+c;n(r,l,{encoding:`utf8`})},Q=(e,t)=>{let n=r.compile(e);return n(t)},$=(e,t)=>t.exec(e)?.groups?.version,ee=e=>{if(!e.commit)return;let t=e.commit;K(`Committing with options:`,t),t.stageAll&&!e.dryRun&&o(`git add -A`,{stdio:`inherit`}),e.dryRun||o(`git commit -m "${t.message}" ${t.signOff?`-s`:``} ${t.gpgSign?`-S`:``} ${t.extraArgs}`,{stdio:`inherit`})},te=e=>{if(!e.tag)return;let t=e.tag;K(`Tagging with options:`,t),e.dryRun||o(`git tag -a ${t.name} -m "${t.message}" ${t.gpgSign?`-s`:``} ${t.force?`-f`:``} ${t.extraArgs}`,{stdio:`inherit`})};async function ne(e){G(!!e.silent||!!e.profile&&!!e[`_${e.profile}`]?.silent);let t=await p(e);J(t),X(t),ee(t),te(t)}const re=e=>e;export{q as changelogSectionsSelector,ne as default,re as defineConfig};
|