Skip to content

Commit 7acf429

Browse files
committed
ci: Automate release and publishing process
This workflow triggers on merges to the `release` branch and performs the following actions: - Determines the semantic version bump (major, minor, patch) based on conventional commit messages. - Updates the package version. - Generates a `CHANGELOG.md` using `auto-changelog`. - Builds the package. - Commits changes, pushes a new git tag, and creates a GitHub Release. - Publishes the new version to the NPM registry.
1 parent 1ee024c commit 7acf429

File tree

15 files changed

+396
-72
lines changed

15 files changed

+396
-72
lines changed

.auto-changelog

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{
2+
"output": "docs/CHANGELOG.md",
3+
"template": "./docs/templates/changelog.hbs",
4+
"commitLimit": false,
5+
"breakingPattern": "(!:)",
6+
"issueUrl": "https://juspay.atlassian.net/browse/{id}",
7+
"issuePattern": "[A-Z]{2,}-\\d+",
8+
"compareUrl": "https://github.com/juspay/svelte-ui-components/compare/{to}..{from}",
9+
"unreleased": true,
10+
"releaseSummary": true,
11+
"hideCredit": false,
12+
"ignoreCommitPattern": "(\\[skip ci\\])",
13+
"replaceText": {
14+
"(ABC-\\d+)": "[`$1`](https://juspay.atlassian.net/browse/$1)"
15+
}
16+
}

.eslintrc.cjs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,5 +26,6 @@ module.exports = {
2626
parser: '@typescript-eslint/parser'
2727
}
2828
}
29-
]
29+
],
30+
ignorePatterns: ['README.md']
3031
};

.github/workflows/release.yml

