Skip to content

Commit 8580667

Browse files
jsightlerampagent
andcommitted
Add automated release workflow and release documentation
Amp-Thread-ID: https://ampcode.com/threads/T-019c45b8-410e-7667-b118-186b9e96aefb Co-authored-by: Amp <amp@ampcode.com>
1 parent 1b8f245 commit 8580667

3 files changed

Lines changed: 250 additions & 1 deletion

File tree

.beads/issues.jsonl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,4 @@
99
{"id":"ha-pecron-efq","title":"Add unit tests for integration","description":"Create tests directory with pytest tests for config_flow, sensor, and binary_sensor modules","status":"closed","priority":2,"issue_type":"task","owner":"jesse.sightler@gmail.com","created_at":"2026-02-09T23:05:48.104966901-05:00","created_by":"Jesse Sightler","updated_at":"2026-02-09T23:18:02.362672436-05:00","closed_at":"2026-02-09T23:18:02.362672436-05:00","close_reason":"Closed"}
1010
{"id":"ha-pecron-w33","title":"Create LICENSE file","description":"Add MIT license file to repository root","status":"closed","priority":2,"issue_type":"task","owner":"jesse.sightler@gmail.com","created_at":"2026-02-09T23:05:51.798560316-05:00","created_by":"Jesse Sightler","updated_at":"2026-02-09T23:13:24.899776281-05:00","closed_at":"2026-02-09T23:13:24.899776281-05:00","close_reason":"Closed"}
1111
{"id":"ha-pecron-y0m","title":"Register integration with Home Assistant community","description":"Submit to Home Assistant HACS registry to enable installation via HACS","status":"open","priority":2,"issue_type":"task","owner":"jesse.sightler@gmail.com","created_at":"2026-02-09T23:05:48.347237095-05:00","created_by":"Jesse Sightler","updated_at":"2026-02-09T23:05:48.347237095-05:00"}
12-
{"id":"ha-pecron-zcr","title":"Create release GitHub Action","description":"Set up automated release workflow using git tags for creating GitHub releases and publishing versions","status":"open","priority":2,"issue_type":"task","owner":"jesse.sightler@gmail.com","created_at":"2026-02-09T23:05:52.172524493-05:00","created_by":"Jesse Sightler","updated_at":"2026-02-09T23:05:52.172524493-05:00"}
12+
{"id":"ha-pecron-zcr","title":"Create release GitHub Action","description":"Set up automated release workflow using git tags for creating GitHub releases and publishing versions","status":"in_progress","priority":2,"issue_type":"task","owner":"jesse.sightler@gmail.com","created_at":"2026-02-09T23:05:52.172524493-05:00","created_by":"Jesse Sightler","updated_at":"2026-02-09T23:20:14.872048426-05:00"}

