marki-docx/docs/release-process.md

59 lines
1.9 KiB
Markdown
Raw Normal View History

# Release Process
## Pre-release checklist
Before tagging a release, verify every item:
- [ ] All tests pass: `pytest --tb=short -q`
- [ ] Lint clean: `ruff check .`
- [ ] Type-check clean: `mypy src/`
- [ ] Corpus regression passes: `markidocx test`
- [ ] SBOM is current (re-run after any dependency change — see CLAUDE.md)
- [ ] `CHANGELOG.md` updated: move items from `[Unreleased]` to a new versioned section
- [ ] Version bumped consistently:
- `src/markidocx/__init__.py``__version__ = "X.Y.Z"`
- `pyproject.toml``version = "X.Y.Z"`
- [ ] Build artefacts clean: `python -m build && twine check dist/*`
## Tagging and releasing
```bash
# Verify version strings match
python -c "import markidocx; print(markidocx.__version__)"
# Create a signed tag
git tag -s vX.Y.Z -m "Release vX.Y.Z"
# Push tag — triggers publish.yml (PyPI) and docker.yml (ghcr.io) automatically
git push origin vX.Y.Z
```
Pushing the tag triggers two GitHub Actions workflows:
- **`publish.yml`** — builds and publishes to PyPI via OIDC trusted publishing
- **`docker.yml`** — builds and pushes Docker image to `ghcr.io`
## Post-release
- Create a GitHub release from the tag and paste the relevant CHANGELOG section
- Verify installation: `pip install markidocx==X.Y.Z && markidocx --version`
- Verify Docker image: `docker run --rm ghcr.io/tegwick/marki-docx:vX.Y.Z --version`
## Versioning policy
markidocx follows [Semantic Versioning](https://semver.org/):
| Change type | Version bump |
|------------|-------------|
| Breaking change to CLI/API/round-trip contract | MAJOR |
| New feature, backwards-compatible | MINOR |
| Bug fix, docs, tooling | PATCH |
## Setting up PyPI trusted publishing (one-time)
In the PyPI project settings, add a trusted publisher:
- Publisher: GitHub Actions
- Repository owner: `tegwick`
- Repository name: `marki-docx`
- Workflow filename: `publish.yml`
- Environment name: (leave blank)