Skip to content

Commit fea4919

Browse files
committed
ci: match prerelease notes to release job format [skip ci]
Build release bodies from pending changesets using @changesets/cli's changelog formatter + commit SHA lookup so prereleases get the same "### Type Changes" + "- sha: summary" shape as stable releases.
1 parent e557e11 commit fea4919

1 file changed

Lines changed: 61 additions & 4 deletions

File tree

.github/workflows/release.yml

Lines changed: 61 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ jobs:
4848
steps:
4949
- name: Checkout Repo
5050
uses: actions/checkout@v4
51+
with:
52+
fetch-depth: 0
5153
- name: Setup pnpm
5254
uses: pnpm/action-setup@v4
5355

@@ -79,6 +81,58 @@ jobs:
7981
git config user.name "github-actions[bot]"
8082
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
8183
84+
- name: Build release notes from pending changesets
85+
if: steps.changesets.outputs.has_pending == 'true'
86+
shell: bash
87+
run: |
88+
mkdir -p /tmp/release-notes
89+
node - <<'NODE'
90+
(async () => {
91+
const fs = require('fs');
92+
const readChangesets = require('@changesets/read').default;
93+
const git = require('@changesets/git');
94+
const { getReleaseLine } = require('@changesets/cli/changelog').default;
95+
96+
const cwd = process.cwd();
97+
const changesets = await readChangesets(cwd);
98+
if (changesets.length === 0) return;
99+
100+
const paths = changesets.map(c => `.changeset/${c.id}.md`);
101+
const shaMap = await git.getCommitsThatAddFiles(paths, { cwd, short: true });
102+
for (const cs of changesets) {
103+
cs.commit = shaMap.get(`.changeset/${cs.id}.md`) || undefined;
104+
}
105+
106+
const byPkg = new Map();
107+
for (const cs of changesets) {
108+
for (const release of cs.releases) {
109+
if (release.type === 'none') continue;
110+
let groups = byPkg.get(release.name);
111+
if (!groups) {
112+
groups = { major: [], minor: [], patch: [] };
113+
byPkg.set(release.name, groups);
114+
}
115+
groups[release.type].push({ changeset: cs, type: release.type });
116+
}
117+
}
118+
119+
const labels = { major: 'Major Changes', minor: 'Minor Changes', patch: 'Patch Changes' };
120+
for (const [name, groups] of byPkg) {
121+
const parts = [];
122+
for (const t of ['major', 'minor', 'patch']) {
123+
if (groups[t].length === 0) continue;
124+
parts.push(`### ${labels[t]}`, '');
125+
for (const { changeset, type } of groups[t]) {
126+
parts.push(await getReleaseLine(changeset, type));
127+
}
128+
parts.push('');
129+
}
130+
const safe = name.replace(/[@/]/g, '_');
131+
fs.writeFileSync(`/tmp/release-notes/${safe}.md`, parts.join('\n'));
132+
}
133+
})().catch(err => { console.error(err); process.exit(1); });
134+
NODE
135+
82136
- name: Snapshot version bump (in-place, not committed)
83137
if: steps.changesets.outputs.has_pending == 'true'
84138
run: |
@@ -107,10 +161,13 @@ jobs:
107161
name=$(jq -r '.name' "$pkg_json")
108162
version=$(jq -r '.version' "$pkg_json")
109163
ref="${name}@${version}"
164+
safe=$(printf '%s' "$name" | tr '@/' '_')
165+
notes_file="/tmp/release-notes/${safe}.md"
110166
git tag -a "$ref" -m "$ref"
111167
git push origin "refs/tags/$ref"
112-
gh release create "$ref" \
113-
--prerelease \
114-
--title "$ref" \
115-
--generate-notes
168+
if [ -s "$notes_file" ]; then
169+
gh release create "$ref" --prerelease --title "$ref" --notes-file "$notes_file"
170+
else
171+
gh release create "$ref" --prerelease --title "$ref" --generate-notes
172+
fi
116173
done

0 commit comments

Comments
 (0)