Skip to content

Commit e87cd84

Browse files
committed
feat: Add GitHub Actions workflow for automated package release
- Introduced a new GitHub Actions workflow to automate the release process for the @jsonbored/opennextjs-cli package. - The workflow builds and tests the package, verifies version consistency, generates a changelog using git-cliff, and publishes the package to npm. - Configured OIDC for secure npm authentication without requiring an NPM_TOKEN. - Updated package.json to reflect the new package name and added publishConfig for public access. This setup streamlines the release process, ensuring consistency and reducing manual effort.
1 parent c0b6a8a commit e87cd84

2 files changed

Lines changed: 159 additions & 1 deletion

File tree

.github/workflows/release.yml

Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
# Package Release Workflow
2+
#
3+
# Automatically releases the opennextjs-cli package to npm when a version tag
4+
# is pushed. Uses OIDC for npm authentication (no NPM_TOKEN secret required).
5+
#
6+
# **What it does:**
7+
# 1. Builds and tests the package
8+
# 2. Extracts version from tag (e.g., v1.0.0 → 1.0.0)
9+
# 3. Verifies package.json version matches tag version
10+
# 4. Generates changelog automatically using git-cliff
11+
# 5. Publishes to npm via OIDC
12+
# 6. Creates GitHub Release with changelog notes
13+
#
14+
# **Trigger:**
15+
# Push a version tag:
16+
# ```bash
17+
# git tag v1.0.0
18+
# git push origin main --tags
19+
# ```
20+
#
21+
# **Prerequisites:**
22+
# - package.json version must match tag version (e.g., 1.0.0)
23+
# - npm package must have GitHub Actions configured as trusted publisher
24+
# (one-time setup on npmjs.com → Account Settings → Access Tokens → Automation)
25+
#
26+
# **OIDC Setup:**
27+
# - No NPM_TOKEN secret required
28+
# - Uses GitHub OIDC for automatic authentication
29+
# - More secure than token-based authentication
30+
# - Automatic token rotation
31+
name: Release
32+
33+
on:
34+
push:
35+
tags:
36+
- 'v*.*.*' # Matches v1.2.3
37+
38+
jobs:
39+
release:
40+
runs-on: ubuntu-latest
41+
timeout-minutes: 20
42+
43+
permissions:
44+
contents: write # Required to create GitHub releases
45+
id-token: write # Required for npm publish (OIDC)
46+
47+
steps:
48+
- name: Checkout repository
49+
uses: actions/checkout@v6
50+
with:
51+
fetch-depth: 0 # Full history for changelog generation
52+
53+
- name: Setup pnpm
54+
uses: pnpm/action-setup@v4
55+
with:
56+
version: 8
57+
58+
- name: Setup Node.js
59+
uses: actions/setup-node@v4
60+
with:
61+
node-version: '22'
62+
registry-url: 'https://registry.npmjs.org'
63+
cache: 'pnpm'
64+
65+
- name: Install dependencies
66+
run: pnpm install --frozen-lockfile
67+
68+
- name: Build
69+
working-directory: packages/opennextjs-cli
70+
run: pnpm build
71+
72+
- name: Extract version from tag
73+
id: version
74+
run: |
75+
# Extract version from tag (e.g., v1.0.0 → 1.0.0)
76+
TAG_NAME="${{ github.ref_name }}"
77+
VERSION="${TAG_NAME#v}"
78+
79+
echo "VERSION=$VERSION" >> $GITHUB_OUTPUT
80+
echo "Tag version: $VERSION"
81+
82+
- name: Verify package.json version matches tag
83+
working-directory: packages/opennextjs-cli
84+
run: |
85+
PACKAGE_VERSION=$(node -p "require('./package.json').version")
86+
TAG_VERSION="${{ steps.version.outputs.VERSION }}"
87+
if [ "$PACKAGE_VERSION" != "$TAG_VERSION" ]; then
88+
echo "❌ Version mismatch: package.json ($PACKAGE_VERSION) != tag ($TAG_VERSION)" >&2
89+
exit 1
90+
fi
91+
echo "✅ Version match: $PACKAGE_VERSION"
92+
93+
- name: Check if git-cliff is installed
94+
id: git-cliff-check
95+
run: |
96+
if command -v git-cliff &> /dev/null; then
97+
echo "installed=true" >> $GITHUB_OUTPUT
98+
else
99+
echo "installed=false" >> $GITHUB_OUTPUT
100+
fi
101+
102+
- name: Install git-cliff (if needed)
103+
if: steps.git-cliff-check.outputs.installed == 'false'
104+
run: |
105+
# Install git-cliff on Ubuntu
106+
sudo apt-get update && sudo apt-get install -y git-cliff || \
107+
echo "⚠️ git-cliff installation failed, will skip changelog generation" >&2
108+
109+
- name: Generate changelog
110+
env:
111+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
112+
run: |
113+
set -e
114+
115+
TAG_VERSION="${{ steps.version.outputs.VERSION }}"
116+
117+
# Generate changelog with git-cliff (writes to root CHANGELOG.md)
118+
git-cliff \
119+
--config cliff.toml \
120+
--tag "v$TAG_VERSION" \
121+
--verbose || \
122+
echo "⚠️ Changelog generation failed, will continue without it" >&2
123+
124+
# Extract changelog section for this version
125+
if [ -f CHANGELOG.md ]; then
126+
# Extract the section for this version
127+
awk "/^## \\[$TAG_VERSION\\]/,/^## \\[/ {if (/^## \\[/ && !/^## \\[$TAG_VERSION\\]/) exit; print}" CHANGELOG.md > /tmp/changelog-section.md || \
128+
echo "## [$TAG_VERSION] - $(date +%Y-%m-%d)" > /tmp/changelog-section.md
129+
else
130+
echo "## [$TAG_VERSION] - $(date +%Y-%m-%d)" > /tmp/changelog-section.md
131+
echo "" >> /tmp/changelog-section.md
132+
echo "Release $TAG_VERSION" >> /tmp/changelog-section.md
133+
fi
134+
135+
echo "CHANGELOG_SECTION<<EOF" >> $GITHUB_ENV
136+
cat /tmp/changelog-section.md >> $GITHUB_ENV
137+
echo "EOF" >> $GITHUB_ENV
138+
139+
- name: Publish to npm
140+
working-directory: packages/opennextjs-cli
141+
run: |
142+
npm publish --access public
143+
echo "✅ Published @jsonbored/opennextjs-cli@${{ steps.version.outputs.VERSION }} to npm"
144+
145+
- name: Create GitHub Release
146+
uses: softprops/action-gh-release@v2
147+
with:
148+
tag_name: ${{ github.ref_name }}
149+
name: Release ${{ steps.version.outputs.VERSION }}
150+
body: |
151+
${{ env.CHANGELOG_SECTION }}
152+
draft: false
153+
prerelease: false
154+
env:
155+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

packages/opennextjs-cli/package.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"name": "opennextjs-cli",
2+
"name": "@jsonbored/opennextjs-cli",
33
"version": "0.1.0",
44
"description": "Interactive CLI/TUI tool for setting up and configuring OpenNext.js projects for Cloudflare Workers",
55
"type": "module",
@@ -11,6 +11,9 @@
1111
"files": [
1212
"dist"
1313
],
14+
"publishConfig": {
15+
"access": "public"
16+
},
1417
"scripts": {
1518
"build": "tsc",
1619
"dev": "tsx watch src/index.ts",

0 commit comments

Comments
 (0)