Every push to main is released automatically. The version is derived from the commit
messages by ietf-tools/semver-action, and
the package is published to PyPI.
A push to main runs the CI/CD pipeline (.github/workflows/ci.yml):
- Runs the test suite across the supported Python and dbt-core versions (
tests.yml) - Runs the release job (
publish-pypi.yml), which:- Checks out the latest
mainand runs the tests again - Works out the next version from the commits since the latest
v*tag - Writes it to
pyproject.tomland pushes achore(release): vX.Y.Z [skip ci]commit - Builds the wheel and sdist from that commit
- Creates the
vX.Y.Ztag and a GitHub Release with generated release notes, both on that commit - Publishes the package to PyPI (https://pypi.org/project/dbt-ci/)
- Moves the major version tag (
v1) to that commit, so workflows using the GitHub Action asdatablock-dev/dbt-ci@v1pick up the release
- Checks out the latest
The release job waits for the GitHub Action smoke test (action-smoke.yml) as well as the
tests, so v1 never moves to a commit whose action.yml is broken.
Release notes live in GitHub Releases; there is no hand-maintained changelog.
Note: Pushes that change only Markdown files (*.md) skip the pipeline, and pull requests that change only Markdown files skip the tests. Any release they would have produced goes out with the next push that touches other files.
Note: Releases run one at a time, and each run releases the latest main rather than the commit that triggered it. Merging several PRs in quick succession therefore produces one release that includes all of them; the runs queued behind it find nothing new and skip without failing. The release tag points at the version-bump commit the package was built from.
Use Conventional Commits format:
<type>[optional scope]: <description>
[optional body]
[optional footer(s)]
PRs are squash-merged, so the PR title becomes the commit message that decides the version.
| Commit | Bump | Example |
|---|---|---|
feat: / feature: |
Minor (1.9.5 → 1.10.0) | feat: add S3 state storage support |
type!: or a BREAKING CHANGE: footer |
Major (1.9.5 → 2.0.0) | feat!: rename --prod-manifest-dir to --state |
Anything else (fix:, refactor:, chore:, docs:, …) |
Patch (1.9.5 → 1.9.6) | fix: resolve path resolution on Windows |
Every release-triggering push bumps at least the patch version, whatever its type.
# Breaking change
git commit -m "feat!: change --prod-manifest-dir to --state
BREAKING CHANGE: --prod-manifest-dir flag renamed to --state
for consistency with dbt conventions"
# No release at all
git commit -m "chore: tidy CI config [skip ci]"There is no manual release path: the release job only runs on a push to main
(running ci.yml by hand with workflow_dispatch runs the tests but not the release).
To release, merge a change to main.
- GitHub Releases: https://github.com/datablock-dev/dbt-ci/releases
- PyPI: https://pypi.org/project/dbt-ci/
- Pipeline runs:
gh run list --workflow=ci.yml
- Check that the push wasn't marked
[skip ci]and changed more than Markdown files. - Check the release job's log in the CI/CD Pipeline run.
- If an earlier run already released the same commits, the job logs "Couldn't find any commits between branch HEAD and latest tag. Exiting silently..." and skips. That is expected.
- Secrets: the job needs
ORG_TOKEN(to push the version bump tomainand read tags) andPYPI_TOKEN. - Push rejected: if another commit landed on
mainbetween checkout and the bump push, the push fails. The next push tomainreleases both.
The GitHub Action (action.yml at the repository root) is listed on the Marketplace by
publishing a GitHub Release with "Publish this Action to the GitHub Marketplace" ticked.
That has to be done once by hand from the release page; later releases stay listed.
.github/workflows/docker.yml can build images to ghcr.io/datablock-dev/dbt-ci, but no
workflow currently calls it, so releases do not publish Docker images.