.github/workflows/release.yaml

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
name: Release
2+
3+
on:
4+
push:
5+
tags:
6+
- "v*.*.*"
7+
8+
permissions:
9+
contents: write
10+
11+
jobs:
12+
validate:
13+
runs-on: ubuntu-latest
14+
name: Validate Release
15+
16+
steps:
17+
- uses: actions/checkout@v4
18+
19+
- name: Extract version from tag
20+
id: version
21+
run: |
22+
VERSION=${GITHUB_REF#refs/tags/v}
23+
echo "version=$VERSION" >> $GITHUB_OUTPUT
24+
echo "tag=$GITHUB_REF_NAME" >> $GITHUB_OUTPUT
25+
26+
- name: Validate version format
27+
run: |
28+
VERSION=${{ steps.version.outputs.version }}
29+
if ! [[ $VERSION =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
30+
echo "Invalid version format: $VERSION"
31+
echo "Expected format: v0.0.0"
32+
exit 1
33+
fi
34+
echo "✓ Version format valid: $VERSION"
35+
36+
- name: Validate manifest version
37+
run: |
38+
VERSION=${{ steps.version.outputs.version }}
39+
MANIFEST_VERSION=$(python -c "import json; print(json.load(open('custom_components/pecron/manifest.json')).get('version', ''))")
40+
41+
if [ "$VERSION" != "$MANIFEST_VERSION" ]; then
42+
echo "Version mismatch!"
43+
echo "Tag version: $VERSION"
44+
echo "Manifest version: $MANIFEST_VERSION"
45+
exit 1
46+
fi
47+
echo "✓ Version matches manifest: $VERSION"
48+
49+
- name: Validate changelog entry
50+
run: |
51+
VERSION=${{ steps.version.outputs.version }}
52+
if ! grep -q "## \[$VERSION\]" CHANGELOG.md; then
53+
echo "No changelog entry found for version $VERSION"
54+
echo "Please add a section in CHANGELOG.md for this release"
55+
exit 1
56+
fi
57+
echo "✓ Changelog entry found"
58+
59+
create-release:
60+
needs: validate
61+
runs-on: ubuntu-latest
62+
name: Create GitHub Release
63+
64+
steps:
65+
- uses: actions/checkout@v4
66+
67+
- name: Extract version from tag
68+
id: version
69+
run: |
70+
VERSION=${GITHUB_REF#refs/tags/v}
71+
echo "version=$VERSION" >> $GITHUB_OUTPUT
72+
echo "tag=$GITHUB_REF_NAME" >> $GITHUB_OUTPUT
73+
74+
- name: Extract changelog section
75+
id: changelog
76+
run: |
77+
VERSION=${{ steps.version.outputs.version }}
78+
python << 'EOF'
79+
import re
80+
81+
with open('CHANGELOG.md', 'r') as f:
82+
content = f.read()
83+
84+
# Find the section for this version
85+
pattern = rf"## \[{re.escape(VERSION)}\].*?(?=## \[|$)"
86+
match = re.search(pattern, content, re.DOTALL)
87+
88+
if match:
89+
section = match.group(0)
90+
# Remove the header line
91+
lines = section.split('\n')[1:]
92+
# Remove trailing blank lines
93+
while lines and not lines[-1].strip():
94+
lines.pop()
95+
changelog = '\n'.join(lines).strip()
96+
else:
97+
changelog = "See CHANGELOG.md for details"
98+
99+
# Write to file for use in next step
100+
with open('/tmp/changelog.txt', 'w') as f:
101+
f.write(changelog)
102+
EOF
103+
cat /tmp/changelog.txt
104+
105+
- name: Create Release
106+
uses: ncipollo/release-action@v1
107+
with:
108+
tag: ${{ steps.version.outputs.tag }}
109+
name: "v${{ steps.version.outputs.version }}"
110+
bodyFile: /tmp/changelog.txt
111+
draft: false
112+
prerelease: false
113+
114+
- name: Release notification
115+
run: |
116+
echo "✓ Release created: ${{ steps.version.outputs.tag }}"
117+
echo "Release URL: https://github.com/${{ github.repository }}/releases/tag/${{ steps.version.outputs.tag }}"

RELEASE.md

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
# Release Process
2+
3+
This document describes how to create and publish a new release.
4+
5+
## Prerequisites
6+
7+
- All changes merged to `main` branch
8+
- All CI checks passing
9+
- CHANGELOG.md updated with release notes
10+
- Version bumped in `custom_components/pecron/manifest.json`
11+
12+
## Release Steps
13+
14+
### 1. Update Version
15+
16+
Update the version in `custom_components/pecron/manifest.json`:
17+
18+
```json
19+
{
20+
"version": "0.2.0"
21+
}
22+
```
23+
24+
### 2. Update Changelog
25+
26+
Add a new section to `CHANGELOG.md` at the top (under "## Unreleased" if present):
27+
28+
```markdown
29+
## [0.2.0] - 2026-02-10
30+
31+
### Added
32+
- New feature description
33+
- Another feature
34+
35+
### Fixed
36+
- Bug fix description
37+
38+
### Changed
39+
- Change description
40+
```
41+
42+
Follow [Keep a Changelog](https://keepachangelog.com/) format.
43+
44+
### 3. Commit Changes
45+
46+
```bash
47+
git add custom_components/pecron/manifest.json CHANGELOG.md
48+
git commit -m "Bump version to 0.2.0"
49+
git push
50+
```
51+
52+
### 4. Create Git Tag
53+
54+
```bash
55+
git tag -a v0.2.0 -m "Release version 0.2.0"
56+
git push origin v0.2.0
57+
```
58+
59+
Or without annotation:
60+
61+
```bash
62+
git tag v0.2.0
63+
git push origin v0.2.0
64+
```
65+
66+
### 5. GitHub Actions Will Automatically:
67+
68+
- Validate the version format (v0.0.0)
69+
- Verify version matches manifest.json
70+
- Check changelog entry exists
71+
- Create GitHub Release with changelog notes
72+
73+
## Release Validation
74+
75+
The release workflow validates:
76+
77+
1. **Version Format**: Must be `v{major}.{minor}.{patch}` (e.g., v1.2.3)
78+
2. **Manifest Version**: Tag version must match `manifest.json` version
79+
3. **Changelog Entry**: Release version must exist in CHANGELOG.md
80+
81+
If validation fails, the release workflow will fail with clear error messages.
82+
83+
## Release Checklist
84+
85+
- [ ] All features/fixes merged to main
86+
- [ ] All CI checks pass on main
87+
- [ ] CHANGELOG.md updated
88+
- [ ] Version bumped in manifest.json
89+
- [ ] Changes committed and pushed
90+
- [ ] Git tag created with correct format
91+
- [ ] Tag pushed to GitHub
92+
- [ ] Check GitHub Actions workflow completes
93+
- [ ] Verify release appears at https://github.com/jsight/ha-pecron/releases
94+
95+
## Rollback
96+
97+
If you need to remove a release:
98+
99+
```bash
100+
# Delete local tag
101+
git tag -d v0.2.0
102+
103+
# Delete remote tag
104+
git push origin :refs/tags/v0.2.0
105+
106+
# Delete GitHub release (via web UI)
107+
```
108+
109+
## HACS Automatic Updates
110+
111+
Once a release is published on GitHub:
112+
113+
1. HACS will detect the new release
114+
2. Users with HACS will see an update available
115+
3. Update will be installed from the GitHub release
116+
117+
No additional action needed for HACS integration once it's registered.
118+
119+
## Version Numbering
120+
121+
Follow [Semantic Versioning](https://semver.org/):
122+
123+
- **MAJOR** (v1.0.0): Incompatible API changes, breaking changes
124+
- **MINOR** (v0.1.0): New features, backwards compatible
125+
- **PATCH** (v0.0.1): Bug fixes, backwards compatible
126+
127+
Example progression:
128+
- v0.1.0 (initial release)
129+
- v0.1.1 (patch)
130+
- v0.2.0 (new feature)
131+
- v0.2.1 (patch)
132+
- v1.0.0 (major milestone)

0 commit comments

Comments
 (0)