Release Process¶
Documentation Path
You are here: About > Release Process
- For contributing: See Contributing
- For project status: See Future Features
This document describes the automated release process for CIS Benchmark CLI using Python Semantic Release.
Overview¶
The project uses python-semantic-release for fully automated releases, similar to Google's Release Please. Releases are triggered automatically when commits are merged to the main branch.
Conventional Commits¶
All commits must follow the Conventional Commits specification:
Commit Types¶
Version-bumping types:
feat:- New feature (triggers minor version bump: 1.0.0 → 1.1.0)fix:- Bug fix (triggers patch version bump: 1.0.0 → 1.0.1)BREAKING CHANGE:- Breaking change in footer (triggers major version bump: 1.0.0 → 2.0.0)
Non-version-bumping types:
docs:- Documentation changeschore:- Maintenance tasksrefactor:- Code refactoringtest:- Test changesci:- CI/CD changes
Examples¶
# Patch release (1.0.0 → 1.0.1)
git commit -m "fix: resolve XCCDF namespace validation error"
# Minor release (1.0.0 → 1.1.0)
git commit -m "feat: add support for XCCDF 1.3 schema"
# Major release (1.0.0 → 2.0.0)
git commit -m "feat: redesign CLI command structure
BREAKING CHANGE: removed --format flag, use subcommands instead"
# No release
git commit -m "docs: update installation instructions"
Automated Release Workflow¶
When commits are pushed to main:
- Analyze Commits - python-semantic-release reads commit history since last release
- Determine Version - Calculates next version based on commit types
- Update Version - Updates
versionfield inpyproject.toml - Generate Changelog - Creates/updates
CHANGELOG.mdwith release notes - Create Git Tag - Tags commit with version (e.g.,
v1.0.0) - GitHub Release - Creates GitHub release with changelog
- Build Package - Builds wheel and sdist
- Publish to PyPI - Uploads to PyPI via trusted publisher (if release created)
All of this happens automatically on merge to main.
Release Types¶
Patch Release (1.0.0 → 1.0.1)¶
Triggered by commits with types: fix:, docs:, chore:, refactor:, test:, ci:
git commit -m "fix: handle missing CIS Controls gracefully"
git push origin main
# Auto-releases v1.0.1
Minor Release (1.0.0 → 1.1.0)¶
Triggered by commits with type: feat:
Major Release (1.0.0 → 2.0.0)¶
Triggered by commits with BREAKING CHANGE: in footer:
git commit -m "feat: restructure export command
BREAKING CHANGE: --style flag now required for XCCDF exports"
git push origin main
# Auto-releases v2.0.0
Manual Release (Emergency)¶
If automation fails or manual release is needed:
# Install semantic-release
pip install python-semantic-release
# Dry run (see what would happen)
semantic-release version --noop
# Create release
semantic-release version
# Publish to PyPI
semantic-release publish
CI/CD Workflows¶
CI Workflow (.github/workflows/ci.yml)¶
Runs on every push and pull request:
- Test - Run pytest with Python 3.12+
- Lint - Check code style (black, ruff)
- Security - Scan with bandit
Documentation Workflow (.github/workflows/docs.yml)¶
Deploys documentation to GitHub Pages:
- Triggered on changes to
docs/ormkdocs.yml - Builds MkDocs site
- Publishes to gh-pages branch
Release Workflow (.github/workflows/release.yml)¶
Automated releases on main branch:
- Analyzes commits since last release
- Bumps version if needed
- Creates GitHub release
- Publishes to PyPI via trusted publisher
PyPI Trusted Publisher Setup¶
One-time setup after creating the GitHub repository:
- Go to PyPI Publishing
-
Add new pending publisher:
-
PyPI Project Name:
cis-bench - Owner:
mitre - Repository:
cis-bench - Workflow:
release.yml - Environment: (leave blank)
- Save
The workflow will automatically publish to PyPI using OIDC (no API tokens needed).
Version Number Format¶
Versions follow Semantic Versioning:
MAJOR.MINOR.PATCH
1.0.0 → Initial release
1.0.1 → Patch (bug fixes)
1.1.0 → Minor (new features, backward compatible)
2.0.0 → Major (breaking changes)
Checking Current Version¶
Troubleshooting¶
No release created after merge:
Check if commits use conventional format:
Commits must start with feat:, fix:, etc.
Release failed:
- Check workflow runs
- Verify PyPI trusted publisher is configured
- Check commit permissions in workflow
Need to skip release:
Use commit types that don't trigger releases: