Skip to content

Commit e435bad

Browse files
nurbiy.teuchezhclaude
andcommitted
feat: add automated release workflow with changelog generation
Added comprehensive release automation: - Auto-tag workflow: automatically creates tags when package.json version changes - Release workflow: builds project, generates changelog, and creates GitHub releases - Changelog is automatically categorized by commit type (feat, fix, docs, chore) - CHANGELOG.md is automatically updated and committed back to main - Removed old build.yml workflow in favor of new release.yml Features: - Automatic tag creation on version bump in package.json - Changelog generation from conventional commits - Release notes with categorized changes (Features, Bug Fixes, Documentation, etc.) - CHANGELOG.md maintenance - Support for manual workflow triggers Files included in releases: - dynamic-weather-card.js (built file) - hacs.json, README.md, README.ru.md, LICENSE, CHANGELOG.md See .github/RELEASE.md for usage instructions 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
1 parent 943a4ec commit e435bad

5 files changed

Lines changed: 348 additions & 52 deletions

File tree

.github/RELEASE.md

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
# Release Process
2+
3+
This project uses automated workflows for creating releases and managing changelogs.
4+
5+
## Automated Release Process
6+
7+
### Option 1: Automatic Tag Creation (Recommended)
8+
9+
1. Update the version in `package.json`:
10+
```bash
11+
npm version patch # for bug fixes (0.2.1 -> 0.2.2)
12+
npm version minor # for new features (0.2.1 -> 0.3.0)
13+
npm version major # for breaking changes (0.2.1 -> 1.0.0)
14+
```
15+
16+
2. Commit and push to main:
17+
```bash
18+
git add package.json
19+
git commit -m "chore: bump version to v0.2.2"
20+
git push
21+
```
22+
23+
3. The `auto-tag.yml` workflow will automatically:
24+
- Detect the version change in package.json
25+
- Create a git tag (e.g., `v0.2.2`)
26+
- Push the tag to GitHub
27+
28+
4. The `release.yml` workflow will automatically:
29+
- Build the project
30+
- Generate a changelog from commits since the last release
31+
- Create a GitHub Release with the changelog
32+
- Update CHANGELOG.md and commit it back to main
33+
34+
### Option 2: Manual Tag Creation
35+
36+
1. Create and push a tag manually:
37+
```bash
38+
git tag -a v0.2.2 -m "Release v0.2.2"
39+
git push origin v0.2.2
40+
```
41+
42+
2. The `release.yml` workflow will run automatically
43+
44+
### Option 3: Manual Workflow Trigger
45+
46+
1. Go to GitHub Actions → Release workflow
47+
2. Click "Run workflow"
48+
3. Enter the version (e.g., `v0.2.2`)
49+
4. Click "Run workflow"
50+
51+
## Commit Message Convention
52+
53+
To generate meaningful changelogs, use conventional commit messages:
54+
55+
- `feat:` or `feature:` - New features (appears in ✨ Features)
56+
- `fix:` or `bugfix:` - Bug fixes (appears in 🐛 Bug Fixes)
57+
- `docs:` - Documentation changes (appears in 📚 Documentation)
58+
- `chore:`, `build:`, `ci:` - Maintenance tasks (appears in 🔧 Chores & Maintenance)
59+
- Other prefixes will appear in "Other Changes"
60+
61+
### Examples:
62+
63+
```bash
64+
git commit -m "feat: add dark mode toggle"
65+
git commit -m "fix: correct temperature display in night mode"
66+
git commit -m "docs: update README with new configuration options"
67+
git commit -m "chore: update dependencies"
68+
```
69+
70+
## What Gets Released
71+
72+
The release workflow automatically includes:
73+
- `dynamic-weather-card.js` - Built JavaScript file
74+
- `hacs.json` - HACS configuration
75+
- `README.md` - English documentation
76+
- `README.ru.md` - Russian documentation
77+
- `LICENSE` - License file
78+
- `CHANGELOG.md` - Full changelog history
79+
80+
## Changelog
81+
82+
The changelog is automatically:
83+
- Generated from git commits between releases
84+
- Categorized by commit type (features, fixes, docs, etc.)
85+
- Saved to CHANGELOG.md in the repository
86+
- Included in the GitHub Release notes
87+
88+
## Versioning
89+
90+
This project follows [Semantic Versioning](https://semver.org/):
91+
92+
- **MAJOR** version (X.0.0): Breaking changes
93+
- **MINOR** version (0.X.0): New features (backwards compatible)
94+
- **PATCH** version (0.0.X): Bug fixes (backwards compatible)

.github/workflows/auto-tag.yml

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
name: Auto Tag on Version Change
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
paths:
8+
- 'package.json'
9+
10+
permissions:
11+
contents: write
12+
13+
jobs:
14+
auto-tag:
15+
runs-on: ubuntu-latest
16+
17+
steps:
18+
- name: Checkout code
19+
uses: actions/checkout@v4
20+
with:
21+
fetch-depth: 0
22+
23+
- name: Get version from package.json
24+
id: package-version
25+
run: |
26+
VERSION=$(node -p "require('./package.json').version")
27+
echo "version=v$VERSION" >> $GITHUB_OUTPUT
28+
echo "Found version: v$VERSION"
29+
30+
- name: Check if tag exists
31+
id: check-tag
32+
run: |
33+
if git rev-parse "${{ steps.package-version.outputs.version }}" >/dev/null 2>&1; then
34+
echo "exists=true" >> $GITHUB_OUTPUT
35+
echo "Tag ${{ steps.package-version.outputs.version }} already exists"
36+
else
37+
echo "exists=false" >> $GITHUB_OUTPUT
38+
echo "Tag ${{ steps.package-version.outputs.version }} does not exist"
39+
fi
40+
41+
- name: Create and push tag
42+
if: steps.check-tag.outputs.exists == 'false'
43+
run: |
44+
git config user.name "github-actions[bot]"
45+
git config user.email "github-actions[bot]@users.noreply.github.com"
46+
git tag -a "${{ steps.package-version.outputs.version }}" -m "Release ${{ steps.package-version.outputs.version }}"
47+
git push origin "${{ steps.package-version.outputs.version }}"
48+
echo "✅ Created and pushed tag ${{ steps.package-version.outputs.version }}"
49+
50+
- name: Tag already exists
51+
if: steps.check-tag.outputs.exists == 'true'
52+
run: |
53+
echo "ℹ️ Tag ${{ steps.package-version.outputs.version }} already exists. Skipping tag creation."

.github/workflows/build.yml

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

.github/workflows/release.yml

Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
1+
name: Release
2+
3+
on:
4+
push:
5+
tags:
6+
- 'v*'
7+
workflow_dispatch:
8+
inputs:
9+
version:
10+
description: 'Version to release (e.g., v0.2.2)'
11+
required: true
12+
type: string
13+
14+
permissions:
15+
contents: write
16+
pull-requests: write
17+
18+
jobs:
19+
release:
20+
runs-on: ubuntu-latest
21+
22+
steps:
23+
- name: Checkout code
24+
uses: actions/checkout@v4
25+
with:
26+
fetch-depth: 0 # Fetch all history for changelog generation
27+
28+
- name: Setup Node.js
29+
uses: actions/setup-node@v4
30+
with:
31+
node-version: '20'
32+
cache: 'yarn'
33+
34+
- name: Install dependencies
35+
run: yarn install --frozen-lockfile
36+
37+
- name: Build
38+
run: yarn build
39+
40+
- name: Verify build output
41+
run: |
42+
if [ ! -f dynamic-weather-card.js ]; then
43+
echo "Build failed: dynamic-weather-card.js not found"
44+
exit 1
45+
fi
46+
echo "Build successful: $(wc -l < dynamic-weather-card.js) lines"
47+
48+
- name: Get version from tag or input
49+
id: version
50+
run: |
51+
if [ "${{ github.event_name }}" == "workflow_dispatch" ]; then
52+
echo "version=${{ inputs.version }}" >> $GITHUB_OUTPUT
53+
echo "tag=${{ inputs.version }}" >> $GITHUB_OUTPUT
54+
else
55+
echo "version=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT
56+
echo "tag=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT
57+
fi
58+
59+
- name: Generate Changelog
60+
id: changelog
61+
run: |
62+
# Get the previous tag
63+
PREV_TAG=$(git describe --tags --abbrev=0 HEAD^ 2>/dev/null || echo "")
64+
CURRENT_TAG="${{ steps.version.outputs.tag }}"
65+
66+
echo "Generating changelog from ${PREV_TAG} to ${CURRENT_TAG}"
67+
68+
# Generate changelog from commits
69+
if [ -z "$PREV_TAG" ]; then
70+
# First release - get all commits
71+
COMMITS=$(git log --pretty=format:"- %s (%h)" --no-merges)
72+
else
73+
# Get commits since last tag
74+
COMMITS=$(git log ${PREV_TAG}..HEAD --pretty=format:"- %s (%h)" --no-merges)
75+
fi
76+
77+
# Categorize commits
78+
FEATURES=$(echo "$COMMITS" | grep -E "^- (feat|feature):" || echo "")
79+
FIXES=$(echo "$COMMITS" | grep -E "^- (fix|bugfix):" || echo "")
80+
DOCS=$(echo "$COMMITS" | grep -E "^- docs?:" || echo "")
81+
CHORES=$(echo "$COMMITS" | grep -E "^- (chore|build|ci):" || echo "")
82+
OTHERS=$(echo "$COMMITS" | grep -vE "^- (feat|feature|fix|bugfix|docs?|chore|build|ci):" || echo "")
83+
84+
# Build changelog
85+
CHANGELOG="## What's Changed"$'\n'$'\n'
86+
87+
if [ -n "$FEATURES" ]; then
88+
CHANGELOG+="### ✨ Features"$'\n'
89+
CHANGELOG+="$FEATURES"$'\n'$'\n'
90+
fi
91+
92+
if [ -n "$FIXES" ]; then
93+
CHANGELOG+="### 🐛 Bug Fixes"$'\n'
94+
CHANGELOG+="$FIXES"$'\n'$'\n'
95+
fi
96+
97+
if [ -n "$DOCS" ]; then
98+
CHANGELOG+="### 📚 Documentation"$'\n'
99+
CHANGELOG+="$DOCS"$'\n'$'\n'
100+
fi
101+
102+
if [ -n "$CHORES" ]; then
103+
CHANGELOG+="### 🔧 Chores & Maintenance"$'\n'
104+
CHANGELOG+="$CHORES"$'\n'$'\n'
105+
fi
106+
107+
if [ -n "$OTHERS" ]; then
108+
CHANGELOG+="### Other Changes"$'\n'
109+
CHANGELOG+="$OTHERS"$'\n'$'\n'
110+
fi
111+
112+
# Add compare link if there's a previous tag
113+
if [ -n "$PREV_TAG" ]; then
114+
CHANGELOG+="**Full Changelog**: https://github.com/${{ github.repository }}/compare/${PREV_TAG}...${CURRENT_TAG}"
115+
fi
116+
117+
# Save to file for release notes
118+
echo "$CHANGELOG" > /tmp/changelog.md
119+
120+
# Output for GitHub Actions (escape newlines)
121+
echo "changelog<<EOF" >> $GITHUB_OUTPUT
122+
echo "$CHANGELOG" >> $GITHUB_OUTPUT
123+
echo "EOF" >> $GITHUB_OUTPUT
124+
125+
- name: Update CHANGELOG.md
126+
run: |
127+
CURRENT_TAG="${{ steps.version.outputs.tag }}"
128+
RELEASE_DATE=$(date +%Y-%m-%d)
129+
130+
# Create or update CHANGELOG.md
131+
if [ ! -f CHANGELOG.md ]; then
132+
echo "# Changelog" > CHANGELOG.md
133+
echo "" >> CHANGELOG.md
134+
echo "All notable changes to this project will be documented in this file." >> CHANGELOG.md
135+
echo "" >> CHANGELOG.md
136+
fi
137+
138+
# Add new release section at the top (after the header)
139+
{
140+
head -n 3 CHANGELOG.md
141+
echo ""
142+
echo "## [${CURRENT_TAG}] - ${RELEASE_DATE}"
143+
echo ""
144+
cat /tmp/changelog.md
145+
echo ""
146+
tail -n +4 CHANGELOG.md
147+
} > CHANGELOG.tmp && mv CHANGELOG.tmp CHANGELOG.md
148+
149+
- name: Commit CHANGELOG.md
150+
run: |
151+
git config user.name "github-actions[bot]"
152+
git config user.email "github-actions[bot]@users.noreply.github.com"
153+
git add CHANGELOG.md
154+
git commit -m "docs: update CHANGELOG.md for ${{ steps.version.outputs.tag }}" || echo "No changes to commit"
155+
git push origin HEAD:main || echo "Could not push to main"
156+
157+
- name: Create or Update Release
158+
uses: softprops/action-gh-release@v2
159+
with:
160+
tag_name: ${{ steps.version.outputs.tag }}
161+
name: Release ${{ steps.version.outputs.tag }}
162+
body: ${{ steps.changelog.outputs.changelog }}
163+
files: |
164+
dynamic-weather-card.js
165+
hacs.json
166+
README.md
167+
README.ru.md
168+
LICENSE
169+
CHANGELOG.md
170+
draft: false
171+
prerelease: false
172+
make_latest: true
173+
env:
174+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

0 commit comments

Comments
 (0)