Skip to content

Commit 4bb954d

Browse files
committed
chore: setup 5.x auto release
1 parent fb98306 commit 4bb954d

File tree

3 files changed

+165
-26
lines changed

3 files changed

+165
-26
lines changed

.github/workflows/publish-undici-types.yml

-26
This file was deleted.

.github/workflows/release.yml

+68
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
name: Create release
2+
3+
on:
4+
push:
5+
branches:
6+
- v5.x
7+
paths:
8+
- package.json
9+
10+
permissions:
11+
contents: read
12+
13+
jobs:
14+
check-release-version:
15+
runs-on: ubuntu-latest
16+
outputs:
17+
release-version: ${{ steps.set-release-version.outputs.result }}
18+
steps:
19+
- uses: actions/checkout@v4
20+
- uses: actions/github-script@v7
21+
id: set-release-version
22+
with:
23+
result-encoding: string
24+
script: |
25+
const { owner, repo } = context.repo
26+
const version = require("./package.json").version
27+
const versionTag = `v${version}`
28+
29+
const previousReleaseTag = await require('./scripts/release').previousReleaseTag({ github, context, versionTag })
30+
31+
if (versionTag !== previousReleaseTag) {
32+
return versionTag
33+
}
34+
35+
release:
36+
runs-on: ubuntu-latest
37+
needs: check-release-version
38+
if: ${{ startsWith(needs.check-release-version.outputs.release-version, 'v') }}
39+
40+
permissions:
41+
contents: write
42+
id-token: write
43+
44+
environment: release
45+
46+
steps:
47+
- uses: actions/checkout@v4
48+
- uses: actions/setup-node@v4
49+
with:
50+
node-version: '20'
51+
registry-url: 'https://registry.npmjs.org'
52+
- run: npm install -g npm@latest
53+
- run: npm install
54+
- name: Create NPM release
55+
run: npm publish --provenance --access public --tag five
56+
env:
57+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
58+
- run: node scripts/generate-undici-types-package-json.js
59+
- run: npm publish --provenance --access public --tag five
60+
working-directory: './types'
61+
env:
62+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
63+
- name: Create GitHub release
64+
uses: actions/github-script@v7
65+
with:
66+
script: |
67+
const versionTag = "${{ needs.check-release-version.outputs.release-version }}"
68+
await require('./scripts/release').release({ github, context, versionTag })

scripts/release.js

+97
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
'use strict'
2+
3+
// Called from .github/workflows
4+
5+
// The following two variables should be updated per major version release branch (main, v5.x, etc)
6+
const VERSION_TAG_PREFIX = 'v5.'
7+
const BRANCH = 'v5.x'
8+
9+
const getLatestRelease = async ({ github, owner, repo }) => {
10+
for await (const { data } of github.paginate.iterator(
11+
github.rest.repos.listReleases,
12+
{
13+
owner,
14+
repo
15+
}
16+
)) {
17+
const latestRelease = data.find((r) => r.tag_name.startsWith(VERSION_TAG_PREFIX))
18+
19+
if (latestRelease) {
20+
return latestRelease
21+
}
22+
}
23+
24+
throw new Error(`Could not find latest release of ${VERSION_TAG_PREFIX}x`)
25+
}
26+
27+
const generateReleaseNotes = async ({ github, owner, repo, versionTag }) => {
28+
const previousRelease = await getLatestRelease({ github, owner, repo, versionTag })
29+
30+
const { data: { body } } = await github.rest.repos.generateReleaseNotes({
31+
owner,
32+
repo,
33+
tag_name: versionTag,
34+
target_commitish: `heads/${BRANCH}`,
35+
previous_tag_name: previousRelease.tag_name
36+
})
37+
38+
const bodyWithoutReleasePr = body.split('\n')
39+
.filter((line) => !line.includes('[Release] v'))
40+
.join('\n')
41+
42+
return bodyWithoutReleasePr
43+
}
44+
45+
const generatePr = async ({ github, context, versionTag }) => {
46+
const { owner, repo } = context.repo
47+
const releaseNotes = await generateReleaseNotes({ github, owner, repo, versionTag })
48+
49+
await github.rest.pulls.create({
50+
owner,
51+
repo,
52+
head: `release/${versionTag}`,
53+
base: BRANCH,
54+
title: `[Release] ${versionTag}`,
55+
body: releaseNotes
56+
})
57+
}
58+
59+
const release = async ({ github, context, versionTag }) => {
60+
const { owner, repo } = context.repo
61+
const releaseNotes = await generateReleaseNotes({ github, owner, repo, versionTag })
62+
63+
await github.rest.repos.createRelease({
64+
owner,
65+
repo,
66+
tag_name: versionTag,
67+
target_commitish: BRANCH,
68+
name: versionTag,
69+
body: releaseNotes,
70+
draft: false,
71+
prerelease: false,
72+
generate_release_notes: false
73+
})
74+
75+
try {
76+
await github.rest.git.deleteRef({
77+
owner,
78+
repo,
79+
ref: `heads/release/${versionTag}`
80+
})
81+
} catch (err) {
82+
console.log("Couldn't delete release PR ref")
83+
console.log(err)
84+
}
85+
}
86+
87+
const previousReleaseTag = async ({ github, context, versionTag }) => {
88+
const { owner, repo } = context.repo
89+
const previousRelease = await getLatestRelease({ github, owner, repo, versionTag })
90+
return previousRelease.tag_name
91+
}
92+
93+
module.exports = {
94+
release,
95+
previousReleaseTag,
96+
generatePr
97+
}

0 commit comments

Comments
 (0)