Skip to content

Commit

Permalink
chore: maintain a 'next release' PR
Browse files Browse the repository at this point in the history
  • Loading branch information
danielroe committed Apr 20, 2023
1 parent f550976 commit e6cc4aa
Show file tree
Hide file tree
Showing 4 changed files with 128 additions and 10 deletions.
35 changes: 35 additions & 0 deletions .github/workflows/changelogensets.yml
Original file line number Diff line number Diff line change
@@ -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 }}
18 changes: 18 additions & 0 deletions scripts/_utils.ts
Original file line number Diff line number Diff line change
@@ -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,
Expand Down Expand Up @@ -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)
}
12 changes: 2 additions & 10 deletions scripts/bump-edge.ts
Original file line number Diff line number Diff line change
@@ -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())
Expand All @@ -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')
Expand Down
73 changes: 73 additions & 0 deletions scripts/update-changelog.ts
Original file line number Diff line number Diff line change
@@ -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)
})

0 comments on commit e6cc4aa

Please sign in to comment.