Skip to content

Commit 8dc4b2c

Browse files
authored
feat: add release-on-merge workflow for protected branches (#91)
1 parent 79292d7 commit 8dc4b2c

3 files changed

Lines changed: 115 additions & 36 deletions

File tree

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
name: Release on Merge
2+
3+
on:
4+
push:
5+
branches: [main]
6+
paths:
7+
# Triggers on version bump; actual release check happens in check-release job
8+
- 'package.json'
9+
10+
jobs:
11+
check-release:
12+
runs-on: ubuntu-latest
13+
outputs:
14+
should_release: ${{ steps.check.outputs.should_release }}
15+
version: ${{ steps.check.outputs.version }}
16+
steps:
17+
- uses: actions/checkout@v6
18+
with:
19+
fetch-depth: 0
20+
21+
- name: Check if release needed
22+
id: check
23+
run: |
24+
VERSION=$(node -p "require('./package.json').version")
25+
TAG="v$VERSION"
26+
if git rev-parse "$TAG" >/dev/null 2>&1; then
27+
echo "Tag $TAG already exists, skipping release"
28+
echo "should_release=false" >> $GITHUB_OUTPUT
29+
else
30+
echo "Tag $TAG does not exist, will create release"
31+
echo "should_release=true" >> $GITHUB_OUTPUT
32+
echo "version=$VERSION" >> $GITHUB_OUTPUT
33+
fi
34+
35+
create-release:
36+
needs: check-release
37+
if: needs.check-release.outputs.should_release == 'true'
38+
runs-on: ubuntu-latest
39+
permissions:
40+
contents: write
41+
steps:
42+
- uses: actions/checkout@v6
43+
44+
- name: Create Release
45+
env:
46+
GH_TOKEN: ${{ github.token }}
47+
run: |
48+
VERSION="${{ needs.check-release.outputs.version }}"
49+
gh release create "v$VERSION" \
50+
--title "v$VERSION" \
51+
--generate-notes

docs/RELEASING.md

Lines changed: 63 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -4,22 +4,34 @@ This document outlines the release process for the Nuxt UTM module.
44

55
## Release Workflow
66

7-
We follow a two-step release process:
8-
9-
1. **Manual Release Preparation (Local)**:
10-
11-
- Version bump
7+
We follow a PR-based release process that works with protected branches:
8+
9+
```mermaid
10+
flowchart TD
11+
A[Create release branch] --> B[Run yarn release:prepare]
12+
B --> C[Commit and push branch]
13+
C --> D[Open PR to main]
14+
D --> E[PR Review and Merge]
15+
E --> F{Version tag exists?}
16+
F -->|No| G[Create git tag]
17+
G --> H[Create GitHub Release]
18+
H --> I[Publish to NPM]
19+
F -->|Yes| J[Skip release]
20+
```
21+
22+
1. **Create a Release PR**:
23+
24+
- Version bump in `package.json`
1225
- CHANGELOG update
13-
- Tag creation
14-
- Git commit
15-
16-
2. **Automated NPM Publishing (GitHub Actions)**:
17-
- Triggered by the newly created release/tag
18-
- Builds and publishes the package to NPM
26+
- Open PR for review
1927

20-
## Manual Release Steps
28+
2. **Automated Release (GitHub Actions)**:
29+
- Triggered automatically when the PR is merged to main
30+
- Detects the new version and creates a git tag
31+
- Creates a GitHub Release
32+
- Publishes the package to NPM
2133

22-
To create a new release:
34+
## Creating a Release
2335

2436
1. Ensure you have the latest changes from the main branch:
2537

@@ -28,43 +40,51 @@ To create a new release:
2840
git pull origin main
2941
```
3042

31-
2. Make sure all tests pass:
43+
2. Create a release branch:
44+
45+
```bash
46+
git checkout -b release-X.Y.Z
47+
```
48+
49+
3. Make sure all tests pass:
3250

3351
```bash
3452
yarn test
3553
```
3654

37-
3. Run the release script, which will:
55+
4. Run the release script, which will:
3856

39-
- Bump the version in package.json
40-
- Update the CHANGELOG.md
41-
- Create a git tag
42-
- Commit changes
57+
- Bump the version in `package.json`
58+
- Update the `CHANGELOG.md`
4359

4460
```bash
45-
yarn release
61+
yarn release:prepare
4662
```
4763

48-
4. Push the changes including the new tag:
64+
5. Commit and push the release branch:
65+
4966
```bash
50-
# This will be done automatically by the release script
67+
git add .
68+
git commit -m "chore: release vX.Y.Z"
69+
git push -u origin release-X.Y.Z
5170
```
5271

53-
## Automated NPM Publishing
72+
6. Open a Pull Request to `main` and get it reviewed.
5473

55-
After the manual release process:
74+
7. Once the PR is merged, the CI will automatically:
75+
- Detect the new version
76+
- Create a git tag (`vX.Y.Z`)
77+
- Create a GitHub Release
78+
- Trigger the NPM publish workflow
5679

57-
1. GitHub Actions workflow [npm-publish.yml](../.github/workflows/npm-publish.yml) will be triggered automatically when:
80+
## Automated Release Detection
5881

59-
- A new GitHub release is created
60-
- OR manually triggered via workflow_dispatch
82+
The [release-on-merge.yml](../.github/workflows/release-on-merge.yml) workflow runs on every push to `main` that modifies `package.json`. It:
6183

62-
2. The workflow will:
63-
- Check out the repository
64-
- Set up Node.js
65-
- Install dependencies
66-
- Build the module
67-
- Publish to NPM using the credentials stored in GitHub secrets
84+
1. Reads the version from `package.json`
85+
2. Checks if a git tag for that version already exists
86+
3. If no tag exists, creates the tag and a GitHub Release
87+
4. The GitHub Release triggers the [npm-publish.yml](../.github/workflows/npm-publish.yml) workflow
6888

6989
## Version Numbering
7090

@@ -76,16 +96,24 @@ We follow [Semantic Versioning](https://semver.org/) for this project:
7696

7797
## Troubleshooting
7898

79-
If the automated publishing fails:
99+
If the automated release fails:
80100

81101
1. Check the GitHub Actions logs for errors
82102
2. Ensure the `npm_token` secret is correctly set in the repository settings
83-
3. Verify that the version in package.json hasn't already been published
103+
3. Verify that the version in `package.json` hasn't already been published
104+
4. If the release workflow failed but the tag was created, you can manually trigger the `npm-publish` workflow
105+
106+
If a release was skipped:
107+
108+
1. The workflow only runs when `package.json` is modified
109+
2. Check if the git tag already exists for the version
110+
3. You can manually trigger the release by creating a GitHub Release
84111

85112
## Additional Notes
86113

87114
- The release process uses [changelogen](https://github.com/unjs/changelogen) to generate CHANGELOG entries
88115
- Always verify that the published package works correctly by installing it in a test project
116+
- The main branch is protected; all releases must go through a PR
89117

90118
---
91119

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@
4545
"dev": "nuxi dev playground",
4646
"dev:build": "nuxi build playground",
4747
"dev:prepare": "nuxt-module-build build --stub && nuxt-module-build prepare && nuxi prepare playground",
48-
"release": "npm run prepack && changelogen --release && git push --follow-tags",
48+
"release:prepare": "npm run prepack && changelogen --release --no-tag --no-push",
4949
"lint": "eslint .",
5050
"lint:prettier": "eslint --config .eslintprettier.config.js .",
5151
"format": "prettier --write .",

0 commit comments

Comments
 (0)