Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: setup 5.x auto release #3111

Draft
wants to merge 1 commit into
base: v5.x
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
26 changes: 0 additions & 26 deletions .github/workflows/publish-undici-types.yml

This file was deleted.

68 changes: 68 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
name: Create release

on:
push:
branches:
- v5.x
paths:
- package.json

permissions:
contents: read

jobs:
check-release-version:
runs-on: ubuntu-latest
outputs:
release-version: ${{ steps.set-release-version.outputs.result }}
steps:
- uses: actions/checkout@v4
- uses: actions/github-script@v7
id: set-release-version
with:
result-encoding: string
script: |
const { owner, repo } = context.repo
const version = require("./package.json").version
const versionTag = `v${version}`

const previousReleaseTag = await require('./scripts/release').previousReleaseTag({ github, context, versionTag })

if (versionTag !== previousReleaseTag) {
return versionTag
}

release:
runs-on: ubuntu-latest
needs: check-release-version
if: ${{ startsWith(needs.check-release-version.outputs.release-version, 'v') }}

permissions:
contents: write
id-token: write

environment: release

steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
registry-url: 'https://registry.npmjs.org'
- run: npm install -g npm@latest
- run: npm install
- name: Create NPM release
run: npm publish --provenance --access public --tag five
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
- run: node scripts/generate-undici-types-package-json.js
- run: npm publish --provenance --access public --tag five
working-directory: './types'
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
- name: Create GitHub release
uses: actions/github-script@v7
with:
script: |
const versionTag = "${{ needs.check-release-version.outputs.release-version }}"
await require('./scripts/release').release({ github, context, versionTag })
97 changes: 97 additions & 0 deletions scripts/release.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
'use strict'

// Called from .github/workflows

// The following two variables should be updated per major version release branch (main, v5.x, etc)
const VERSION_TAG_PREFIX = 'v5.'
const BRANCH = 'v5.x'

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: `heads/${BRANCH}`,
previous_tag_name: previousRelease.tag_name
})

const bodyWithoutReleasePr = body.split('\n')
.filter((line) => !line.includes('[Release] v'))
.join('\n')

return bodyWithoutReleasePr
}

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

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

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

await github.rest.repos.createRelease({
owner,
repo,
tag_name: versionTag,
target_commitish: BRANCH,
name: versionTag,
body: releaseNotes,
draft: false,
prerelease: false,
generate_release_notes: false
})

try {
await github.rest.git.deleteRef({
owner,
repo,
ref: `heads/release/${versionTag}`
})
} catch (err) {
console.log("Couldn't delete release PR ref")
console.log(err)
}
}

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 = {
release,
previousReleaseTag,
generatePr
}