Releasing¶
Releases are cut by pushing a version tag. The release workflow then:
- Checks the tag matches the version in every package.
- Builds the web UI into the Python package and builds both wheels.
- Publishes
openpipeline-coreandopenpipelineto PyPI. - Builds and pushes a multi-arch Docker image (amd64 and arm64) to
ghcr.io/pawanpatil19/openpipeline, with an SBOM and provenance. - Creates a GitHub release with generated notes and the wheels attached.
Tags with a pre-release suffix (for example v0.2.0-rc1) are marked as
pre-releases and do not move the latest Docker tag.
Steps¶
python3 scripts/bump_version.py 0.2.0
uv lock
# Move the Unreleased section of CHANGELOG.md under a 0.2.0 heading.
git commit -am "Release 0.2.0"
git tag v0.2.0
git push origin main v0.2.0
bump_version.py sets the version in both Python packages, in
apps/web/package.json, and in the exact openpipeline-core== pin of the app.
Never edit those by hand. Check them with
python3 scripts/bump_version.py --check 0.2.0. The release workflow runs the
same check against the tag and stops if anything differs.
One-time setup¶
These need a repository admin and only have to be done once, before the first tag.
- PyPI trusted publishing. On PyPI, add a "pending publisher" for each
package, with owner
PawanPatil19, repositoryopenpipelineand workflowrelease.yml: openpipeline-corewith environmentpypi-coreopenpipelinewith environmentpypi
PyPI refuses two pending publishers with the same repository, workflow and
environment, which is why each package has its own environment. The first
release creates each project. No API token is stored in GitHub.
- GitHub environments. Create environments named pypi-core and pypi
under Settings > Environments. Adding yourself as a required reviewer gives
every release a final manual approval.
- GHCR visibility. The first image is pushed as a private package. After it
appears, make openpipeline public under the repository's Packages settings so
docker pull ghcr.io/pawanpatil19/openpipeline works without logging in.
- Branch protection. Require the All checks passed status on main. It
covers the Python matrix, the web checks, the Docker build, and the PR summary
action. The site build (Build docs) runs only when site, docs, or web files change, so add
it as a required check as well if you want it enforced.
Cutting 0.1.0 (the first release)¶
The version is 0.x on purpose: the project is young and names may still change. 1.0 comes after real teams have used it.
- Start from an up-to-date
mainwith every check green. - Confirm the one-time setup above is done. A missing PyPI publisher fails the release after the tag is pushed.
- Optional but recommended: rehearse on TestPyPI. Add the same two pending
publishers on https://test.pypi.org, with environments
testpypi-core(foropenpipeline-core) andtestpypi(foropenpipeline), create those two environments in GitHub, then run the Release workflow by hand frommain(Actions > Release > Run workflow) with "testpypi" ticked. Checkpip install -i https://test.pypi.org/simple/ --extra-index-url https://pypi.org/simple/ openpipeline==0.1.0. - Run
python3 scripts/bump_version.py --check 0.1.0. It should print nothing. - In
CHANGELOG.md, fold the Unreleased section into the0.1.0section, give it today's date, and leave an empty Unreleased section. - Run
make lint typecheck test build docs-build. Install the built wheels in a fresh virtual environment and runopenpipeline demo --no-serveto confirm the example ships inside them. - Tag and push:
git tag v0.1.0 && git push origin main v0.1.0. - Approve the
pypi-coreandpypienvironments when GitHub asks. Wait for the PyPI, Docker, and GitHub release jobs to finish. - Make the GHCR package public if this is the first image.
- Try it from scratch:
pip install openpipeline==0.1.0andopenpipeline demo, thendocker run --rm -p 8484:8484 ghcr.io/pawanpatil19/openpipeline:0.1.0. - Check that https://openpipeline.vercel.app/ (the landing page,
/docs/, and/demo/) is live and that the pull request action works with@v0.1.0.
Website (Vercel)¶
The website at https://openpipeline.vercel.app/ deploys from main through Vercel's
Git integration. Every push to main is a production deploy, and every pull request
gets a preview deploy. It is one static site:
/is the landing page insite/./docs/is the mkdocs site./demo/is a read-only copy of the web UI.scripts/export_demo.pywrites the demo project's API answers as JSON files that the UI reads instead of a server.
scripts/build_site.sh builds all three into build/site, and make site runs it
locally. The Site workflow runs the same script on pull requests.
One-time setup: in Vercel, choose Add New > Project, import this repository, and leave
Root Directory at the repository root. Everything else comes from vercel.json. If the
project gets a different production domain, set VERCEL_PROJECT_PRODUCTION_URL (Vercel
sets it for you) and update the links in README.md.