Release & Hot-Fix Workflow¶
This document explains how to cut a new feature release, data release, or hot-fix in the OpenAI Model Registry project.
Table of Contents¶
- Branching Model
- Release Types
- Library Release Workflow
- Data Release Workflow
- Hot-Fix Workflow
- Do's and Don'ts
- Troubleshooting
Branching Model¶
main– the only long-lived branch. All daily work happens here.- Tags – every published version (
v1.0.0,v1.0.1,data-v1.0.0) is an annotated git tag onmain. - Hot-fix branch – created only if you must fix the current release without pulling in unreleased work that is already on
main. Delete it right after the tag is pushed.
Release Types¶
1. Library Releases¶
Library releases contain the Python package code and are published to PyPI.
- Tag Format:
v1.0.0,v1.0.1,v1.1.0 - RC Format:
v1.0.0-rc1,v1.0.0-rc2 - Publishing:
- RC → TestPyPI
- Final → PyPI
2. Data Releases¶
Data releases contain model configuration files and are published as GitHub releases.
- Tag Format:
data-v1.0.0,data-v1.0.1 - RC Format:
data-v1.0.0-rc1,data-v1.0.0-rc2 - Publishing: GitHub Releases with data packages
Library Release Workflow¶
Before Writing Code¶
- Make sure you are on
mainand up-to-date:
git switch main
git pull --ff-only origin main
- Create a short feature branch (optional but recommended):
git switch -c feature/<short-name>
-
Implement the feature, update tests, update
CHANGELOG.mdincrementally. -
Open a PR (even if you merge it yourself) – CI must be green.
Creating a Release Candidate¶
-
Merge your PR into
main. -
Verify
CHANGELOG.mdand docs are ready. -
Run pre-release validation:
./scripts/release/create-rc.sh
- Create RC tag:
./scripts/release/create-rc.sh 1.0.0 1
-
CI automatically:
-
Builds the package
- Runs tests
- Publishes to TestPyPI
-
Creates GitHub release (marked as prerelease)
-
Test the RC:
pip install --index-url https://test.pypi.org/simple/ \
--extra-index-url https://pypi.org/simple/ \
"openai-model-registry==1.0.0rc1"
- Verify functionality:
python -c "import openai_model_registry; print('✅ Import works')"
python -c "from openai_model_registry import ModelRegistry, RegistryConfig; registry = ModelRegistry(RegistryConfig(auto_update=False)); print('✅ Registry works')"
Creating the Final Release¶
- After RC testing is complete and successful:
./scripts/release/create-final.sh 1.0.0
-
CI automatically:
-
Builds the package
- Runs tests
- Publishes to PyPI
-
Creates GitHub release (production)
-
Verify PyPI publication:
pip install openai-model-registry==1.0.0
python -c "import openai_model_registry; print('✅ PyPI install works')"
Data Release Workflow¶
Automatic Data Releases¶
Data releases are automatically triggered when configuration files change:
-
Edit data files in
data/: -
models.yaml- Model definitions -
overrides.yaml- Provider-specific overrides -
Commit and push to
main:
git add data/
git commit -m "feat: add new model definitions"
git push origin main
-
CI automatically:
-
Detects config changes
- Validates YAML files
- Creates data package
- Increments version
- Creates GitHub release
Contributor Data Release Playbook¶
Use this checklist when publishing a new data release (or RC):
- Update files:
data/models.yaml-
data/overrides.yaml -
Update
data/data-changelog.md(summarize changes, breaking notes) - Tag and publish:
- RC:
data-vX.Y.Z-rcN - Final:
data-vX.Y.Z - Attach assets:
models.yaml,overrides.yaml - Provide clear Release notes and link to changelog
- Verify client awareness:
- Run
omr --format json update check→ exit code10indicates an available update - In code:
ModelRegistry.check_for_updates()/get_update_info()returns latest - Optionally notify via GitHub Releases (watch → releases)
- Respect environments:
- Clients may pin via
OMR_DATA_VERSION_PIN - Clients may disable updates via
OMR_DISABLE_DATA_UPDATES - Confirm integrity:
- Assets properly attached and downloadable
- Fallback raw URLs (only if needed) should be tag-pinned for immutability
Manual Data Releases¶
For manual data releases or RCs:
- Create RC:
./scripts/release/create-rc.sh 1.0.0 1 --data
- Create final release:
./scripts/release/create-final.sh 1.0.0 --data
- Test data release:
# Download and verify
curl -L https://github.com/yaniv-golan/openai-model-registry/releases/download/data-v1.0.0/openai-model-registry-data-1.0.0.tar.gz -o data.tar.gz
tar -xzf data.tar.gz
cd data-package
# Verify files are present
ls -la models.yaml overrides.yaml
Hot-Fix Workflow¶
Scenario A – Fix is already on main and safe to release¶
-
Ensure
CHANGELOG.mdhas a Hot-fix entry. -
Tag and push directly from
main:
git switch main && git pull --ff-only
./scripts/release/create-final.sh 1.1.1
Scenario B – Fix must not include unreleased work on main¶
- Create a throw-away branch from the last tag:
git switch -c hotfix/v1.1.1 v1.1.0
-
Cherry-pick or implement just the necessary commits.
-
Update
CHANGELOG.mdin that branch. -
Tag & push:
git tag -a v1.1.1 -m "v1.1.1: security hot-fix"
git push origin hotfix/v1.1.1 v1.1.1
- After CI turns green, delete the branch:
git push origin --delete hotfix/v1.1.1
git branch -D hotfix/v1.1.1
Do's and Don'ts¶
Do ✓¶
- Keep
mainin a releasable state; let CI protect you. - Use annotated tags (
-a) for every version. - Update the CHANGELOG steadily while you code.
- Delete merged or obsolete branches immediately.
- Test release candidates thoroughly before final release.
- Use the provided scripts for consistent release process.
- Run validation before creating releases.
Don't ✗¶
- ✗ Don't create long-lived
release/x.ybranches – history gets messy. - ✗ Don't manually publish to PyPI – CI handles this automatically.
- ✗ Don't force-push to shared branches or tags.
- ✗ Don't skip RC testing for significant releases.
- ✗ Don't forget to update CHANGELOG.md.
Troubleshooting¶
Common Issues¶
Release Script Fails¶
# Check if you're on main branch
git branch --show-current
# Ensure you're up to date
git pull --ff-only origin main
# Check for existing tags
git tag -l | grep v1.0.0
CI Build Fails¶
-
Check GitHub Actions logs for detailed error messages
-
Run validation locally:
./scripts/release/create-final.sh
- Test locally:
poetry run pytest -v
poetry build
python -m twine check dist/*
TestPyPI Installation Fails¶
# Try with verbose output
pip install -v --index-url https://test.pypi.org/simple/ \
--extra-index-url https://pypi.org/simple/ \
"openai-model-registry==1.0.0rc1"
# Check if dependencies are available
pip install --index-url https://test.pypi.org/simple/ \
--extra-index-url https://pypi.org/simple/ \
--dry-run "openai-model-registry==1.0.0rc1"
Version Mismatch¶
# Check current versions
poetry version --short
python -c "import openai_model_registry; print(openai_model_registry.__version__)"
# Update if needed
poetry version 1.0.0
Getting Help¶
- Check CI logs in GitHub Actions
- Review validation output from CI workflows (build/tests/docs) triggered by the release tag
- Test in clean environment to isolate issues
- Check existing tags to avoid conflicts
Automation Overview¶
GitHub Actions Workflows¶
-
release.yml - Library releases
-
Triggered by
v*andv*-rc*tags - Builds package, runs tests, publishes to PyPI/TestPyPI
-
Creates GitHub releases
-
data-release-enhanced.yml - Data releases
-
Triggered by config file changes or
data-v*tags - Validates YAML, creates data packages
-
Creates GitHub releases
-
cross-platform-test.yml - Cross-platform testing
-
Tests installation across OS and Python versions
- Validates package quality and performance
Scripts¶
- create-rc.sh - Create release candidates
- create-final.sh - Create final releases
- Use GitHub Actions logs for validation (build/tests/docs) instead of local
validate-release.py
Related Documentation¶
- RELEASE_CHECKLIST.md - Pre-release validation checklist
- CHANGELOG.md - Version history and changes
- CONTRIBUTING.md - General contribution guidelines
- ostruct pricing automation - Detector and per-model pricing extraction templates used by CI