Skip to content

feat(ci): migrate build, test, and publish pipelines to uv#66

Merged
danieljrc888 merged 1 commit intomainfrom
chore/migrate-to-uv
Mar 1, 2026
Merged

feat(ci): migrate build, test, and publish pipelines to uv#66
danieljrc888 merged 1 commit intomainfrom
chore/migrate-to-uv

Conversation

@danieljrc888
Copy link
Contributor

@danieljrc888 danieljrc888 commented Feb 23, 2026

Summary

  • Replace pip/twine/build with uv across all CI workflows (tests, release, publish)
  • Add [dependency-groups] dev group in pyproject.toml, delete requirements.test.txt
  • Use uvx for one-shot semantic-release invocation instead of pip-installing it
  • Use uv publish instead of twine with UV_PUBLISH_TOKEN
  • Update CLAUDE.md dev commands to use uv

Test plan

  • uv sync --group dev installs all deps from lockfile
  • uv run pytest tests/unit --disable-warnings -v -m "not testnet" — 41 passed
  • uv build produces sdist and wheel
  • CI tests workflow passes on PR
  • Verify no GitHub secrets changes needed (PYPI_API_TOKEN reused as-is)

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Documentation

    • Added comprehensive developer documentation covering architecture overview, core components, design patterns, development workflow, and detailed setup instructions for project contributors.
  • Chores

    • Transitioned build, test, and release pipelines from traditional Python tooling to the uv package manager for streamlined dependency management and improved execution.
    • Consolidated development dependencies from separate requirements file into the project configuration file for centralized management.

@coderabbitai
Copy link

coderabbitai bot commented Feb 23, 2026

Warning

Rate limit exceeded

@danieljrc888 has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 18 minutes and 46 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between 6321eb6 and 0ebfb04.

