Release Process
How a new version of Convexfolio gets published.
📖 New to releasing software? See the Glossary for terms like commit, tag, SemVer.
What is a release?
A “release” is a named snapshot of the code. Once a release exists:
- It has a version number (e.g.,
2.0.1). - It’s tagged in git so you can find it later.
- It’s described in
CHANGELOG.mdso people know what changed.
You’d cut a release when:
- You’ve fixed a bug users care about.
- You’ve added a feature.
- You’ve made a breaking change (this deserves a major version bump).
Releases are mostly administrative — there’s no magic build step.
What is SemVer?
Semantic Versioning is a convention for version
numbers. A version has three parts: MAJOR.MINOR.PATCH.
| Bump | When | Example |
|---|---|---|
| MAJOR | Incompatible change — old code will break. | 1.0.0 → 2.0.0 |
| MINOR | New feature, backwards-compatible. | 2.0.0 → 2.1.0 |
| PATCH | Bug fix, backwards-compatible. | 2.0.0 → 2.0.1 |
Examples:
- “I renamed the
Riskclass to useCFVaR2nddirectly.” → MAJOR (callers must update). - “I added a
QualityScoreclass.” → MINOR (additions don’t break anything). - “I fixed a typo in a docstring.” → PATCH.
Convexfolio uses SemVer.
What is a git tag?
A “tag” is a named pointer to a specific commit. Tags are how software marks releases in version control. (Glossary: tag)
git tag v2.0.0 # tag the current commit as v2.0.0
git push origin v2.0.0 # push the tag to the remote
Once a tag exists, you can always check out that exact version of the code:
git checkout v2.0.0
The pre-release checklist
Run through these before cutting a release. Each item is a one-liner explanation.
Code quality
- All tests pass. Run the coverage-enabled command from CI; the suite must pass the 90% package and critical-module branch gates.
- No type errors.
mypy convexfolio— should printSuccess: no issues found. - No lint errors.
ruff check convexfolio tests scripts benchmarks— should printAll checks passed!. - Build succeeds.
python -m build— should producedist/convexfolio-X.Y.Z-py3-none-any.whlanddist/convexfolio-X.Y.Z.tar.gz. - Site builds. From
site/, runnpm ci && npm run check && npm run build. - Links and site invariants pass. Run
python scripts/check_docs.pyandpython scripts/check_site.py.
Documentation
-
CHANGELOG.mdupdated. Add a section for the new version with### Added,### Changed,### Fixed, etc. -
README.mdreflects current features. Anything you added should be documented. - Examples still work. Re-run any tutorial commands.
Configuration
- Version bumped in
pyproject.toml. Theversion = "X.Y.Z"line at the top of the file.
The release steps
1. Make sure you’re on master, up-to-date
git checkout master
git pull origin master
2. Bump the version
Edit pyproject.toml:
[project]
version = "2.0.1" # or whatever the new version is
(If you’re not sure what to bump, see SemVer above.)
3. Update the changelog
Add a new section to CHANGELOG.md, just below ## [Unreleased]:
## [2.0.1] - YYYY-MM-DD
### Added
- Description of new feature.
### Changed
- Description of behaviour change.
### Fixed
- Description of bug fix.
Then add the link at the bottom of the file:
[2.0.1]: https://github.com/sachncs/convexfolio/compare/v2.0.0...v2.0.1
4. Run the quality checks
ruff check convexfolio tests scripts benchmarks
mypy convexfolio
PYTEST_DISABLE_PLUGIN_AUTOLOAD=1 pytest -q
python -m build
All four must succeed.
5. Commit and tag
git add pyproject.toml CHANGELOG.md
git commit -m "chore: release v2.0.1"
git tag v2.0.1
6. Push
git push origin master
git push origin v2.0.1
7. (Optional) Create a GitHub release
If you want a fancy release page on GitHub:
- Go to github.com/sachncs/convexfolio/releases.
- Click “Draft a new release”.
- Pick the tag you just pushed (
v2.0.1). - Title:
v2.0.1. - Description: paste the changelog section.
- Attach the wheel and sdist from
dist/(optional — most teams attach them, some don’t). - Click “Publish release”.
Rollback and recovery
Releases and deployments are immutable records. Do not delete or force-move a published tag to make a rollback look like a new release.
Package rollback
The previous stable package remains available as the v1.0.0 GitHub release.
Pin the application to that release while the v2 issue is investigated:
python -m pip install \
https://github.com/sachncs/convexfolio/releases/download/v1.0.0/convexfolio-1.0.0-py3-none-any.whl
Confirm the installed version and run the CLI smoke test before restoring service:
convexfolio --version
convexfolio --command print-report > /tmp/convexfolio-rollback-report.json
Pages rollback
GitHub Pages deploys from master. For a site regression, identify the last
known-good commit that still contains the Astro site, create a recovery branch
from it, and merge a reviewed pull request into master:
git switch -c recovery/site <known-good-commit>
git push -u origin recovery/site
After the merge, the Pages workflow runs automatically. Verify the deployed
homepage and /docs/architecture/ route before closing the incident. A
package rollback to v1.0.0 is separate: that tag predates the Astro site and
must not be treated as an automatic Pages rollback target.
Hotfix process
For critical bug fixes:
-
Branch from the release tag, not from
master:git checkout -b hotfix/v2.0.2 v2.0.1 -
Make the minimum change needed.
-
Bump the PATCH version (
2.0.1→2.0.2). -
Follow the regular release steps above.
-
Merge back to
masterwhen done:git checkout master git merge hotfix/v2.0.2 git push origin master
Where to look next
- Glossary — Every term used here.
- CHANGELOG.md — The changelog itself.
- Architecture — How the package fits together.
- Deployment — How to run the released version in production.