mnswpr/scripts/release.js
Ayo 3b17a596c6
Some checks are pending
Checks / lint (push) Waiting to run
Checks / test (push) Waiting to run
Checks / content (push) Waiting to run
feat: use app version instead of packate
2026-07-18 21:20:57 +02:00

71 lines
2.4 KiB
JavaScript

/**
* Release: sync the `release` branch to `main` and push the tags.
*
* Run via `pnpm release`, which is `bumpp && node scripts/release.js` — bumpp
* bumps package.json, commits, and tags first, so by the time this runs `main`
* already carries the release commit.
*
* Netlify builds mnswpr.com from the `release` branch on the `gh` remote, so the
* force-push below IS the deploy. Everything before it is a guard against
* shipping a tree you didn't mean to ship.
*
* Originally forked from https://github.com/elk-zone/elk/blob/main/scripts/release.ts
*/
import { simpleGit } from 'simple-git'
// Netlify watches gh/release; the others just mirror tags.
const DEPLOY_REMOTE = 'gh'
const TAG_REMOTES = ['origin', 'gh', 'sh']
const git = simpleGit()
const fail = (message) => {
console.error(`\n${message}`)
process.exit(1)
}
const status = await git.status()
if (status.current !== 'main')
fail(`Release must run from main — you are on "${status.current}".`)
if (!status.isClean())
fail('Working tree is dirty. Commit or stash before releasing.')
const hash = await git.revparse(['main'])
const { latest } = await git.tags()
console.log(`Releasing ${latest} (main @ ${hash.slice(0, 8)})`)
// A leftover local `release` branch from an interrupted run would make the
// checkout below fail, so drop it before recreating it from the remote.
const branches = await git.branchLocal()
if (branches.all.includes('release')) {
console.log('Removing a stale local release branch')
await git.branch(['-D', 'release'])
}
console.log(`Fetching ${DEPLOY_REMOTE}`)
await git.fetch(DEPLOY_REMOTE)
try {
console.log('Checking out release')
await git.checkout(['-b', 'release', '--track', `${DEPLOY_REMOTE}/release`])
console.log(`Resetting release to main (${hash.slice(0, 8)})`)
await git.reset(['--hard', hash])
console.log(`Pushing release to ${DEPLOY_REMOTE} — this triggers the Netlify deploy`)
await git.push([DEPLOY_REMOTE, 'release', '--force'])
} finally {
// Never strand the user on the release branch, even if a step above threw.
await git.checkout('main')
const after = await git.branchLocal()
if (after.all.includes('release')) await git.branch(['-D', 'release'])
}
for (const remote of TAG_REMOTES) {
console.log(`Pushing tags to ${remote}`)
await git.push([remote, '--tags'])
}
console.log(`\n✓ Released ${latest} — Netlify is building from ${DEPLOY_REMOTE}/release`)