ci: switch dynamic versioning from file-based to git tag-based#175
Conversation
Replace [tool.uv-dynamic-versioning.from-file] (which read a hardcoded version from _version.py) with vcs=git so the package version is resolved from git tags at build time. This fixes the v1.0.0rc1 release issue where the tag said rc1 but PyPI got 1.0.0 because _version.py always returned '1.0.0'. Also adds fetch-depth: 0 to publish.yml so git tags are available during the release build. Co-Authored-By: AJ Steers <aj@airbyte.io>
🤖 Devin AI EngineerI'll be helping with this pull request! Here's what you should know: ✅ I will automatically:
Note: I can only respond to comments from users who have write access to this repository. ⚙️ Control Options:
|
| vcs = "git" | ||
| style = "pep440" | ||
| fallback-version = "0.0.0" |
There was a problem hiding this comment.
🔴 VCS versioning switch breaks pre-release workflow which still sets version via _version.py sed
The versioning source changed from file-based (from-file reading _version.py) to VCS-based (vcs = "git"), but the pre-release workflow (.github/workflows/pre-release-command.yml:122-127) still uses sed to modify _version.py to set the desired pre-release version. Since uv-dynamic-versioning now derives the package version from git tags instead of _version.py, the sed edit has no effect on the built package version.
Additionally, the pre-release workflow does a shallow checkout (no fetch-depth: 0 at .github/workflows/pre-release-command.yml:113-116), so VCS versioning will fall back to 0.0.0. Even with fetch-depth: 0, the version would be derived from the latest existing tag rather than the user-specified pre-release version, because the pre-release tag is only created after the build/publish steps (.github/workflows/pre-release-command.yml:138-144). The result is that pre-release packages will be published with the wrong version (likely 0.0.0).
Prompt for agents
The switch from file-based versioning to VCS git-tag-based versioning in pyproject.toml breaks the pre-release workflow at .github/workflows/pre-release-command.yml.
The pre-release workflow (lines 122-130) sets the version by editing src/airbyte_api/_version.py via sed, then builds. Previously, uv-dynamic-versioning read the version from that file, so this worked. Now that versioning is VCS-based (vcs = git), the sed edit is ignored — the package version comes from git tags.
Further, the pre-release workflow does a shallow checkout (no fetch-depth: 0) at line 113-116, so git tag history is unavailable and the version falls back to 0.0.0. Even adding fetch-depth: 0 won't fix it because the pre-release git tag is only created AFTER the build/publish at lines 138-144.
To fix this, the pre-release workflow needs a different mechanism to override the package version for pre-release builds. Possible approaches:
1. Create and push the git tag BEFORE the build step so VCS versioning picks it up (requires reordering steps and adding fetch-depth: 0).
2. Use an environment variable or CLI flag to override the version at build time if uv-dynamic-versioning supports it.
3. Keep the file-based override as a fallback — e.g. set a SETUPTOOLS_SCM_PRETEND_VERSION or equivalent env var that uv-dynamic-versioning respects.
Was this helpful? React with 👍 or 👎 to provide feedback.
| pattern = "__version__: str = \"(?P<version>[^\"]+)\"" | ||
| vcs = "git" | ||
| style = "pep440" | ||
| fallback-version = "0.0.0" |
There was a problem hiding this comment.
🚩 fallback-version of 0.0.0 could silently produce bad releases
The fallback-version = "0.0.0" at pyproject.toml:36 means that if VCS versioning fails for any reason (no tags found, shallow clone, detached HEAD without tag info, etc.), the package silently builds as version 0.0.0 instead of failing. This could lead to accidentally publishing a 0.0.0 package to PyPI. Consider whether it would be safer to omit the fallback (so the build fails loudly) or use a clearly-invalid fallback that would be caught by PyPI upload validation. This is a design tradeoff rather than a clear bug.
Was this helpful? React with 👍 or 👎 to provide feedback.
There was a problem hiding this comment.
Pull request overview
This PR updates the package’s dynamic versioning to derive the published version from git tags (PEP 440), and adjusts the PyPI publish workflow to fetch full git history so tags are available during release builds.
Changes:
- Switch
uv-dynamic-versioningconfiguration from file-based version extraction (src/airbyte_api/_version.py) to git tag–based versioning (vcs = "git",style = "pep440"). - Update the PyPI publish GitHub Action to use
fetch-depth: 0when checking out the release tag, ensuring tag history is available.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
pyproject.toml |
Reconfigures uv-dynamic-versioning to compute versions from git tags rather than a version file. |
.github/workflows/publish.yml |
Fetches full git history/tags during release checkout to support git tag–based versioning. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| [tool.uv-dynamic-versioning] | ||
| [tool.uv-dynamic-versioning.from-file] | ||
| source = "src/airbyte_api/_version.py" | ||
| pattern = "__version__: str = \"(?P<version>[^\"]+)\"" | ||
| vcs = "git" | ||
| style = "pep440" | ||
| fallback-version = "0.0.0" |
Summary
The
v1.0.0rc1release published1.0.0to PyPI instead of1.0.0rc1becauseuv-dynamic-versioningwas configured to read the version fromsrc/airbyte_api/_version.py(which hardcodes1.0.0) rather than from git tags.This matches the pattern used by PyAirbyte and airbyte-ops-mcp. The build version now comes from the git tag (e.g.
v1.0.0rc1→1.0.0rc1), and dev builds without a tag resolve to{last_tag}.postN.dev0+{sha}.Also adds
fetch-depth: 0topublish.ymlso the full tag history is available during release builds.Verified locally:
git tag v1.0.0rc1→ buildsairbyte_api-1.0.0rc1-py3-none-any.whlairbyte_api-0.53.0.post29.dev0+492ae670-py3-none-any.whlLink to Devin session: https://app.devin.ai/sessions/854c664803f3400387fdaa02e123b888
Requested by: Aaron ("AJ") Steers (@aaronsteers)