|
48 | 48 | steps: |
49 | 49 | - name: Checkout Repo |
50 | 50 | uses: actions/checkout@v4 |
| 51 | + with: |
| 52 | + fetch-depth: 0 |
51 | 53 | - name: Setup pnpm |
52 | 54 | uses: pnpm/action-setup@v4 |
53 | 55 |
|
|
79 | 81 | git config user.name "github-actions[bot]" |
80 | 82 | git config user.email "41898282+github-actions[bot]@users.noreply.github.com" |
81 | 83 |
|
| 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 | +
|
82 | 136 | - name: Snapshot version bump (in-place, not committed) |
83 | 137 | if: steps.changesets.outputs.has_pending == 'true' |
84 | 138 | run: | |
@@ -107,10 +161,13 @@ jobs: |
107 | 161 | name=$(jq -r '.name' "$pkg_json") |
108 | 162 | version=$(jq -r '.version' "$pkg_json") |
109 | 163 | ref="${name}@${version}" |
| 164 | + safe=$(printf '%s' "$name" | tr '@/' '_') |
| 165 | + notes_file="/tmp/release-notes/${safe}.md" |
110 | 166 | git tag -a "$ref" -m "$ref" |
111 | 167 | 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 |
116 | 173 | done |
0 commit comments