Skip to content

Commit a946cea

Browse files
committed
chore(shell-bson-parser): add publish release workflow
1 parent 7d91f50 commit a946cea

1 file changed

Lines changed: 104 additions & 0 deletions

File tree

.github/workflows/publish.yml

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
name: Publish Release
2+
3+
on:
4+
push:
5+
branches:
6+
- esm
7+
8+
permissions:
9+
contents: read
10+
11+
jobs:
12+
publish_package:
13+
if: startsWith(github.event.head_commit.message, 'release(')
14+
runs-on: ubuntu-latest
15+
permissions:
16+
contents: write
17+
id-token: write
18+
environment: release
19+
steps:
20+
- uses: actions/checkout@v6
21+
- name: Install Node
22+
uses: actions/setup-node@v6
23+
with:
24+
node-version: 24
25+
registry-url: 'https://registry.npmjs.org'
26+
- name: Create NPM release
27+
run: npm publish --access public
28+
env:
29+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
30+
- name: Create GitHub release
31+
uses: actions/github-script@v8
32+
with:
33+
script: |
34+
const { owner, repo } = context.repo
35+
36+
const { data: releases } = await github.rest.repos.listReleases({
37+
owner,
38+
repo
39+
})
40+
41+
const defaultBranch = context.ref.replace('refs/heads/', '')
42+
43+
const commitMessage = context.payload.head_commit.message
44+
45+
const packageMatch = commitMessage.match(/^release\(([^)]+)\):/)
46+
if (!packageMatch) {
47+
throw new Error('Missing package name. Expected format: "release(package-name):"')
48+
}
49+
const packageName = packageMatch[1]
50+
51+
const version = require(`./packages/${packageName}/package.json`).version
52+
const versionTag = `${packageName}-v${version}`
53+
54+
let releaseNotes = ''
55+
if (releases.length === 0) {
56+
releaseNotes = 'First release!'
57+
} else {
58+
// Get range of commits using the API (from the previous release to the current HEAD)
59+
const { data: comparison } = await github.rest.repos.compareCommits({
60+
owner,
61+
repo,
62+
base: releases[0].tag_name,
63+
head: context.sha
64+
})
65+
66+
const features = []
67+
const fixes = []
68+
const breaking =[]
69+
70+
// Split commits by standard Conventional Commits
71+
for (const { commit, sha } of comparison.commits) {
72+
const firstLine = commit.message.split('\n')[0].trim()
73+
const shortSha = sha.substring(0, 7)
74+
const entry = `- ${firstLine} (${shortSha})`
75+
76+
// Breaking Changes "!" before the colon, e.g. "feat!:"
77+
if (/^[a-zA-Z]+(?:\([^)]+\))?!:/.test(firstLine)) {
78+
breaking.push(entry)
79+
}
80+
// Features with prefix "feat:" or "feat(scope):"
81+
else if (/^feat(?:\([^)]+\))?:/.test(firstLine)) {
82+
features.push(entry)
83+
}
84+
// Bug Fixes with prefix "fix:" or "fix(scope):"
85+
else if (/^fix(?:\([^)]+\))?:/.test(firstLine)) {
86+
fixes.push(entry)
87+
}
88+
}
89+
90+
if (breaking.length > 0) releaseNotes += '### Breaking Changes\n' + breaking.join('\n') + '\n\n'
91+
if (features.length > 0) releaseNotes += '### Features\n' + features.join('\n') + '\n\n'
92+
if (fixes.length > 0) releaseNotes += '### Bug Fixes\n' + fixes.join('\n') + '\n\n'
93+
}
94+
95+
await github.rest.repos.createRelease({
96+
owner,
97+
repo,
98+
tag_name: versionTag,
99+
target_commitish: defaultBranch,
100+
name: versionTag,
101+
body: releaseNotes.trim()
102+
})
103+
104+
console.log(`Release ${versionTag} created`)

0 commit comments

Comments
 (0)