chore: maintain a 'next release' PR

This commit is contained in:
Daniel Roe 2023-04-20 10:40:07 +01:00
parent f550976f74
commit e6cc4aa02a
4 changed files with 128 additions and 10 deletions

35
.github/workflows/changelogensets.yml vendored Normal file
View File

@ -0,0 +1,35 @@
name: Release
on:
push:
branches:
- main
permissions:
pull-requests: write
concurrency:
group: ${{ github.workflow }}-${{ github.event.number || github.sha }}
cancel-in-progress: ${{ github.event_name != 'push' }}
jobs:
update-changelog:
if: github.repository_owner == 'nuxt'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0
- run: corepack enable
- uses: actions/setup-node@v3
with:
node-version: 18
cache: "pnpm"
- name: Install dependencies
run: pnpm install
- run: pnpm jiti ./scripts/update-changelog.ts
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

View File

@ -1,6 +1,8 @@
import { promises as fsp } from 'node:fs'
import { resolve } from 'pathe'
import { globby } from 'globby'
import { execaSync } from 'execa'
import { determineSemverChange, getGitDiff, loadChangelogConfig, parseCommits } from 'changelogen'
export interface Dep {
name: string,
@ -94,3 +96,19 @@ export async function loadWorkspace (dir: string) {
setVersion
}
}
export async function determineBumpType () {
const config = await loadChangelogConfig(process.cwd())
const commits = await getLatestCommits()
const bumpType = determineSemverChange(commits, config)
return bumpType === 'major' ? 'minor' : bumpType
}
export async function getLatestCommits () {
const config = await loadChangelogConfig(process.cwd())
const latestTag = execaSync('git', ['describe', '--tags', '--abbrev=0']).stdout
return parseCommits(await getGitDiff(latestTag), config)
}

View File

@ -1,9 +1,7 @@
import { execSync } from 'node:child_process'
import { $fetch } from 'ofetch'
import { inc } from 'semver'
import { determineSemverChange, getGitDiff, loadChangelogConfig, parseCommits } from 'changelogen'
import { execaSync } from 'execa'
import { loadWorkspace } from './_utils'
import { determineBumpType, loadWorkspace } from './_utils'
async function main () {
const workspace = await loadWorkspace(process.cwd())
@ -16,13 +14,7 @@ async function main () {
const latestNitro = nitroInfo['dist-tags'].latest
nuxtPkg.data.dependencies.nitropack = `npm:nitropack-edge@^${latestNitro}`
const config = await loadChangelogConfig(process.cwd())
const latestTag = execaSync('git', ['describe', '--tags', '--abbrev=0']).stdout
const commits = await getGitDiff(latestTag)
let bumpType = determineSemverChange(parseCommits(commits, config), config)
if (bumpType === 'major') { bumpType = 'minor' } // 🙈
const bumpType = await determineBumpType()
for (const pkg of workspace.packages.filter(p => !p.data.private)) {
const newVersion = inc(pkg.data.version, bumpType || 'patch')

View File

@ -0,0 +1,73 @@
import { execSync } from 'node:child_process'
import { $fetch } from 'ofetch'
import { inc } from 'semver'
import { generateMarkDown, loadChangelogConfig } from 'changelogen'
import { determineBumpType, getLatestCommits, loadWorkspace } from './_utils'
async function main () {
const workspace = await loadWorkspace(process.cwd())
const config = await loadChangelogConfig(process.cwd(), {
})
const commits = await getLatestCommits()
const bumpType = await determineBumpType()
const newVersion = inc(workspace.find('nuxt').data.version, bumpType || 'patch')
const changelog = await generateMarkDown(commits, config)
// Create and push a branch with bumped versions if it has not already been created
const branchExists = execSync(`git ls-remote --heads origin v${newVersion}`).toString().trim().length > 0
if (!branchExists) {
execSync(`git checkout -b v${newVersion}`)
for (const pkg of workspace.packages.filter(p => !p.data.private)) {
workspace.setVersion(pkg.data.name, newVersion!)
}
await workspace.save()
execSync(`git commit -am v${newVersion}`)
execSync(`git push -u origin v${newVersion}`)
}
// Get the current PR for this release, if it exists
const [currentPR] = await $fetch(`https://api.github.com/repos/nuxt/nuxt/pulls?head=nuxt:v${newVersion}`)
const releaseNotes = [
currentPR?.body.replace(/## 👉 Changelog[\s\S]*$/, '') || `> ${newVersion} is the next ${bumpType} release.\n>\n> **Timetable**: to be announced.`,
'## 👉 Changelog',
changelog.replace(/^## v.*?\n/, '').replace('...main', `...v${newVersion}`)
].join('\n')
// Create a PR with release notes if none exists
if (!currentPR) {
return await $fetch('https://api.github.com/repos/nuxt/nuxt/pulls', {
method: 'POST',
headers: {
Authorization: `token ${process.env.GITHUB_TOKEN}`
},
body: {
title: `v${newVersion}`,
head: `v${newVersion}`,
base: 'main',
body: releaseNotes,
draft: true
}
})
}
// Update release notes if the pull request does exist
await $fetch(`https://api.github.com/repos/nuxt/nuxt/pulls/${currentPR.number}`, {
method: 'PATCH',
headers: {
Authorization: `token ${process.env.GITHUB_TOKEN}`
},
body: {
body: releaseNotes
}
})
}
main().catch((err) => {
console.error(err)
process.exit(1)
})