Skip to content

Commit 68a0107

Browse files
authored
Merge pull request #85 from ushiboy/chore/release-workflow
chore: Add release workflow
2 parents 20348af + b0e0a96 commit 68a0107

2 files changed

Lines changed: 257 additions & 0 deletions

File tree

.github/RELEASE.md

Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
# Release Process
2+
3+
This document describes the process for releasing a new version of nmcli.
4+
5+
## Current Release Flow (Phase 1: GitHub Release)
6+
7+
Currently, only GitHub Release automation is implemented. PyPI publishing automation will be added in the future.
8+
9+
## Pre-Release Checklist
10+
11+
- [ ] All tests pass (`python -m pytest tests`)
12+
- [ ] Type checking passes (`python -m mypy nmcli`)
13+
- [ ] Lint checks pass (`python -m pylint nmcli`)
14+
- [ ] README.md Change Log is updated
15+
- [ ] README.md API documentation is up to date
16+
- [ ] README.md Compatibility table is up to date
17+
18+
## Release Steps
19+
20+
### 1. Determine Version Number
21+
22+
Follow semantic versioning:
23+
- **MAJOR**: Incompatible API changes
24+
- **MINOR**: Backwards-compatible functionality additions
25+
- **PATCH**: Backwards-compatible bug fixes
26+
27+
Example: Current `1.6.0` → Next `1.7.0` (for feature additions)
28+
29+
### 2. Update pyproject.toml Version
30+
31+
```toml
32+
[project]
33+
version = "1.7.0" # ← Update this
34+
```
35+
36+
### 3. Update README.md Change Log
37+
38+
Add the new version's changes to the "Change Log" section in README.md:
39+
40+
```markdown
41+
### 1.7.0
42+
43+
- Added support for `connection.show_all` with active filtering
44+
- Added support for `device.up` and `device.down` commands
45+
- Added support for `general.reload` with configuration flags
46+
```
47+
48+
### 4. Commit Changes
49+
50+
```bash
51+
git add pyproject.toml README.md
52+
git commit -m "Release v1.7.0"
53+
```
54+
55+
### 5. Create and Push Tag
56+
57+
```bash
58+
# Push to main branch
59+
git push origin main
60+
61+
# Create tag
62+
git tag v1.7.0
63+
64+
# Push tag (this triggers GitHub Actions)
65+
git push origin v1.7.0
66+
```
67+
68+
### 6. Verify GitHub Actions Completion
69+
70+
1. Check workflow execution status at https://github.com/ushiboy/nmcli/actions
71+
2. Verify all tests pass
72+
3. Verify build succeeds
73+
74+
### 7. Edit and Publish Draft Release
75+
76+
1. Go to https://github.com/ushiboy/nmcli/releases
77+
2. Open the auto-created draft release
78+
3. Edit release notes:
79+
- Review auto-generated content
80+
- Add main changes as bullet points in the "What's Changed" section
81+
- Clean up commit history if needed
82+
4. Click "Publish release" to publish
83+
84+
### 8. Manual PyPI Publishing (Current)
85+
86+
PyPI publishing is currently done manually:
87+
88+
```bash
89+
# Build (requires Python 3.10+)
90+
python -m build
91+
92+
# Upload to PyPI
93+
twine upload dist/nmcli-1.7.0*
94+
```
95+
96+
## Troubleshooting
97+
98+
### Tag and Version Mismatch Error
99+
100+
```
101+
Error: Package version (1.6.0) does not match tag version (1.7.0)
102+
```
103+
104+
**Cause**: Forgot to update version in pyproject.toml
105+
106+
**Solution**:
107+
1. Delete tag: `git tag -d v1.7.0 && git push origin :v1.7.0`
108+
2. Fix pyproject.toml and commit
109+
3. Create and push tag again
110+
111+
### Test Failures
112+
113+
**Solution**:
114+
1. Delete tag (see above)
115+
2. Fix tests and commit
116+
3. Create and push tag again
117+
118+
### Build Failures
119+
120+
Recommended to verify locally before tagging:
121+
122+
```bash
123+
# Clean build verification
124+
rm -rf dist/
125+
python -m build
126+
127+
# Check generated files
128+
ls -lh dist/
129+
```
130+
131+
## Future Extension (Phase 2: PyPI Auto-Publishing)
132+
133+
The following will be added in the future:
134+
135+
1. **PyPI Trusted Publishers Setup**
136+
- Register GitHub repository as a trusted publisher on PyPI
137+
- No token management needed, more secure
138+
139+
2. **Workflow Extension**
140+
- Automatically publish to PyPI after GitHub Release
141+
- Or make PyPI publishing optional at draft stage
142+
143+
3. **TestPyPI Validation**
144+
- Validate on TestPyPI before production release
145+
146+
## Release Checklist
147+
148+
Before releasing, verify:
149+
150+
- [ ] Updated pyproject.toml version
151+
- [ ] Updated README.md Change Log
152+
- [ ] All tests pass locally
153+
- [ ] Committed changes
154+
- [ ] Pushed to main
155+
- [ ] Created and pushed tag
156+
- [ ] Verified GitHub Actions completion
157+
- [ ] Edited draft release
158+
- [ ] Published release
159+
- [ ] (Current) Manually uploaded to PyPI

