This page documents the complete workflow from making code changes through committing, version bumping, and triggering releases. It covers the interaction between pre-commit hooks, commitizen for conventional commits, version management logic, and the automated release pipeline.
For details on individual CLI commands, see page 4.6 (Version Control and Release Commands). For pre-commit hook configuration, see page 9.2 (Pre-commit Hooks and Code Quality). For release workflow mechanics, see page 5.3 (Release Workflow).
The commit and version management workflow follows a structured pipeline that enforces quality standards at each stage and automates the transition from code changes to published releases.
Workflow: Code Change to Release
Sources: src/afterpython/cli/commands/bump.py1-119 afterpython/doc/package_maintenance/commit_workflow.md1-50 afterpython/doc/package_maintenance/package_releases.md1-56
The commit stage enforces code quality and commit message standards before changes enter the repository history.
When using ap commit, pre-commit hooks execute before the commit message prompt:
| Hook Stage | Configuration | Purpose |
|---|---|---|
trailing-whitespace | .pre-commit-config.yaml | Remove trailing whitespace |
end-of-file-fixer | .pre-commit-config.yaml | Ensure newline at EOF |
ruff-check | ruff.toml | Lint Python code |
ruff-format | ruff.toml | Format Python code |
commitizen | cz.toml | Validate commit message format |
commitizen-branch | cz.toml | Validate branch naming |
The ap commit command supports bypassing mechanisms through flags that control hook execution:
--no-pc - Skip pre-commit hooks before message prompt--no-cz - Disable commitizen validation in hooksgit commit --no-verify directly - Bypass all hooks entirelyCommit Command Flow with Code Entities
Sources: afterpython/doc/package_maintenance/commit_workflow.md23-42
Commitizen enforces the Conventional Commits specification defined in cz.toml. The format determines how version bumps are calculated:
| Commit Type | Version Impact | Example |
|---|---|---|
fix: | Patch increment | fix: resolve null pointer in parser |
feat: | Minor increment | feat: add export to CSV |
feat!: or BREAKING CHANGE: | Major increment | feat!: remove deprecated API |
docs:, style:, refactor:, test:, chore: | No version change | docs: update README |
The commitizen configuration resides at afterpython/cz.toml with the following critical settings:
tag_format = "v$version"
version_scheme = "pep440"
Sources: afterpython/doc/package_maintenance/commit_workflow.md18-29 afterpython/doc/package_maintenance/package_releases.md18-21
The ap bump command orchestrates version increments through commitizen while handling pre-release and development version transitions.
Version Bump Decision Logic
Sources: src/afterpython/cli/commands/bump.py25-98
The bump command implements three distinct version management strategies:
1. Default: Stay in Current Phase
When neither --pre nor --release is specified, the version remains in its current development phase:
Development releases (e.g., 0.1.0.dev3): Increments the dev number → 0.1.0.dev4
args = ["--devrelease", str(devrelease_number + 1), *ctx.args]Pre-releases (e.g., 0.1.0a1, 0.1.0rc2): Increments within the same pre-release type
a → alpha, b → beta, rc → rc2. Pre-release Transition: --pre Flag
Advances to the next pre-release phase:
| Current Version | Command | Result |
|---|---|---|
0.1.0.dev5 | ap bump --pre | 0.1.0rc0 |
0.1.0a1 | ap bump --pre | 0.1.0a2 |
0.1.0rc2 | ap bump --pre | 0.1.0rc3 |
3. Stable Release: --release Flag
Produces a stable version and automatically triggers the release workflow:
| Current Version | Command | Result | Action |
|---|---|---|---|
0.1.0.dev5 | ap bump --release | 0.1.0 | Auto-push tag |
0.1.0rc2 | ap bump --release | 0.1.0 | Auto-push tag |
Implementation: src/afterpython/cli/commands/bump.py49-66
Sources: src/afterpython/cli/commands/bump.py25-92 afterpython/doc/package_maintenance/package_releases.md9-21
After version bumping, if pixi is detected via the has_pixi() utility function src/afterpython/utils.py the system updates pixi.lock to reflect the new editable install version:
Lock File Update Sequence
The automatic commit uses a standardized message: "build: update pixi.lock after version bump" src/afterpython/cli/commands/bump.py114
Implementation: src/afterpython/cli/commands/bump.py94-118
Sources: src/afterpython/cli/commands/bump.py94-118
Git tags in the format v{version} serve as the trigger mechanism for the release workflow. The tag format is defined in cz.toml with tag_format = "v$version".
Tag Creation Methods
| Method | Tag Creation | Tag Push | Use Case |
|---|---|---|---|
ap bump --release | Automatic via cz bump | Automatic bump.py66 | Production releases |
ap bump (default) | Automatic via cz bump | Manual with ap release | Pre-releases, dev versions |
ap release | None (uses existing) | Pushes existing tag | Retry failed push |
ap release --force | None (uses existing) | Pushes even if dev version | Emergency releases |
Implementation details:
pyproject.toml versionsubprocess.run(["git", "push", "origin", tag])read_metadata() from pyprojectThe release.yml workflow activates on tag push events matching the pattern v*:
on:
push:
tags:
- 'v*'
Tag Push to Release Pipeline
Sources: src/afterpython/cli/commands/bump.py66 afterpython/doc/package_maintenance/package_releases.md24-48
The release workflow automatically marks versions containing pre-release identifiers (dev, a, b, rc) as pre-releases on GitHub:
| Version Example | GitHub Release Type |
|---|---|
v0.1.0 | Stable release |
v0.1.0.dev5 | Pre-release |
v0.1.0a1 | Pre-release |
v0.1.0rc2 | Pre-release |
This allows users to distinguish between stable and unstable releases in the GitHub Releases UI.
Sources: afterpython/doc/package_maintenance/package_releases.md24-48
The commit and version management workflow integrates with three GitHub Actions workflows:
| Workflow | Trigger | Purpose |
|---|---|---|
ci.yml | Every push | Lint, test, build verification |
deploy.yml | Push to main branch | Deploy website to GitHub Pages |
release.yml | Push tag v* | Publish to PyPI and create GitHub release |
Complete Workflow Integration
Sources: afterpython/doc/package_maintenance/commit_workflow.md1-50 afterpython/doc/package_maintenance/package_releases.md24-48
The version management workflow ensures that quality gates (CI checks) run on every commit, while releases are only triggered by explicit version tags, preventing accidental production deployments.
1. Make changes to code
2. ap commit # Pre-commit hooks + commitizen prompt
3. git push origin feature-branch
4. (Wait for CI to pass)
5. Merge to main
6. ap bump # Increment dev version (e.g., 0.1.0.dev3 -> 0.1.0.dev4)
7. git push origin main
1. Complete feature development on main branch
2. ap bump --pre # Transition to RC (e.g., 0.1.0.dev5 -> 0.1.0rc0)
3. git push origin main
4. (Test release candidate in staging/production)
5. ap bump --release # Promote to stable version + auto-trigger release workflow
1. Create hotfix branch from main
2. Make fix and commit with: fix: description
3. ap bump --release # Automatically increments patch version
4. Merge to main
1. Verify tag exists: git tag -l
2. ap release # Push existing tag to trigger release.yml
Sources: afterpython/doc/package_maintenance/commit_workflow.md1-50 afterpython/doc/package_maintenance/package_releases.md9-48
The workflow depends on several configuration files in the afterpython/ directory:
| File | Location | Purpose | Key Settings |
|---|---|---|---|
.pre-commit-config.yaml | afterpython/ | Pre-commit hook definitions | Hook repos, stages, args |
cz.toml | afterpython/ | Commitizen configuration | tag_format, version_scheme |
ruff.toml | afterpython/ | Linter/formatter rules | Line length, rules enabled |
.github/workflows/release.yml | .github/workflows/ | Release automation | PyPI trusted publishing, tag pattern |
These configuration files are initialized by ap init with optional flags:
.pre-commit-config.yaml - Created when user accepts pre-commit setupcz.toml - Created when user accepts commitizen setupruff.toml - Created automatically in afterpython/ directory.github/workflows/release.yml - Part of standard workflow initializationSources: src/afterpython/tools/commitizen.py6-13 src/afterpython/tools/pre_commit.py27-37 pyproject.toml1-74
If pixi install fails during bump src/afterpython/cli/commands/bump.py95-97 the bump command exits with the pixi error code. The version has already been committed, so manual intervention is required:
1. Fix pixi.toml or dependency issues
2. pixi install
3. git add pixi.lock
4. git commit -m "build: update pixi.lock after version bump"
If tag push fails after ap bump --release src/afterpython/cli/commands/bump.py66 the tag exists locally but not on remote:
1. Fix network/permission issues
2. ap release # Retry push with existing tag
The bump command respects --dry-run flag src/afterpython/cli/commands/bump.py53-54 In dry-run mode:
Refresh this wiki