diff --git a/.github/RELEASE.md b/.github/RELEASE.md new file mode 100644 index 0000000..1a7f2ff --- /dev/null +++ b/.github/RELEASE.md @@ -0,0 +1,159 @@ +# Release Process + +This document describes the process for releasing a new version of nmcli. + +## Current Release Flow (Phase 1: GitHub Release) + +Currently, only GitHub Release automation is implemented. PyPI publishing automation will be added in the future. + +## Pre-Release Checklist + +- [ ] All tests pass (`python -m pytest tests`) +- [ ] Type checking passes (`python -m mypy nmcli`) +- [ ] Lint checks pass (`python -m pylint nmcli`) +- [ ] README.md Change Log is updated +- [ ] README.md API documentation is up to date +- [ ] README.md Compatibility table is up to date + +## Release Steps + +### 1. Determine Version Number + +Follow semantic versioning: +- **MAJOR**: Incompatible API changes +- **MINOR**: Backwards-compatible functionality additions +- **PATCH**: Backwards-compatible bug fixes + +Example: Current `1.6.0` → Next `1.7.0` (for feature additions) + +### 2. Update pyproject.toml Version + +```toml +[project] +version = "1.7.0" # ← Update this +``` + +### 3. Update README.md Change Log + +Add the new version's changes to the "Change Log" section in README.md: + +```markdown +### 1.7.0 + +- Added support for `connection.show_all` with active filtering +- Added support for `device.up` and `device.down` commands +- Added support for `general.reload` with configuration flags +``` + +### 4. Commit Changes + +```bash +git add pyproject.toml README.md +git commit -m "Release v1.7.0" +``` + +### 5. Create and Push Tag + +```bash +# Push to main branch +git push origin main + +# Create tag +git tag v1.7.0 + +# Push tag (this triggers GitHub Actions) +git push origin v1.7.0 +``` + +### 6. Verify GitHub Actions Completion + +1. Check workflow execution status at https://github.com/ushiboy/nmcli/actions +2. Verify all tests pass +3. Verify build succeeds + +### 7. Edit and Publish Draft Release + +1. Go to https://github.com/ushiboy/nmcli/releases +2. Open the auto-created draft release +3. Edit release notes: + - Review auto-generated content + - Add main changes as bullet points in the "What's Changed" section + - Clean up commit history if needed +4. Click "Publish release" to publish + +### 8. Manual PyPI Publishing (Current) + +PyPI publishing is currently done manually: + +```bash +# Build (requires Python 3.10+) +python -m build + +# Upload to PyPI +twine upload dist/nmcli-1.7.0* +``` + +## Troubleshooting + +### Tag and Version Mismatch Error + +``` +Error: Package version (1.6.0) does not match tag version (1.7.0) +``` + +**Cause**: Forgot to update version in pyproject.toml + +**Solution**: +1. Delete tag: `git tag -d v1.7.0 && git push origin :v1.7.0` +2. Fix pyproject.toml and commit +3. Create and push tag again + +### Test Failures + +**Solution**: +1. Delete tag (see above) +2. Fix tests and commit +3. Create and push tag again + +### Build Failures + +Recommended to verify locally before tagging: + +```bash +# Clean build verification +rm -rf dist/ +python -m build + +# Check generated files +ls -lh dist/ +``` + +## Future Extension (Phase 2: PyPI Auto-Publishing) + +The following will be added in the future: + +1. **PyPI Trusted Publishers Setup** + - Register GitHub repository as a trusted publisher on PyPI + - No token management needed, more secure + +2. **Workflow Extension** + - Automatically publish to PyPI after GitHub Release + - Or make PyPI publishing optional at draft stage + +3. **TestPyPI Validation** + - Validate on TestPyPI before production release + +## Release Checklist + +Before releasing, verify: + +- [ ] Updated pyproject.toml version +- [ ] Updated README.md Change Log +- [ ] All tests pass locally +- [ ] Committed changes +- [ ] Pushed to main +- [ ] Created and pushed tag +- [ ] Verified GitHub Actions completion +- [ ] Edited draft release +- [ ] Published release +- [ ] (Current) Manually uploaded to PyPI diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..275dbfc --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,98 @@ +name: Release + +on: + push: + tags: + - 'v*.*.*' + +permissions: + contents: write + +jobs: + # Run tests first to ensure quality + test: + runs-on: ${{ matrix.os }} + strategy: + matrix: + include: + - python-version: '3.7' + os: ubuntu-22.04 + - python-version: '3.8' + os: ubuntu-latest + - python-version: '3.9' + os: ubuntu-latest + - python-version: '3.10' + os: ubuntu-latest + - python-version: '3.11' + os: ubuntu-latest + - python-version: '3.12' + os: ubuntu-latest + - python-version: '3.13' + os: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python-version }} + - name: Install dependencies + run: | + python -m pip install -U pip + pip install -r develop-requirements.txt + - name: Check mypy + run: python -m mypy nmcli + - name: Check lint + run: python -m pylint nmcli + - name: Run unit tests + run: python -m pytest tests + + # Build and create release after tests pass + build-and-release: + needs: test + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: '3.10' + + - name: Install build dependencies + run: | + python -m pip install -U pip + pip install build + + - name: Build package + run: python -m build + + - name: Extract version from tag + id: version + run: echo "version=${GITHUB_REF#refs/tags/v}" >> $GITHUB_OUTPUT + + - name: Verify version matches + run: | + PKG_VERSION=$(grep '^version = ' pyproject.toml | cut -d '"' -f 2) + TAG_VERSION="${{ steps.version.outputs.version }}" + if [ "$PKG_VERSION" != "$TAG_VERSION" ]; then + echo "Error: Package version ($PKG_VERSION) does not match tag version ($TAG_VERSION)" + exit 1 + fi + + - name: Create GitHub Release + uses: softprops/action-gh-release@v2 + with: + # Auto-generate release notes (editable after creation) + generate_release_notes: true + # Create as draft (publish after manual review) + draft: true + # Attach build artifacts + files: | + dist/*.whl + dist/*.tar.gz + # Release body template (shown before auto-generated notes) + body: | + ## What's Changed + + + + **Full Changelog**: https://github.com/${{ github.repository }}/compare/v${{ steps.version.outputs.version }}...v${{ steps.version.outputs.version }}