.github/workflows/release.yml

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
name: Release
2+
3+
on:
4+
push:
5+
tags:
6+
- 'v*.*.*'
7+
8+
permissions:
9+
contents: write
10+
11+
jobs:
12+
# Run tests first to ensure quality
13+
test:
14+
runs-on: ${{ matrix.os }}
15+
strategy:
16+
matrix:
17+
include:
18+
- python-version: '3.7'
19+
os: ubuntu-22.04
20+
- python-version: '3.8'
21+
os: ubuntu-latest
22+
- python-version: '3.9'
23+
os: ubuntu-latest
24+
- python-version: '3.10'
25+
os: ubuntu-latest
26+
- python-version: '3.11'
27+
os: ubuntu-latest
28+
- python-version: '3.12'
29+
os: ubuntu-latest
30+
- python-version: '3.13'
31+
os: ubuntu-latest
32+
steps:
33+
- uses: actions/checkout@v4
34+
- uses: actions/setup-python@v5
35+
with:
36+
python-version: ${{ matrix.python-version }}
37+
- name: Install dependencies
38+
run: |
39+
python -m pip install -U pip
40+
pip install -r develop-requirements.txt
41+
- name: Check mypy
42+
run: python -m mypy nmcli
43+
- name: Check lint
44+
run: python -m pylint nmcli
45+
- name: Run unit tests
46+
run: python -m pytest tests
47+
48+
# Build and create release after tests pass
49+
build-and-release:
50+
needs: test
51+
runs-on: ubuntu-latest
52+
steps:
53+
- uses: actions/checkout@v4
54+
55+
- name: Set up Python
56+
uses: actions/setup-python@v5
57+
with:
58+
python-version: '3.10'
59+
60+
- name: Install build dependencies
61+
run: |
62+
python -m pip install -U pip
63+
pip install build
64+
65+
- name: Build package
66+
run: python -m build
67+
68+
- name: Extract version from tag
69+
id: version
70+
run: echo "version=${GITHUB_REF#refs/tags/v}" >> $GITHUB_OUTPUT
71+
72+
- name: Verify version matches
73+
run: |
74+
PKG_VERSION=$(grep '^version = ' pyproject.toml | cut -d '"' -f 2)
75+
TAG_VERSION="${{ steps.version.outputs.version }}"
76+
if [ "$PKG_VERSION" != "$TAG_VERSION" ]; then
77+
echo "Error: Package version ($PKG_VERSION) does not match tag version ($TAG_VERSION)"
78+
exit 1
79+
fi
80+
81+
- name: Create GitHub Release
82+
uses: softprops/action-gh-release@v2
83+
with:
84+
# Auto-generate release notes (editable after creation)
85+
generate_release_notes: true
86+
# Create as draft (publish after manual review)
87+
draft: true
88+
# Attach build artifacts
89+
files: |
90+
dist/*.whl
91+
dist/*.tar.gz
92+
# Release body template (shown before auto-generated notes)
93+
body: |
94+
## What's Changed
95+
96+
<!-- Add main changes as bullet points here -->
97+
98+
**Full Changelog**: https://github.com/${{ github.repository }}/compare/v${{ steps.version.outputs.version }}...v${{ steps.version.outputs.version }}

0 commit comments

Comments
 (0)