Skip to content

Commit

Permalink
chore: set up multi-branch automated release
Browse files Browse the repository at this point in the history
  • Loading branch information
mweberxyz committed Apr 13, 2024
1 parent ec74bf7 commit c1b2ebf
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 34 deletions.
21 changes: 11 additions & 10 deletions .github/workflows/release-create-pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,20 @@ permissions:
on:
workflow_dispatch:
inputs:
version:
description: 'The version number to release (has priority over release_type)'
type: string
major_branch:
description: Major version branch
type: choice
default: main
options:
- main
- v5.x
release_type:
description: Type of release
type: choice
default: patch
options:
- patch
- minor
- major

jobs:
create-pr:
Expand All @@ -26,11 +29,10 @@ jobs:
contents: write
pull-requests: write

outputs:
version: ${{ steps.bump.outputs.version }}

steps:
- uses: actions/checkout@v4
with:
ref: ${{ inputs.major_branch }}
- uses: actions/setup-node@v4
with:
node-version: '20'
Expand All @@ -41,7 +43,7 @@ jobs:
- name: Change version number and push
id: bump
run: |
npm version ${{ inputs.version || inputs.release_type }} --git-tag-version=false
npm version ${{ inputs.release_type }} --git-tag-version=false
VERSION=`jq -r ".version" package.json`
RELEASE_BRANCH="release/v$VERSION"
git add -u
Expand All @@ -52,6 +54,5 @@ jobs:
uses: actions/github-script@v7
with:
script: |
const defaultBranch = "${{ github.event.repository.default_branch }}"
const versionTag = "v${{ steps.bump.outputs.version }}"
await require('./scripts/release').generatePr({ github, context, defaultBranch, versionTag })
await require('./scripts/release').generatePr({ github, context, versionTag })
16 changes: 6 additions & 10 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ name: Create release
on:
push:
branches:
- main
- main
paths:
- package.json

Expand All @@ -26,12 +26,9 @@ jobs:
const version = require("./package.json").version
const versionTag = `v${version}`
const { data: releases } = await github.rest.repos.listReleases({
owner,
repo
})
const previousReleaseTag = await require('./scripts/release').previousReleaseTag({ github, context, versionTag })
if (versionTag !== releases[0]?.tag_name) {
if (versionTag !== previousReleaseTag) {
return versionTag
}
Expand All @@ -55,18 +52,17 @@ jobs:
- run: npm install -g npm@latest
- run: npm install
- name: Create NPM release
run: npm publish --provenance --access public
run: npm publish --provenance --access public --tag latest
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
- run: node scripts/generate-undici-types-package-json.js
- run: npm publish --provenance
- run: npm publish --provenance --access public --tag latest
working-directory: './types'
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
- name: Create GitHub release
uses: actions/github-script@v7
with:
script: |
const defaultBranch = "${{ github.event.repository.default_branch }}"
const versionTag = "${{ needs.check-release-version.outputs.release-version }}"
await require('./scripts/release').release({ github, context, defaultBranch, versionTag })
await require('./scripts/release').release({ github, context, versionTag })
54 changes: 40 additions & 14 deletions scripts/release.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,37 @@

// Called from .github/workflows

const generateReleaseNotes = async ({ github, owner, repo, versionTag, defaultBranch }) => {
const { data: releases } = await github.rest.repos.listReleases({
owner,
repo
})
// The following two variables should be updated per major version release branch (main, v5.x, etc)
const VERSION_TAG_PREFIX = 'v6.'
const BRANCH = 'main'

const getLatestRelease = async ({ github, owner, repo }) => {
for await (const { data } of github.paginate.iterator(
github.rest.repos.listReleases,
{
owner,
repo
}
)) {
const latestRelease = data.find((r) => r.tag_name.startsWith(VERSION_TAG_PREFIX))

if (latestRelease) {
return latestRelease
}
}

throw new Error(`Could not find latest release of ${VERSION_TAG_PREFIX}x`)
}

const generateReleaseNotes = async ({ github, owner, repo, versionTag }) => {
const previousRelease = await getLatestRelease({ github, owner, repo, versionTag })

const { data: { body } } = await github.rest.repos.generateReleaseNotes({
owner,
repo,
tag_name: versionTag,
target_commitish: defaultBranch,
previous_tag_name: releases[0]?.tag_name
target_commitish: `heads/${BRANCH}`,
previous_tag_name: previousRelease.tag_name
})

const bodyWithoutReleasePr = body.split('\n')
Expand All @@ -23,29 +42,29 @@ const generateReleaseNotes = async ({ github, owner, repo, versionTag, defaultBr
return bodyWithoutReleasePr
}

const generatePr = async ({ github, context, defaultBranch, versionTag }) => {
const generatePr = async ({ github, context, versionTag }) => {
const { owner, repo } = context.repo
const releaseNotes = await generateReleaseNotes({ github, owner, repo, versionTag, defaultBranch })
const releaseNotes = await generateReleaseNotes({ github, owner, repo, versionTag })

await github.rest.pulls.create({
owner,
repo,
head: `release/${versionTag}`,
base: defaultBranch,
base: BRANCH,
title: `[Release] ${versionTag}`,
body: releaseNotes
})
}

const release = async ({ github, context, defaultBranch, versionTag }) => {
const release = async ({ github, context, versionTag }) => {
const { owner, repo } = context.repo
const releaseNotes = await generateReleaseNotes({ github, owner, repo, versionTag, defaultBranch })
const releaseNotes = await generateReleaseNotes({ github, owner, repo, versionTag })

await github.rest.repos.createRelease({
owner,
repo,
tag_name: versionTag,
target_commitish: defaultBranch,
target_commitish: BRANCH,
name: versionTag,
body: releaseNotes,
draft: false,
Expand All @@ -65,7 +84,14 @@ const release = async ({ github, context, defaultBranch, versionTag }) => {
}
}

const previousReleaseTag = async ({ github, context, versionTag }) => {
const { owner, repo } = context.repo
const previousRelease = await getLatestRelease({ github, owner, repo, versionTag })
return previousRelease.tag_name
}

module.exports = {
generatePr,
release
release,
previousReleaseTag
}

0 comments on commit c1b2ebf

Please sign in to comment.