⛔ Files ignored due to path filters (1)
  • uv.lock is excluded by !**/*.lock
📒 Files selected for processing (7)
  • .github/workflows/publish.yml
  • .github/workflows/smoke.yml
  • .github/workflows/tests.yml
  • CLAUDE.md
  • pyproject.toml
  • requirements.test.txt
  • scripts/semantic-version-release.sh
📝 Walkthrough

Walkthrough

This PR migrates the project's Python toolchain and CI/CD workflows from pip and setuptools to uv, a modern Python package manager. Changes include updating GitHub Actions to use uv for Python setup and dependency management, replacing twine with uv publish, updating build commands, reorganizing test dependencies, and adding developer documentation.

Changes

Cohort / File(s) Summary
CI/CD Workflow Migration
.github/workflows/publish.yml, .github/workflows/tests.yml
Updated Python setup from actions/setup-python to astral-sh/setup-uv, replaced pip install with uv sync --group dev, replaced python -m build with uv build, replaced twine upload with uv publish, and updated test execution to use uv run pytest.
Dependency Configuration
pyproject.toml, requirements.test.txt
Moved test dependencies (pytest, python-dotenv) from requirements.test.txt to a new [dependency-groups] dev section in pyproject.toml; removed requirements.test.txt entries.
Release Script
scripts/semantic-version-release.sh
Wrapped semantic-release invocation with uvx --from 'python-semantic-release==10.0.2' for consistent toolchain usage.
Developer Documentation
CLAUDE.md
Added comprehensive developer guide covering setup commands, testing structure, architecture overview, design patterns, and release workflow.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Suggested reviewers

  • cristiam86

Poem

🐰 With uv so swift, the workflows gleam,
No pip delays, just a developer's dream!
From workflows to scripts, all now aligned,
A faster Python toolchain, elegantly designed. ✨

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main change: migrating CI pipelines to use uv, which is reflected across all modified workflow files, build configuration, and supporting scripts.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch chore/migrate-to-uv

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (5)
.github/workflows/tests.yml (3)

14-14: Quote Python version matrix entries to avoid YAML float ambiguity.

[3.12, 3.13] are unquoted YAML floats. While 3.12 and 3.13 happen to survive float-to-string conversion correctly, 3.10 would silently become "3.1". The official uv GitHub Actions guide quotes all matrix python versions as strings.

♻️ Proposed fix
-        python-version: [3.12, 3.13]
+        python-version: ["3.12", "3.13"]
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/tests.yml at line 14, Update the python-version matrix
entry to use string values to avoid YAML float parsing (e.g., change
python-version: [3.12, 3.13] to quoted strings); locate the python-version key
in the GitHub Actions workflow (tests.yml) and replace unquoted numeric entries
with quoted strings like "3.12" and "3.13" so versions such as "3.10" won't be
interpreted as floats.

27-30: Add --frozen to uv sync and uv run for reproducible CI.

Without --frozen, if uv.lock is out of sync with pyproject.toml, uv will silently update the lockfile and install different dependency versions in the runner — breaking reproducibility. --frozen fails fast instead, forcing the developer to commit an updated lockfile.

♻️ Proposed fix
-        run: uv sync --group dev --python ${{ matrix.python-version }}
+        run: uv sync --frozen --group dev --python ${{ matrix.python-version }}

-        run: uv run pytest tests/unit --disable-warnings -v -m "not testnet"
+        run: uv run --frozen pytest tests/unit --disable-warnings -v -m "not testnet"
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/tests.yml around lines 27 - 30, Add the --frozen flag to
the uv commands to enforce lockfile consistency: update the uv sync invocation
(uv sync --group dev --python ${{ matrix.python-version }}) and the uv run
invocation that runs tests (uv run pytest tests/unit --disable-warnings -v -m
"not testnet") so both include --frozen, causing the workflow to fail if uv.lock
is out of sync with pyproject.toml rather than silently updating dependencies.

20-21: astral-sh/setup-uv@v5 is two major versions behind — upgrade to v7.

The current version of setup-uv is v7 and the official astral docs recommend astral-sh/setup-uv@v7. Using v5 misses two major releases of features and fixes.

Additionally, v7 supports a python-version input directly on the action, removing the need for the separate uv python install step:

♻️ Consolidated setup using v7
-      - name: Setup | Install uv
-        uses: astral-sh/setup-uv@v5
-
-      - name: Setup | Install Python ${{ matrix.python-version }}
-        run: uv python install ${{ matrix.python-version }}
+      - name: Setup | Install uv and Python ${{ matrix.python-version }}
+        uses: astral-sh/setup-uv@v7
+        with:
+          python-version: ${{ matrix.python-version }}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/tests.yml around lines 20 - 21, Update the GitHub Actions
step that currently uses astral-sh/setup-uv@v5 to use astral-sh/setup-uv@v7, and
remove the separate "uv python install" step by passing the python-version input
directly to the setup action; target the step named "Setup | Install uv" (uses:
astral-sh/setup-uv@v5) and any following step invoking "uv python install" and
replace them with a single setup step using the v7 action with the
python-version argument.
pyproject.toml (1)

36-36: python-dotenv==1.1.0 is stale — current latest is 1.2.1.

python-dotenv releases: 1.2.1 (Oct 2025), 1.2.0 (Oct 2025), 1.1.1 (Jun 2025), 1.1.0 (Mar 2025). 1.1.1 notably fixes find_dotenv reliability on Python 3.13, which this project targets. Consider bumping to at least 1.1.1, or ideally 1.2.1.

📦 Suggested update
-    "python-dotenv==1.1.0",
+    "python-dotenv==1.2.1",
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@pyproject.toml` at line 36, Update the pinned dependency
"python-dotenv==1.1.0" in pyproject.toml to a newer release (at least "1.1.1" to
pick up the find_dotenv fix for Python 3.13, ideally "1.2.1"); locate the
dependency entry containing the exact token "python-dotenv==1.1.0" and replace
it with the chosen version, then run your dependency resolution / lockfile
update (poetry lock or equivalent) and test loads that use find_dotenv or
dotenv.load_dotenv to confirm no regressions.
.github/workflows/publish.yml (1)

56-57: astral-sh/setup-uv@v5 in both jobs — upgrade to v7.

Same stale version as in tests.yml. Two major releases (v6v7) have shipped since v5 with meaningful bug fixes.

♻️ Proposed fix (both occurrences)
-      - name: Setup | Install uv
-        uses: astral-sh/setup-uv@v5
+      - name: Setup | Install uv
+        uses: astral-sh/setup-uv@v7

Apply in both release-and-upload (line 57) and publish-to-pypi (line 99).

Also applies to: 98-99

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/publish.yml around lines 56 - 57, Update the GitHub Action
step that uses astral-sh/setup-uv@v5 to the newer tag v7 in both jobs; locate
the "Setup | Install uv" step (uses: astral-sh/setup-uv@v5) in the
release-and-upload job and the same step in the publish-to-pypi job and change
the version suffix from `@v5` to `@v7` so both occurrences use
astral-sh/setup-uv@v7.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@CLAUDE.md`:
- Line 80: The README claim in CLAUDE.md saying "Supports Python 3.8+" is
inconsistent with pyproject.toml which sets requires-python = ">=3.12" and only
lists Python 3.12/3.13 classifiers; update CLAUDE.md to match pyproject.toml
(e.g., change the phrase "Supports Python 3.8+" to "Supports Python 3.12+" or
similar), or alternatively update pyproject.toml requires-python and classifiers
if you intend to support 3.8+, ensuring the two places (the string in CLAUDE.md
and the requires-python/classifiers in pyproject.toml) are consistent.

---

Nitpick comments:
In @.github/workflows/publish.yml:
- Around line 56-57: Update the GitHub Action step that uses
astral-sh/setup-uv@v5 to the newer tag v7 in both jobs; locate the "Setup |
Install uv" step (uses: astral-sh/setup-uv@v5) in the release-and-upload job and
the same step in the publish-to-pypi job and change the version suffix from `@v5`
to `@v7` so both occurrences use astral-sh/setup-uv@v7.

In @.github/workflows/tests.yml:
- Line 14: Update the python-version matrix entry to use string values to avoid
YAML float parsing (e.g., change python-version: [3.12, 3.13] to quoted
strings); locate the python-version key in the GitHub Actions workflow
(tests.yml) and replace unquoted numeric entries with quoted strings like "3.12"
and "3.13" so versions such as "3.10" won't be interpreted as floats.
- Around line 27-30: Add the --frozen flag to the uv commands to enforce
lockfile consistency: update the uv sync invocation (uv sync --group dev
--python ${{ matrix.python-version }}) and the uv run invocation that runs tests
(uv run pytest tests/unit --disable-warnings -v -m "not testnet") so both
include --frozen, causing the workflow to fail if uv.lock is out of sync with
pyproject.toml rather than silently updating dependencies.
- Around line 20-21: Update the GitHub Actions step that currently uses
astral-sh/setup-uv@v5 to use astral-sh/setup-uv@v7, and remove the separate "uv
python install" step by passing the python-version input directly to the setup
action; target the step named "Setup | Install uv" (uses: astral-sh/setup-uv@v5)
and any following step invoking "uv python install" and replace them with a
single setup step using the v7 action with the python-version argument.

In `@pyproject.toml`:
- Line 36: Update the pinned dependency "python-dotenv==1.1.0" in pyproject.toml
to a newer release (at least "1.1.1" to pick up the find_dotenv fix for Python
3.13, ideally "1.2.1"); locate the dependency entry containing the exact token
"python-dotenv==1.1.0" and replace it with the chosen version, then run your
dependency resolution / lockfile update (poetry lock or equivalent) and test
loads that use find_dotenv or dotenv.load_dotenv to confirm no regressions.

ℹ️ Review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ae3645d and 6321eb6.

⛔ Files ignored due to path filters (1)
  • uv.lock is excluded by !**/*.lock
📒 Files selected for processing (6)
  • .github/workflows/publish.yml
  • .github/workflows/tests.yml
  • CLAUDE.md
  • pyproject.toml
  • requirements.test.txt
  • scripts/semantic-version-release.sh
💤 Files with no reviewable changes (1)
  • requirements.test.txt

Replace pip/twine/build with uv across all CI workflows:
- Add dependency-groups dev in pyproject.toml, delete requirements.test.txt
- Use astral-sh/setup-uv@v5 + uv sync in tests.yml
- Use uv build and uv publish in publish.yml
- Use uvx for semantic-release in release script
- Update CLAUDE.md dev commands to use uv

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@danieljrc888 danieljrc888 merged commit 3c09b90 into main Mar 1, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant