@furystack/yarn-plugin-changelog 1.0.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 ADDED
@@ -0,0 +1,181 @@
1
+ # @furystack/yarn-plugin-changelog
2
+
3
+ A Yarn plugin for automated changelog generation and management in monorepos. It integrates with Yarn's version plugin to generate, validate, and apply changelog entries from version manifests.
4
+
5
+ ## Installation
6
+
7
+ ### As a Yarn Plugin (Recommended)
8
+
9
+ ```bash
10
+ yarn plugin import https://raw.githubusercontent.com/furystack/furystack/main/packages/yarn-plugin-changelog/bundles/@yarnpkg/plugin-changelog.js
11
+ ```
12
+
13
+ ### From NPM
14
+
15
+ ```bash
16
+ yarn plugin import @furystack/yarn-plugin-changelog
17
+ ```
18
+
19
+ ## Usage
20
+
21
+ This plugin provides three commands that work together with Yarn's version workflow:
22
+
23
+ ### 1. Create Changelog Drafts
24
+
25
+ Generate changelog draft files from version manifests (`.yarn/versions/*.yml`):
26
+
27
+ ```bash
28
+ yarn changelog create
29
+ ```
30
+
31
+ This creates draft files in `.yarn/changelogs/` with template sections based on the version bump type (patch/minor/major).
32
+
33
+ **Options:**
34
+
35
+ | Flag | Description |
36
+ | --------------------- | ---------------------------------------------------------------------- |
37
+ | `-v, --verbose` | Show verbose output |
38
+ | `-f, --force` | Regenerate changelogs with mismatched version types or invalid entries |
39
+ | `--dependabot` | Auto-fill changelog for dependency updates (Dependabot PRs) |
40
+ | `-m, --message <msg>` | Custom message for the changelog entry (used with `--dependabot`) |
41
+
42
+ **Examples:**
43
+
44
+ ```bash
45
+ # Generate changelog drafts for all version manifests
46
+ yarn changelog create
47
+
48
+ # Regenerate mismatched or invalid changelogs
49
+ yarn changelog create --force
50
+
51
+ # Auto-fill for Dependabot dependency updates
52
+ yarn changelog create --dependabot
53
+
54
+ # With custom message (e.g., from PR title)
55
+ yarn changelog create --dependabot -m "Bump lodash from 4.17.20 to 4.17.21"
56
+ ```
57
+
58
+ ### 2. Validate Changelogs
59
+
60
+ Validate that all changelog entries are complete and match their version manifests:
61
+
62
+ ```bash
63
+ yarn changelog check
64
+ ```
65
+
66
+ **Validates:**
67
+
68
+ - Every release in `.yarn/versions/*.yml` has a corresponding changelog file
69
+ - Major releases have filled "Breaking Changes" sections
70
+ - At least one section has content (not just placeholders)
71
+ - Version type in changelog matches the manifest
72
+
73
+ **Options:**
74
+
75
+ | Flag | Description |
76
+ | --------------- | -------------------------------------------- |
77
+ | `-v, --verbose` | Show verbose output including passing checks |
78
+
79
+ ### 3. Apply Changelogs
80
+
81
+ Apply changelog drafts to each package's `CHANGELOG.md` file:
82
+
83
+ ```bash
84
+ yarn changelog apply
85
+ ```
86
+
87
+ This command:
88
+
89
+ - Reads all changelog drafts from `.yarn/changelogs/`
90
+ - Groups entries by package name
91
+ - Merges multiple entries for the same package (with deduplication)
92
+ - Prepends new entries to each package's `CHANGELOG.md`
93
+ - Deletes processed draft files
94
+
95
+ **Options:**
96
+
97
+ | Flag | Description |
98
+ | --------------- | ---------------------------------------------- |
99
+ | `-v, --verbose` | Show verbose output |
100
+ | `--dry-run` | Show what would be done without making changes |
101
+
102
+ ## Workflow
103
+
104
+ A typical release workflow using this plugin:
105
+
106
+ ```bash
107
+ # 1. Make your changes and commit them
108
+
109
+ # 2. Bump versions (creates .yarn/versions/*.yml)
110
+ yarn version check --interactive
111
+
112
+ # 3. Generate changelog drafts
113
+ yarn changelog create
114
+
115
+ # 4. Edit the generated drafts in .yarn/changelogs/
116
+ # Fill in the relevant sections with your changes
117
+
118
+ # 5. Validate changelogs
119
+ yarn changelog check
120
+
121
+ # 6. Apply version changes and changelogs
122
+ yarn version apply --all
123
+ yarn changelog apply
124
+
125
+ # 7. Commit and push
126
+ git add -A
127
+ git commit -m "Release"
128
+ ```
129
+
130
+ ## Changelog Draft Format
131
+
132
+ Draft files use a markdown format with conventional changelog sections:
133
+
134
+ ```markdown
135
+ <!-- version-type: minor -->
136
+
137
+ # @scope/package-name
138
+
139
+ ## 💥 Breaking Changes
140
+
141
+ (Only for major releases)
142
+
143
+ ## ✨ Features
144
+
145
+ - Added new feature X
146
+
147
+ ## 🐛 Bug Fixes
148
+
149
+ - Fixed issue with Y
150
+
151
+ ## 📚 Documentation
152
+
153
+ ## ⚡ Performance
154
+
155
+ ## ♻️ Refactoring
156
+
157
+ ## 🧪 Tests
158
+
159
+ ## 📦 Build
160
+
161
+ ## 👷 CI
162
+
163
+ ## ⬆️ Dependencies
164
+
165
+ ## 🔧 Chores
166
+ ```
167
+
168
+ ## Directory Structure
169
+
170
+ ```
171
+ .yarn/
172
+ ├── versions/ # Version manifests (created by yarn version)
173
+ │ └── abc123.yml
174
+ └── changelogs/ # Changelog drafts (created by this plugin)
175
+ ├── @scope-package-a.abc123.md
176
+ └── @scope-package-b.abc123.md
177
+ ```
178
+
179
+ ## License
180
+
181
+ GPL-2.0
@@ -0,0 +1,124 @@
1
+ /* eslint-disable */
2
+ //prettier-ignore
3
+ module.exports = {
4
+ name: "@yarnpkg/plugin-changelog",
5
+ factory: function (require) {
6
+ "use strict";var plugin=(()=>{var z=Object.defineProperty;var le=Object.getOwnPropertyDescriptor;var ge=Object.getOwnPropertyNames;var pe=Object.prototype.hasOwnProperty;var N=(e=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(e,{get:(t,o)=>(typeof require<"u"?require:t)[o]}):e)(function(e){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+e+'" is not supported')});var he=(e,t)=>{for(var o in t)z(e,o,{get:t[o],enumerable:!0})},de=(e,t,o,s)=>{if(t&&typeof t=="object"||typeof t=="function")for(let i of ge(t))!pe.call(e,i)&&i!==o&&z(e,i,{get:()=>t[i],enumerable:!(s=le(t,i))||s.enumerable});return e};var me=e=>de(z({},"__esModule",{value:!0}),e);var $e={};he($e,{default:()=>Oe});var re=N("@yarnpkg/cli"),M=N("@yarnpkg/core"),f=N("@yarnpkg/fslib"),$=N("clipanion");function W(e,t,o){let s=`## [${t}] - ${o}
7
+
8
+ `;for(let i of e.sections)i.isEmpty||(s+=`### ${i.name}
9
+ `,s+=`${i.content.trim()}
10
+
11
+ `);return s}var ne={heading:1,other:2,list:3};function oe(e){let t=e.trim();if(!t)return"other";let o=t.split(`
12
+ `)[0].trim();return/^#{2,}/.test(o)?"heading":/^[-*+]/.test(o)||/^\d+\./.test(o)?"list":"other"}function fe(e){let t=e.trim();return/^[-*+]/.test(t)||/^\d+\./.test(t)}function Y(e){if(e.length===0)return"";let t=e.map(l=>({content:l.trim(),type:oe(l)}));t.sort((l,h)=>ne[l.type]-ne[h.type]);let o=t.filter(l=>l.type!=="list"),s=t.filter(l=>l.type==="list"),i=[];for(let l of o)i.push(l.content);if(s.length>0){let l=[];for(let h of s){let a=h.content.split(`
13
+ `);for(let r of a)r.trim()&&(fe(r)||/^\s+/.test(r))&&l.push(r)}l.length>0&&i.push(l.join(`
14
+ `))}return i.join(`
15
+
16
+ `)}var se={major:3,minor:2,patch:1};function X(e){if(e.length===0)return{packageName:"",versionType:"patch",sections:[],hasPlaceholders:!1};if(e.length===1)return e[0];let{packageName:t}=e[0],o=e.some(a=>a.hasPlaceholders),s=e.reduce((a,r)=>{let c=se[r.versionType]??0,m=se[a]??0;return c>m?r.versionType:a},"patch"),i=new Map,l=[];for(let a of e)for(let r of a.sections){i.has(r.name)||(i.set(r.name,[]),l.push(r.name));let c=r.content.trim();if(!c)continue;let m=i.get(r.name);m.some(p=>p.trim().toLowerCase()===c.toLowerCase())||m.push(c)}let h=l.map(a=>{let r=i.get(a)??[],c=Y(r);return{name:a,content:c?`${c}
17
+ `:"",isEmpty:!c}});return{packageName:t,versionType:s,sections:h,hasPlaceholders:o}}var n={BREAKING_CHANGES:"\u{1F4A5} Breaking Changes",DEPRECATED:"\u{1F5D1}\uFE0F Deprecated",FEATURES:"\u2728 Features",BUG_FIXES:"\u{1F41B} Bug Fixes",DOCUMENTATION:"\u{1F4DA} Documentation",PERFORMANCE:"\u26A1 Performance",REFACTORING:"\u267B\uFE0F Refactoring",TESTS:"\u{1F9EA} Tests",BUILD:"\u{1F4E6} Build",CI:"\u{1F477} CI",DEPENDENCIES:"\u2B06\uFE0F Dependencies",CHORES:"\u{1F527} Chores"};function G(e,t={}){let o=[];return t.expectedVersionType&&e.versionType!==t.expectedVersionType&&o.push(`Version type mismatch: changelog has "${e.versionType}" but manifest expects "${t.expectedVersionType}". Run 'yarn changelog create --force' to regenerate.`),e.versionType==="major"&&!e.sections.some(i=>i.name===n.BREAKING_CHANGES&&!i.isEmpty)&&o.push(`Major release requires filled "${n.BREAKING_CHANGES}" section`),e.sections.filter(i=>!i.isEmpty).length===0&&o.push("At least one section must have content"),o}function J(e,t){let o=[];return e||o.push(`${t}: Missing package name heading. Expected a heading like "# @furystack/package-name" at the start of the file.`),{isValid:o.length===0,errors:o}}function q(e,t){let o=e.versionType!==t,i=G(e,{expectedVersionType:t}).filter(l=>!l.includes("Version type mismatch"));return{shouldRegenerate:o||i.length>0,hasVersionMismatch:o,contentErrors:i}}var ue="patch",Ee="<!-- PLACEHOLDER:",ye=/<!-- version-type: (\w+) -->/,Ce=/^# (.+)$/m,Pe=/^## (.+)$/;function A(e){let t=e.split(`
18
+ `),s=e.match(ye)?.[1]??ue,l=e.match(Ce)?.[1]??"",h=e.includes(Ee),a=[],r=null;for(let c of t){let m=c.match(Pe);m?(r&&a.push(r),r={name:m[1],content:"",isEmpty:!0}):r&&!c.trim().startsWith("<!--")&&(r.content+=`${c}
19
+ `,c.trim()&&(r.isEmpty=!1))}return r&&a.push(r),{packageName:l,versionType:s,sections:a,hasPlaceholders:h}}var I=".yarn/changelogs",F=".yarn/versions";var Q="0.0.0",Z="# Changelog",_=class extends re.BaseCommand{static paths=[["changelog","apply"]];static usage=$.Command.Usage({description:"Apply changelog entries to package CHANGELOG.md files",details:`
20
+ This command:
21
+ - Reads all changelog drafts from \`.yarn/changelogs/\`
22
+ - Groups entries by package name
23
+ - Prepends new entries to each package's CHANGELOG.md
24
+ - Deletes processed draft files
25
+ `,examples:[["Apply changelogs","yarn changelog apply"]]});verbose=$.Option.Boolean("-v,--verbose",!1,{description:"Show verbose output"});dryRun=$.Option.Boolean("--dry-run",!1,{description:"Show what would be done without making changes"});async execute(){let t=await M.Configuration.find(this.context.cwd,this.context.plugins),{project:o}=await M.Project.find(t,this.context.cwd),s=f.ppath.join(o.cwd,I);if(this.dryRun&&this.context.stdout.write(`[DRY RUN] No changes will be made.
26
+
27
+ `),!await f.xfs.existsPromise(s))return this.context.stdout.write(`No .yarn/changelogs directory found. Nothing to apply.
28
+ `),0;let l=(await f.xfs.readdirPromise(s)).filter(p=>p.endsWith(".md"));if(l.length===0)return this.context.stdout.write(`No changelog drafts found. Nothing to apply.
29
+ `),0;let h=[],a=[];for(let p of l){let d=f.ppath.join(s,p),C=await f.xfs.readFilePromise(d,"utf8"),g=A(C),E=J(g.packageName,p);if(!E.isValid){a.push(...E.errors);continue}h.push({path:d,filename:p,packageName:g.packageName,content:C})}if(a.length>0){this.context.stderr.write(`Validation errors found:
30
+ `);for(let p of a)this.context.stderr.write(` \u2717 ${p}
31
+ `);this.context.stderr.write(`
32
+ Invalid drafts were skipped and not deleted.
33
+
34
+ `)}let r=new Map;for(let p of h){let d=r.get(p.packageName)??[];d.push(p),r.set(p.packageName,d)}let c=new Date().toISOString().split("T")[0],m=0;for(let[p,d]of r){let C=o.workspaces.find(y=>y.manifest.raw.name===p),g,E;if(C)g=C.cwd,E=C.manifest.version??Q;else{let y=p.replace(/^@[^/]+\//,"");g=f.ppath.join(o.cwd,`packages/${y}`);let O=f.ppath.join(g,"package.json");await f.xfs.existsPromise(O)?E=JSON.parse(await f.xfs.readFilePromise(O,"utf8")).version??Q:E=Q}if(!await f.xfs.existsPromise(g))throw new Error(`Package directory not found: ${g}
35
+ Package '${p}' has changelog entries but no workspace directory exists.
36
+ This may indicate the package was deleted or uses a non-standard directory structure.`);let R=f.ppath.join(g,"CHANGELOG.md"),T="";await f.xfs.existsPromise(R)&&(T=await f.xfs.readFilePromise(R,"utf8"));let b=d.map(y=>A(y.content)),k=X(b),P=W(k,E,c),x,S=new RegExp(`^${Z}(?:\\r?\\n)+`);if(T){let y=T.match(S);if(y){let O=y[0].length;x=T.slice(0,O)+P+T.slice(O)}else x=`${Z}
37
+
38
+ ${P}${T}`}else x=`${Z}
39
+
40
+ ${P}`;if(this.context.stdout.write(`Applying ${d.length} entry(ies) to ${p}
41
+ `),this.dryRun){if(this.verbose){this.context.stdout.write(` Would write to: ${R}
42
+ `);for(let y of d)this.context.stdout.write(` Would delete: ${y.filename}
43
+ `)}}else{await f.xfs.writeFilePromise(R,x);for(let y of d)await f.xfs.unlinkPromise(y.path),this.verbose&&this.context.stdout.write(` Deleted: ${y.filename}
44
+ `)}m+=d.length}let D=this.dryRun?"Would apply":"Applied";return this.context.stdout.write(`
45
+ ${D} ${m} changelog entry(ies) to ${r.size} package(s).
46
+ `),a.length>0?1:0}};var ae=N("@yarnpkg/cli"),H=N("@yarnpkg/core"),w=N("@yarnpkg/fslib"),U=N("clipanion");function Ne(e){return e==="patch"||e==="minor"||e==="major"}function V(e,t){let o=[],s=e.split(`
47
+ `),i=!1;for(let l of s){let h=l.trim();if(h==="releases:"){i=!0;continue}if(i&&h){let a=h.match(/^["']?([^"':]+)["']?\s*:\s*(patch|minor|major)\s*$/);if(a){let r=a[1],c=a[2];Ne(c)&&o.push({packageName:r,versionType:c})}}}return{id:Re(t),path:t,releases:o}}function ie(e){return e.replace(/\//g,"-")}function Re(e){return(e.split("/").pop()??"").replace(".yml","")}var Te="Updated dependencies",we=`<!--
48
+ FORMATTING GUIDE:
49
+
50
+ ### Detailed Entry (appears first when merging)
51
+
52
+ Use h3 (###) and below for detailed entries with paragraphs, code examples, and lists.
53
+
54
+ ### Simple List Items
55
+
56
+ - Simple changes can be added as list items
57
+ - They are collected together at the bottom of each section
58
+
59
+ TIP: When multiple changelog drafts are merged, heading-based entries
60
+ appear before simple list items within each section.
61
+ -->`,xe={[n.BREAKING_CHANGES]:"Describe breaking changes (BREAKING CHANGE:)",[n.DEPRECATED]:"Describe deprecated features. Double-check if they are annotated with a `@deprecated` jsdoc tag.",[n.FEATURES]:"Describe your shiny new features (feat:)",[n.BUG_FIXES]:"Describe the nasty little bugs that has been eradicated (fix:)",[n.DOCUMENTATION]:"Describe documentation changes (docs:)",[n.PERFORMANCE]:"Describe performance improvements (perf:)",[n.REFACTORING]:"Describe code refactoring (refactor:)",[n.TESTS]:"Describe test changes (test:)",[n.BUILD]:"Describe build system changes (build:)",[n.CI]:"Describe CI configuration changes (ci:)",[n.DEPENDENCIES]:"Describe dependency updates (deps:)",[n.CHORES]:"Describe other changes (chore:)"},De="<!-- MIGRATION REQUIRED: Explain how to migrate from the previous version -->",Se=[n.BREAKING_CHANGES,n.DEPRECATED,n.FEATURES,n.BUG_FIXES,n.DOCUMENTATION,n.PERFORMANCE,n.REFACTORING,n.TESTS,n.BUILD,n.CI,n.DEPENDENCIES,n.CHORES],Ae=[n.DEPRECATED,n.FEATURES,n.BUG_FIXES,n.DOCUMENTATION,n.PERFORMANCE,n.REFACTORING,n.TESTS,n.BUILD,n.CI,n.DEPENDENCIES,n.CHORES],ve=[n.FEATURES,n.BUG_FIXES,n.DOCUMENTATION,n.PERFORMANCE,n.REFACTORING,n.TESTS,n.BUILD,n.CI,n.DEPENDENCIES,n.CHORES];function Ie(e,t=!1){let o=xe[e],s=`## ${e}
62
+ <!-- PLACEHOLDER: ${o} -->`;return t&&(s+=`
63
+ ${De}`),s}function be(e){return(e==="major"?Se:e==="minor"?Ae:ve).map(o=>{let s=o===n.BREAKING_CHANGES;return Ie(o,s)}).join(`
64
+
65
+ `)}function ee(e,t){let o=be(t);return`<!-- version-type: ${t} -->
66
+ # ${e}
67
+
68
+ ${we}
69
+
70
+ ${o}
71
+ `}function L(e,t){return`${ie(e)}.${t}.md`}function te(e,t,o){let s=o||Te;return t==="major"?`<!-- version-type: ${t} -->
72
+ # ${e}
73
+
74
+ ## ${n.BREAKING_CHANGES}
75
+ - ${s}
76
+
77
+ ## ${n.DEPENDENCIES}
78
+ - ${s}
79
+ `:`<!-- version-type: ${t} -->
80
+ # ${e}
81
+
82
+ ## ${n.DEPENDENCIES}
83
+ - ${s}
84
+ `}var j=class extends ae.BaseCommand{static paths=[["changelog","check"]];static usage=U.Command.Usage({description:"Validate changelog entries for all version manifests",details:`
85
+ This command validates that:
86
+ - Every release in \`.yarn/versions/*.yml\` has a changelog file
87
+ - Major releases have filled BREAKING CHANGES sections
88
+ - At least one section (Added/Changed/Fixed) has content
89
+ `,examples:[["Validate changelogs","yarn changelog check"]]});verbose=U.Option.Boolean("-v,--verbose",!1,{description:"Show verbose output"});async execute(){let t=await H.Configuration.find(this.context.cwd,this.context.plugins),{project:o}=await H.Project.find(t,this.context.cwd),s=w.ppath.join(o.cwd,F),i=w.ppath.join(o.cwd,I);if(!await w.xfs.existsPromise(s))return this.context.stdout.write(`No .yarn/versions directory found. Nothing to check.
90
+ `),0;let h=(await w.xfs.readdirPromise(s)).filter(c=>c.endsWith(".yml"));if(h.length===0)return this.context.stdout.write(`No version manifests found. Nothing to check.
91
+ `),0;let a=[],r=0;for(let c of h){let m=w.ppath.join(s,c),D=await w.xfs.readFilePromise(m,"utf8"),p=V(D,m);this.verbose&&this.context.stdout.write(`Checking manifest: ${c}
92
+ `);for(let d of p.releases){let C=L(d.packageName,p.id),g=w.ppath.join(i,C);if(!await w.xfs.existsPromise(g)){a.push(`Missing changelog for ${d.packageName} (manifest: ${p.id}). Run 'yarn changelog create' to generate it.`);continue}let E=await w.xfs.readFilePromise(g,"utf8"),R=A(E),T=G(R,{expectedVersionType:d.versionType});if(T.length>0)for(let b of T)a.push(`${d.packageName} (${C}): ${b}`);else this.verbose&&this.context.stdout.write(` \u2713 ${d.packageName}
93
+ `);r++}}if(a.length>0){this.context.stderr.write(`
94
+ Changelog validation failed:
95
+
96
+ `);for(let c of a)this.context.stderr.write(` \u2717 ${c}
97
+ `);return this.context.stderr.write(`
98
+ Found ${a.length} error(s).
99
+ `),1}return this.context.stdout.write(`
100
+ \u2713 All ${r} changelog(s) are valid.
101
+ `),0}};var ce=N("@yarnpkg/cli"),K=N("@yarnpkg/core"),u=N("@yarnpkg/fslib"),v=N("clipanion");var B=class extends ce.BaseCommand{static paths=[["changelog","create"]];static usage=v.Command.Usage({description:"Generate changelog drafts from version manifests",details:`
102
+ This command reads all version manifests in \`.yarn/versions/*.yml\`
103
+ and generates draft changelog files in \`.yarn/changelogs/\`.
104
+
105
+ Each draft includes sections for Added, Changed, and Fixed entries.
106
+ For major/minor releases, additional sections are included.
107
+
108
+ Existing changelog drafts are not overwritten unless --force is used.
109
+
110
+ Use --dependabot to auto-fill changelogs for dependency updates.
111
+ The --message option can provide a custom message (e.g., PR title).
112
+ `,examples:[["Generate changelog drafts","yarn changelog create"],["Regenerate mismatched/invalid changelogs","yarn changelog create --force"],["Generate for Dependabot PR","yarn changelog create --dependabot"],["Generate with custom message",'yarn changelog create --dependabot -m "Bump lodash from 4.17.20 to 4.17.21"']]});verbose=v.Option.Boolean("-v,--verbose",!1,{description:"Show verbose output"});force=v.Option.Boolean("-f,--force",!1,{description:"Regenerate changelogs with mismatched version types or invalid entries"});dependabot=v.Option.Boolean("--dependabot",!1,{description:"Auto-fill changelog for dependency updates (Dependabot PRs)"});message=v.Option.String("-m,--message",{description:"Custom message for the changelog entry (used with --dependabot)"});async execute(){let t=await K.Configuration.find(this.context.cwd,this.context.plugins),{project:o}=await K.Project.find(t,this.context.cwd),s=u.ppath.join(o.cwd,F),i=u.ppath.join(o.cwd,I);if(await u.xfs.mkdirPromise(i,{recursive:!0}),!await u.xfs.existsPromise(s))return this.context.stdout.write(`No .yarn/versions directory found. Nothing to do.
113
+ `),0;let h=(await u.xfs.readdirPromise(s)).filter(D=>D.endsWith(".yml"));if(h.length===0)return this.context.stdout.write(`No version manifests found. Nothing to do.
114
+ `),0;let a=0,r=0,c=0;for(let D of h){let p=u.ppath.join(s,D),d=await u.xfs.readFilePromise(p,"utf8"),C=V(d,p);this.verbose&&this.context.stdout.write(`Processing manifest: ${D}
115
+ `);for(let g of C.releases){let E=L(g.packageName,C.id),R=u.ppath.join(i,E);if(await u.xfs.existsPromise(R)){let b=await u.xfs.readFilePromise(R,"utf8"),k=A(b),P=q(k,g.versionType);if(this.force&&P.shouldRegenerate){let x=this.dependabot?te(g.packageName,g.versionType,this.message):ee(g.packageName,g.versionType);await u.xfs.writeFilePromise(R,x);let S=[];P.hasVersionMismatch&&S.push(`${k.versionType} \u2192 ${g.versionType}`),P.contentErrors.length>0&&S.push(...P.contentErrors),this.context.stdout.write(` Regenerated: ${E} (${S.join(", ")})
116
+ `),r++;continue}if(this.verbose)if(P.shouldRegenerate){let x=[];P.hasVersionMismatch&&x.push(`version mismatch: ${k.versionType} vs ${g.versionType}`),P.contentErrors.length>0&&x.push(...P.contentErrors.map(S=>S.toLowerCase())),this.context.stdout.write(` Skipping ${g.packageName} (${x.join("; ")}, use --force to regenerate)
117
+ `)}else this.context.stdout.write(` Skipping ${g.packageName} (already exists)
118
+ `);c++;continue}let T=this.dependabot?te(g.packageName,g.versionType,this.message):ee(g.packageName,g.versionType);await u.xfs.writeFilePromise(R,T),this.context.stdout.write(` Created: ${E} (${g.versionType})
119
+ `),a++}}let m=[`Created ${a}`];return r>0&&m.push(`regenerated ${r}`),m.push(`skipped ${c}`),this.context.stdout.write(`
120
+ Done! ${m.join(", ")} changelog draft(s).
121
+ `),0}};var ke={commands:[B,j,_]},Oe=ke;return me($e);})();
122
+ return plugin;
123
+ }
124
+ };
package/package.json ADDED
@@ -0,0 +1,48 @@
1
+ {
2
+ "name": "@furystack/yarn-plugin-changelog",
3
+ "version": "1.0.0",
4
+ "description": "Yarn plugin for managing changelogs from version manifests",
5
+ "license": "GPL-2.0",
6
+ "main": "./src/index.ts",
7
+ "files": [
8
+ "bundles"
9
+ ],
10
+ "publishConfig": {
11
+ "access": "public",
12
+ "main": "./bundles/@yarnpkg/plugin-changelog.js"
13
+ },
14
+ "repository": {
15
+ "type": "git",
16
+ "url": "https://github.com/furystack/furystack.git"
17
+ },
18
+ "keywords": [
19
+ "yarn",
20
+ "yarn-plugin",
21
+ "changelog",
22
+ "version-management",
23
+ "monorepo",
24
+ "furystack"
25
+ ],
26
+ "author": "Gallay Lajos <gallay.lajos@gmail.com>",
27
+ "bugs": {
28
+ "url": "https://github.com/furystack/furystack/issues"
29
+ },
30
+ "homepage": "https://github.com/furystack/furystack/tree/main/packages/yarn-plugin-changelog",
31
+ "scripts": {
32
+ "build": "yarn build:types && yarn build:plugin",
33
+ "build:types": "tsc -b",
34
+ "build:plugin": "mv bundles/@yarnpkg/plugin-changelog.js bundles/@yarnpkg/plugin-changelog.js.bak 2>/dev/null; node ../../node_modules/@yarnpkg/builder/lib/cli.js build plugin && rm -f bundles/@yarnpkg/plugin-changelog.js.bak || (mv bundles/@yarnpkg/plugin-changelog.js.bak bundles/@yarnpkg/plugin-changelog.js 2>/dev/null; exit 1)"
35
+ },
36
+ "dependencies": {
37
+ "@yarnpkg/cli": "^4.12.0",
38
+ "@yarnpkg/core": "^4.5.0",
39
+ "@yarnpkg/fslib": "^3.1.4",
40
+ "clipanion": "^4.0.0-rc.4"
41
+ },
42
+ "devDependencies": {
43
+ "@types/node": "^25.0.10",
44
+ "@yarnpkg/builder": "^4.2.3",
45
+ "typescript": "^5.9.3",
46
+ "vitest": "^4.0.17"
47
+ }
48
+ }