Lines changed: 212 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,212 @@
1+
name: Release and Publish
2+
3+
on:
4+
push:
5+
branches: [release]
6+
pull_request:
7+
branches: [release]
8+
types: [closed]
9+
10+
jobs:
11+
release:
12+
# Only run on direct pushes to release branch or when PR is merged
13+
if: |
14+
(github.event_name == 'push') ||
15+
(github.event_name == 'pull_request' && github.event.pull_request.merged == true)
16+
17+
runs-on: ubuntu-latest
18+
19+
permissions:
20+
contents: write
21+
packages: write
22+
pull-requests: write
23+
24+
steps:
25+
- name: Checkout code
26+
uses: actions/checkout@v4
27+
with:
28+
fetch-depth: 0
29+
token: ${{ secrets.GITHUB_TOKEN }}
30+
31+
- name: Setup Node.js
32+
uses: actions/setup-node@v4
33+
with:
34+
node-version: '20'
35+
registry-url: 'https://registry.npmjs.org'
36+
37+
- name: Install pnpm
38+
uses: pnpm/action-setup@v4
39+
with:
40+
version: 8
41+
42+
- name: Install dependencies
43+
run: pnpm install
44+
45+
- name: Run linting
46+
run: pnpm lint
47+
48+
- name: Determine version bump type
49+
id: version-type
50+
run: |
51+
# Get the latest commit message
52+
COMMIT_MSG=$(git log -1 --pretty=format:"%s")
53+
echo "Latest commit: $COMMIT_MSG"
54+
55+
# Determine version bump based on commit message
56+
if echo "$COMMIT_MSG" | grep -iE "^feat(\(.+\))?!?:" > /dev/null; then
57+
if echo "$COMMIT_MSG" | grep -E "!" > /dev/null; then
58+
echo "version_type=major" >> $GITHUB_OUTPUT
59+
echo "Version bump: MAJOR (breaking change)"
60+
else
61+
echo "version_type=minor" >> $GITHUB_OUTPUT
62+
echo "Version bump: MINOR (new feature)"
63+
fi
64+
elif echo "$COMMIT_MSG" | grep -iE "^fix(\(.+\))?:" > /dev/null; then
65+
echo "version_type=patch" >> $GITHUB_OUTPUT
66+
echo "Version bump: PATCH (bug fix)"
67+
elif echo "$COMMIT_MSG" | grep -iE "^(build|chore|ci|docs|style|refactor|perf|test)(\(.+\))?:" > /dev/null; then
68+
echo "version_type=patch" >> $GITHUB_OUTPUT
69+
echo "Version bump: PATCH (maintenance)"
70+
else
71+
echo "version_type=patch" >> $GITHUB_OUTPUT
72+
echo "Version bump: PATCH (default)"
73+
fi
74+
75+
- name: Configure Git
76+
run: |
77+
git config user.name "github-actions[bot]"
78+
git config user.email "github-actions[bot]@users.noreply.github.com"
79+
80+
- name: Bump version and generate changelog
81+
id: version-bump
82+
run: |
83+
# Get current version
84+
CURRENT_VERSION=$(node -p "require('./package.json').version")
85+
echo "Current version: $CURRENT_VERSION"
86+
87+
# Bump version based on type
88+
if [ "${{ steps.version-type.outputs.version_type }}" = "major" ]; then
89+
NEW_VERSION=$(pnpm version major --no-git-tag-version)
90+
elif [ "${{ steps.version-type.outputs.version_type }}" = "minor" ]; then
91+
NEW_VERSION=$(pnpm version minor --no-git-tag-version)
92+
else
93+
NEW_VERSION=$(pnpm version patch --no-git-tag-version)
94+
fi
95+
96+
# Clean up version string (remove 'v' prefix if present)
97+
NEW_VERSION=$(echo $NEW_VERSION | sed 's/^v//')
98+
echo "New version: $NEW_VERSION"
99+
echo "new_version=$NEW_VERSION" >> $GITHUB_OUTPUT
100+
101+
- name: Generate changelog
102+
run: |
103+
# Install auto-changelog if not already installed
104+
if ! command -v auto-changelog &> /dev/null; then
105+
npm install -g auto-changelog
106+
fi
107+
108+
# Ensure docs directory exists
109+
mkdir -p docs
110+
111+
# Generate changelog
112+
auto-changelog --config .auto-changelog
113+
114+
# If changelog generation failed, create a basic one
115+
if [ ! -f "docs/CHANGELOG.md" ]; then
116+
echo "# Changelog" > docs/CHANGELOG.md
117+
echo "" >> docs/CHANGELOG.md
118+
echo "## [v${{ steps.version-bump.outputs.new_version }}] - $(date +%Y-%m-%d)" >> docs/CHANGELOG.md
119+
echo "" >> docs/CHANGELOG.md
120+
echo "### Changes" >> docs/CHANGELOG.md
121+
echo "- $(git log -1 --pretty=format:"%s")" >> docs/CHANGELOG.md
122+
fi
123+
124+
- name: Build package
125+
run: |
126+
pnpm build
127+
128+
- name: Create git tag
129+
run: |
130+
TAG_NAME="v${{ steps.version-bump.outputs.new_version }}"
131+
132+
# Delete tag if it exists locally
133+
if git tag -l | grep -q "^${TAG_NAME}$"; then
134+
git tag -d "$TAG_NAME"
135+
fi
136+
137+
# Delete tag if it exists remotely
138+
if git ls-remote --tags origin | grep -q "refs/tags/${TAG_NAME}$"; then
139+
git push origin ":refs/tags/$TAG_NAME"
140+
fi
141+
142+
# Create new tag
143+
git tag -a "$TAG_NAME" -m "Release $TAG_NAME"
144+
145+
- name: Stage and commit changes
146+
run: |
147+
# Check if there are any changes to commit
148+
if [ -n "$(git status --porcelain)" ]; then
149+
git add package.json
150+
if [ -f "docs/CHANGELOG.md" ]; then
151+
git add docs/CHANGELOG.md
152+
fi
153+
git commit -m "chore(release): v${{ steps.version-bump.outputs.new_version }}"
154+
else
155+
echo "No changes to commit"
156+
fi
157+
158+
- name: Push changes and tags
159+
run: |
160+
# Pull latest changes to avoid conflicts
161+
git fetch origin release
162+
163+
# Check if we're behind
164+
if [ $(git rev-list --count HEAD..origin/release) -gt 0 ]; then
165+
echo "Local branch is behind remote. Attempting to rebase..."
166+
git rebase origin/release
167+
fi
168+
169+
# Push changes first
170+
git push origin release
171+
172+
# Then push the tag
173+
git push origin "v${{ steps.version-bump.outputs.new_version }}"
174+
175+
echo "Successfully pushed version v${{ steps.version-bump.outputs.new_version }}"
176+
177+
- name: Publish to NPM
178+
run: |
179+
# Set up npm authentication
180+
echo "//registry.npmjs.org/:_authToken=${{ secrets.NPM_TOKEN }}" > ~/.npmrc
181+
182+
# Check if this version already exists on NPM
183+
PACKAGE_NAME=$(node -p "require('./package.json').name")
184+
NEW_VERSION="${{ steps.version-bump.outputs.new_version }}"
185+
186+
if npm view "$PACKAGE_NAME@$NEW_VERSION" version 2>/dev/null; then
187+
echo "Version $NEW_VERSION already exists on NPM, skipping publish"
188+
exit 0
189+
fi
190+
191+
# Publish to NPM (with organization scope support)
192+
npm publish --access public --registry https://registry.npmjs.org/
193+
echo "Successfully published $PACKAGE_NAME@$NEW_VERSION to NPM"
194+
195+
- name: Create GitHub Release
196+
uses: softprops/action-gh-release@v1
197+
id: create_release
198+
with:
199+
tag_name: v${{ steps.version-bump.outputs.new_version }}
200+
name: Release v${{ steps.version-bump.outputs.new_version }}
201+
body: |
202+
## What's Changed
203+
204+
See [CHANGELOG.md](https://github.com/juspay/svelte-ui-components/blob/release/docs/CHANGELOG.md) for detailed changes.
205+
206+
**Full Changelog**: https://github.com/juspay/svelte-ui-components/compare/v${{ steps.version-bump.outputs.previous_version }}...v${{ steps.version-bump.outputs.new_version }}
207+
draft: false
208+
prerelease: false
209+
files: |
210+
dist/**/*
211+
env:
212+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

.prettierignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,6 @@ node_modules
1111
pnpm-lock.yaml
1212
package-lock.json
1313
yarn.lock
14+
15+
# Ignore README formatting for now
16+
README.md

.vscode/settings.json

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,22 @@
11
{
2-
"workbench.colorCustomizations": {
3-
"activityBar.activeBackground": "#2f7c47",
4-
"activityBar.background": "#2f7c47",
5-
"activityBar.foreground": "#e7e7e7",
6-
"activityBar.inactiveForeground": "#e7e7e799",
7-
"activityBarBadge.background": "#422c74",
8-
"activityBarBadge.foreground": "#e7e7e7",
9-
"commandCenter.border": "#e7e7e799",
10-
"sash.hoverBorder": "#2f7c47",
11-
"statusBar.background": "#215732",
12-
"statusBar.foreground": "#e7e7e7",
13-
"statusBarItem.hoverBackground": "#2f7c47",
14-
"statusBarItem.remoteBackground": "#215732",
15-
"statusBarItem.remoteForeground": "#e7e7e7",
16-
"titleBar.activeBackground": "#215732",
17-
"titleBar.activeForeground": "#e7e7e7",
18-
"titleBar.inactiveBackground": "#21573299",
19-
"titleBar.inactiveForeground": "#e7e7e799"
20-
},
21-
"peacock.color": "#215732"
22-
}
2+
"workbench.colorCustomizations": {
3+
"activityBar.activeBackground": "#2f7c47",
4+
"activityBar.background": "#2f7c47",
5+
"activityBar.foreground": "#e7e7e7",
6+
"activityBar.inactiveForeground": "#e7e7e799",
7+
"activityBarBadge.background": "#422c74",
8+
"activityBarBadge.foreground": "#e7e7e7",
9+
"commandCenter.border": "#e7e7e799",
10+
"sash.hoverBorder": "#2f7c47",
11+
"statusBar.background": "#215732",
12+
"statusBar.foreground": "#e7e7e7",
13+
"statusBarItem.hoverBackground": "#2f7c47",
14+
"statusBarItem.remoteBackground": "#215732",
15+
"statusBarItem.remoteForeground": "#e7e7e7",
16+
"titleBar.activeBackground": "#215732",
17+
"titleBar.activeForeground": "#e7e7e7",
18+
"titleBar.inactiveBackground": "#21573299",
19+
"titleBar.inactiveForeground": "#e7e7e799"
20+
},
21+
"peacock.color": "#215732"
22+
}

