Skip to content

Commit 02d0e3d

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

2 files changed

Lines changed: 106 additions & 5 deletions

File tree

.github/workflows/publish.yml

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
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: Install modules
27+
run: yarn install
28+
- name: Create NPM release
29+
run: npm publish --access public
30+
env:
31+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
32+
- name: Create GitHub release
33+
uses: actions/github-script@v8
34+
with:
35+
script: |
36+
const { owner, repo } = context.repo
37+
38+
const { data: releases } = await github.rest.repos.listReleases({
39+
owner,
40+
repo
41+
})
42+
43+
const defaultBranch = context.ref.replace('refs/heads/', '')
44+
45+
const commitMessage = context.payload.head_commit.message
46+
47+
const packageMatch = commitMessage.match(/^release\(([^)]+)\):/)
48+
if (!packageMatch) {
49+
throw new Error('Missing package name. Expected format: "release(package-name):"')
50+
}
51+
const packageName = packageMatch[1]
52+
53+
const version = require(`./packages/${packageName}/package.json`).version
54+
const versionTag = `${packageName}-v${version}`
55+
56+
let releaseNotes = ''
57+
if (releases.length === 0) {
58+
releaseNotes = 'First release!'
59+
} else {
60+
// Get range of commits using the API (from the previous release to the current HEAD)
61+
const { data: comparison } = await github.rest.repos.compareCommits({
62+
owner,
63+
repo,
64+
base: releases[0].tag_name,
65+
head: context.sha
66+
})
67+
68+
const features = []
69+
const fixes = []
70+
const breaking =[]
71+
72+
// Split commits by standard Conventional Commits
73+
for (const { commit, sha } of comparison.commits) {
74+
const firstLine = commit.message.split('\n')[0].trim()
75+
const shortSha = sha.substring(0, 7)
76+
const entry = `- ${firstLine} (${shortSha})`
77+
78+
// Breaking Changes "!" before the colon, e.g. "feat!:"
79+
if (/^[a-zA-Z]+(?:\([^)]+\))?!:/.test(firstLine)) {
80+
breaking.push(entry)
81+
}
82+
// Features with prefix "feat:" or "feat(scope):"
83+
else if (/^feat(?:\([^)]+\))?:/.test(firstLine)) {
84+
features.push(entry)
85+
}
86+
// Bug Fixes with prefix "fix:" or "fix(scope):"
87+
else if (/^fix(?:\([^)]+\))?:/.test(firstLine)) {
88+
fixes.push(entry)
89+
}
90+
}
91+
92+
if (breaking.length > 0) releaseNotes += '### Breaking Changes\n' + breaking.join('\n') + '\n\n'
93+
if (features.length > 0) releaseNotes += '### Features\n' + features.join('\n') + '\n\n'
94+
if (fixes.length > 0) releaseNotes += '### Bug Fixes\n' + fixes.join('\n') + '\n\n'
95+
}
96+
97+
await github.rest.repos.createRelease({
98+
owner,
99+
repo,
100+
tag_name: versionTag,
101+
target_commitish: defaultBranch,
102+
name: versionTag,
103+
body: releaseNotes.trim()
104+
})
105+
106+
console.log(`Release ${versionTag} created`)

.npmrc

Lines changed: 0 additions & 5 deletions
This file was deleted.

0 commit comments

Comments
 (0)