also looking at this
fix(release): one publisher, and a red run when the DMG is missing
#58
3 files
+93
-36
| @@ -41,6 +41,13 @@ async function openMessages(config: ReturnType<typeof loadConfig>, appDir: strin | ||
| 41 | 41 | * key, and the tables runs are recorded in. Both steps are idempotent, so |
| 42 | 42 | * install can always run them. |
| 43 | 43 | */ |
| 44 | const CHANGELOG_HEADING = '# Uplink Changelog' | |
| 45 | ||
| 46 | /** A changelog file without its heading, so two of them can be stacked. */ | |
| 47 | function changelogBody(markdown: string): string { | |
| 48 | return markdown.replace(CHANGELOG_HEADING, '').trim() | |
| 49 | } | |
| 50 | ||
| 44 | 51 | function prepareApp(appDir: string): void { |
| 45 | 52 | const buddy = `${appDir}/buddy` |
| 46 | 53 | if (!existsSync(`${appDir}/.env`)) { |
| @@ -243,20 +250,35 @@ export default defineCommand((cli) => { | ||
| 243 | 250 | url: 'https://github.com/stacksjs/uplink/releases/latest/download/Uplink.dmg', |
| 244 | 251 | }, null, 2)}\n`) |
| 245 | 252 | |
| 253 | // `buddy changelog` rewrites the file with the commits since the last | |
| 254 | // tag and nothing else, so the older entries are carried over by hand. | |
| 255 | // A changelog that forgets every release but the newest is not one. | |
| 256 | const changelogPath = `${appDir}/CHANGELOG.md` | |
| 257 | const kept = changelogBody(await Bun.file(changelogPath).text()) | |
| 258 | step(['./buddy', 'changelog', '--no-interaction']) | |
| 259 | const generated = changelogBody(await Bun.file(changelogPath).text()) | |
| 260 | const sections = [`## v${version}\n`, `${generated}\n`, kept && `${kept}\n`].filter(Boolean) | |
| 261 | await Bun.write(changelogPath, `${CHANGELOG_HEADING}\n\n${sections.join('\n')}`) | |
| 262 | ||
| 246 | 263 | // Committed and pushed here rather than left as a note to whoever is |
| 247 | 264 | // releasing. `gh` cuts the tag from the remote tip, so this has to land |
| 248 | // first or the tagged commit does not contain its own release metadata, | |
| 249 | // and the site keeps advertising the previous version until somebody | |
| 250 | // remembers. Skipped when nothing changed, so re-running a release for | |
| 251 | // the same version is not an error. | |
| 252 | const pending = Bun.spawnSync(['git', 'status', '--porcelain', 'resources/data/release.json'], { cwd: appDir }).stdout.toString().trim() | |
| 265 | // first or the tagged commit does not contain its own release notes or | |
| 266 | // the version the site advertises. Skipped when nothing changed, so | |
| 267 | // re-running a release for the same version is not an error. | |
| 268 | const pending = Bun.spawnSync(['git', 'status', '--porcelain', 'resources/data/release.json', 'CHANGELOG.md'], { cwd: appDir }).stdout.toString().trim() | |
| 253 | 269 | if (pending) { |
| 254 | step(['git', 'add', 'resources/data/release.json']) | |
| 270 | step(['git', 'add', 'resources/data/release.json', 'CHANGELOG.md']) | |
| 255 | 271 | step(['git', 'commit', '-m', `chore: Uplink ${version} is out`]) |
| 256 | 272 | step(['git', 'push']) |
| 257 | 273 | } |
| 258 | 274 | |
| 259 | step(['gh', 'release', 'create', `v${version}`, stable, built, '--title', `Uplink ${version}`, '--notes', `Uplink ${version} for macOS 13 or later. Signed with a Developer ID and notarized by Apple.`, ...(options.draft ? ['--draft'] : [])]) | |
| 275 | // The only thing that writes a release body. The workflow used to create | |
| 276 | // a second release for the same tag with its own generated notes, so | |
| 277 | // which text a reader got came down to which of the two finished last. | |
| 278 | const notesPath = `${appDir}/storage/framework/desktop-dmg/notes.md` | |
| 279 | await Bun.write(notesPath, `Uplink ${version} for macOS 13 or later. Signed with a Developer ID and notarized by Apple.\n\n${generated}\n`) | |
| 280 | ||
| 281 | step(['gh', 'release', 'create', `v${version}`, stable, built, '--title', `Uplink ${version}`, '--notes-file', notesPath, ...(options.draft ? ['--draft'] : [])]) | |
| 260 | 282 | process.exit(0) |
| 261 | 283 | }) |
| 262 | 284 | |