docs/templates/changelog.hbs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
{{#each releases}}
2+
{{#if @first}}
3+
# Changelog All notable changes to this project will be documented in this file. The format is
4+
based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to
5+
[Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6+
7+
{{/if}}
8+
{{#if href}}
9+
## [{{title}}]({{href}}){{#if tag}} - {{niceDate}}{{/if}}
10+
{{else}}
11+
##
12+
{{title}}{{#if tag}} - {{niceDate}}{{/if}}
13+
{{/if}}
14+
15+
{{#if summary}}
16+
{{summary}}
17+
18+
{{/if}}
19+
{{#each sections}}
20+
{{#if title}}
21+
###
22+
{{title}}
23+
24+
{{/if}}
25+
{{#each commits}}
26+
{{#if breaking}}
27+
- **BREAKING:**
28+
{{subject}}{{#if href}} ([{{shorthash}}]({{href}})){{/if}}
29+
{{else}}
30+
-
31+
{{subject}}{{#if href}} ([{{shorthash}}]({{href}})){{/if}}
32+
{{/if}}
33+
{{/each}}
34+
{{/each}}
35+
36+
{{/each}}

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,9 @@
3636
"@digitalroute/cz-conventional-changelog-for-jira": "^8.0.1",
3737
"@playwright/test": "^1.39.0",
3838
"@sveltejs/adapter-auto": "^2.1.1",
39-
"@sveltejs/kit": "^2.20.6",
39+
"@sveltejs/kit": "^1.30.4",
4040
"@sveltejs/package": "^2.2.2",
41+
"@sveltejs/vite-plugin-svelte": "^2.5.0",
4142
"@typescript-eslint/eslint-plugin": "^6.11.0",
4243
"@typescript-eslint/parser": "^6.11.0",
4344
"commitizen": "^4.3.0",

0 commit comments

Comments
 (0)