Adopt uv across dev/CI/release workflows and remove remaining Poetry packaging usage#168
Adopt uv across dev/CI/release workflows and remove remaining Poetry packaging usage#168Copilot wants to merge 11 commits into
uv across dev/CI/release workflows and remove remaining Poetry packaging usage#168Conversation
Agent-Logs-Url: https://github.com/tjorim/pyrail/sessions/f248dcc6-b823-4c90-95c9-a488f489331e Co-authored-by: tjorim <1294876+tjorim@users.noreply.github.com>
uv for Astral-aligned dev/CI workflows
|
@copilot why do we use |
Agent-Logs-Url: https://github.com/tjorim/pyrail/sessions/d20d316d-3e21-4815-be3b-1da896845a54 Co-authored-by: tjorim <1294876+tjorim@users.noreply.github.com>
Good call. I switched this to lockfile-based Warning Firewall rules blocked me from connecting to one or more addresses (expand for details)I tried to connect to the following addresses, but was blocked by firewall rules:
If you need me to access, download, or install something from one of these locations, you can either:
|
uv for Astral-aligned dev/CI workflowsuv with lockfile-based sync for Astral-aligned dev/CI workflows
|
@copilot any reason we still have poetry in our pyproject file? |
Yes — right now Poetry is still the package backend ( |
|
@copilot so... Why not switch that as well? We can't do that with UV? |
Agent-Logs-Url: https://github.com/tjorim/pyrail/sessions/6509c7b8-7cc7-4c4c-b33f-7d1d40160191 Co-authored-by: tjorim <1294876+tjorim@users.noreply.github.com>
Agent-Logs-Url: https://github.com/tjorim/pyrail/sessions/6509c7b8-7cc7-4c4c-b33f-7d1d40160191 Co-authored-by: tjorim <1294876+tjorim@users.noreply.github.com>
Agent-Logs-Url: https://github.com/tjorim/pyrail/sessions/6509c7b8-7cc7-4c4c-b33f-7d1d40160191 Co-authored-by: tjorim <1294876+tjorim@users.noreply.github.com>
Agent-Logs-Url: https://github.com/tjorim/pyrail/sessions/6509c7b8-7cc7-4c4c-b33f-7d1d40160191 Co-authored-by: tjorim <1294876+tjorim@users.noreply.github.com>
Agent-Logs-Url: https://github.com/tjorim/pyrail/sessions/6509c7b8-7cc7-4c4c-b33f-7d1d40160191 Co-authored-by: tjorim <1294876+tjorim@users.noreply.github.com>
Agent-Logs-Url: https://github.com/tjorim/pyrail/sessions/6509c7b8-7cc7-4c4c-b33f-7d1d40160191 Co-authored-by: tjorim <1294876+tjorim@users.noreply.github.com>
Agent-Logs-Url: https://github.com/tjorim/pyrail/sessions/6509c7b8-7cc7-4c4c-b33f-7d1d40160191 Co-authored-by: tjorim <1294876+tjorim@users.noreply.github.com>
Agent-Logs-Url: https://github.com/tjorim/pyrail/sessions/6509c7b8-7cc7-4c4c-b33f-7d1d40160191 Co-authored-by: tjorim <1294876+tjorim@users.noreply.github.com>
Yes, we can — and I’ve switched it. Poetry has now been removed from Warning Firewall rules blocked me from connecting to one or more addresses (expand for details)I tried to connect to the following addresses, but was blocked by firewall rules:
If you need me to access, download, or install something from one of these locations, you can either:
|
uv with lockfile-based sync for Astral-aligned dev/CI workflowsuv across dev/CI/release workflows and remove remaining Poetry packaging usage
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
📝 WalkthroughWalkthroughThis PR migrates the entire pyrail project from Poetry to Astral's ChangesPoetry to uv migration
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.github/workflows/lint.yml:
- Line 26: Replace the `uv sync` invocation that currently uses the
`--only-group dev` flag with `--group dev` so production dependencies are
included during type checking; specifically update the command string `uv sync
--only-group dev --locked` to `uv sync --group dev --locked` in the workflow
step that runs the type-check/lint job.
In @.github/workflows/publish.yml:
- Around line 62-68: The workflow step "Push version bump to main" should skip
committing/pushing when there are no staged changes; replace the unconditional
git commit/git push sequence by first checking the staged diff (e.g., using git
diff --staged --quiet or git diff --cached --quiet) and only run git commit -m
"Bump version to $VERSION" and git push origin HEAD:main if that check indicates
there are changes; keep the existing git config and git add pyproject.toml but
guard the commit/push behind the staged-diff check so the job continues when the
version rewrite is a no-op.
In @.github/workflows/test.yml:
- Line 26: The workflow currently runs "uv sync --only-group test --locked",
which installs only test dependencies and omits the package and its runtime
deps; update the GitHub Actions step to use "uv sync --group test --locked" so
the package itself and its runtime dependencies (e.g., aiohttp,
mashumaro[orjson]) are installed alongside the test group, preventing import
errors during tests.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: 24ce3ad0-04da-47e6-8090-500347226fd6
⛔ Files ignored due to path filters (1)
uv.lockis excluded by!**/*.lock
📒 Files selected for processing (7)
.devcontainer/devcontainer.json.github/workflows/build.yml.github/workflows/lint.yml.github/workflows/publish.yml.github/workflows/test.ymlREADME.mdpyproject.toml
| run: | | ||
| pip install poetry | ||
| poetry install | ||
| run: uv sync --only-group dev --locked |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Find the project configuration files
fd -e "pyproject.toml" -e "uv.lock" -e "requirements.txt" | head -20Repository: tjorim/pyrail
Length of output: 39
🏁 Script executed:
#!/bin/bash
# Look at the lint.yml workflow file
cat .github/workflows/lint.ymlRepository: tjorim/pyrail
Length of output: 593
🏁 Script executed:
#!/bin/bash
# Check if there's a test.yml mentioned in the review comment
cat .github/workflows/test.yml 2>/dev/null | head -60Repository: tjorim/pyrail
Length of output: 530
🏁 Script executed:
#!/bin/bash
# List all files in the repo to find pyproject.toml
git ls-files | grep -E "(pyproject|setup\.py|uv\.lock)" | head -20Repository: tjorim/pyrail
Length of output: 80
🏁 Script executed:
#!/bin/bash
# List root directory
ls -laRepository: tjorim/pyrail
Length of output: 1199
🏁 Script executed:
#!/bin/bash
# Read pyproject.toml
cat -n pyproject.tomlRepository: tjorim/pyrail
Length of output: 2061
🏁 Script executed:
#!/bin/bash
# Check if pyrail source code imports aiohttp or mashumaro
rg "(import aiohttp|from aiohttp|import mashumaro|from mashumaro)" pyrail/Repository: tjorim/pyrail
Length of output: 263
Replace --only-group dev with --group dev to include production dependencies during type checking.
The --only-group dev flag installs only the dev group (ruff, ty) and the package itself, excluding production dependencies. However, pyrail imports runtime dependencies (aiohttp and mashumaro) in its source code. Type checking with ty requires these dependencies to be available for import resolution; without them, type checking will fail or produce incomplete results.
Use uv sync --group dev --locked instead to include both production and dev dependencies.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/lint.yml at line 26, Replace the `uv sync` invocation that
currently uses the `--only-group dev` flag with `--group dev` so production
dependencies are included during type checking; specifically update the command
string `uv sync --only-group dev --locked` to `uv sync --group dev --locked` in
the workflow step that runs the type-check/lint job.
| - name: Push version bump to main | ||
| run: | | ||
| git config user.name "GitHub Actions" | ||
| git config user.email "actions@github.com" | ||
| git add pyproject.toml poetry.lock | ||
| git add pyproject.toml | ||
| git commit -m "Bump version to $VERSION" | ||
| git push origin HEAD:main # Push from detached HEAD directly to main |
There was a problem hiding this comment.
Skip the commit when the version rewrite is a no-op.
If the tag already matches [project].version, git commit fails with “nothing to commit” and the release stops before uv publish runs. Guard the commit/push behind a staged-diff check.
Proposed fix
- name: Push version bump to main
run: |
git config user.name "GitHub Actions"
git config user.email "actions@github.com"
git add pyproject.toml
- git commit -m "Bump version to $VERSION"
- git push origin HEAD:main # Push from detached HEAD directly to main
+ if git diff --cached --quiet; then
+ echo "pyproject.toml already matches $VERSION; skipping commit"
+ else
+ git commit -m "Bump version to $VERSION"
+ git push origin HEAD:main # Push from detached HEAD directly to main
+ fi📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| - name: Push version bump to main | |
| run: | | |
| git config user.name "GitHub Actions" | |
| git config user.email "actions@github.com" | |
| git add pyproject.toml poetry.lock | |
| git add pyproject.toml | |
| git commit -m "Bump version to $VERSION" | |
| git push origin HEAD:main # Push from detached HEAD directly to main | |
| - name: Push version bump to main | |
| run: | | |
| git config user.name "GitHub Actions" | |
| git config user.email "actions@github.com" | |
| git add pyproject.toml | |
| if git diff --cached --quiet; then | |
| echo "pyproject.toml already matches $VERSION; skipping commit" | |
| else | |
| git commit -m "Bump version to $VERSION" | |
| git push origin HEAD:main # Push from detached HEAD directly to main | |
| fi |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/publish.yml around lines 62 - 68, The workflow step "Push
version bump to main" should skip committing/pushing when there are no staged
changes; replace the unconditional git commit/git push sequence by first
checking the staged diff (e.g., using git diff --staged --quiet or git diff
--cached --quiet) and only run git commit -m "Bump version to $VERSION" and git
push origin HEAD:main if that check indicates there are changes; keep the
existing git config and git add pyproject.toml but guard the commit/push behind
the staged-diff check so the job continues when the version rewrite is a no-op.
| run: | | ||
| pip install poetry | ||
| poetry install | ||
| run: uv sync --only-group test --locked |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Check if pyrail declares runtime dependencies in pyproject.toml
echo "=== Checking for runtime dependencies in [project.dependencies] ==="
if grep -A 20 '^\[project\.dependencies\]' pyproject.toml | grep -v '^#' | grep -v '^\[' | grep -q '^\S'; then
echo "✗ Runtime dependencies found:"
grep -A 20 '^\[project\.dependencies\]' pyproject.toml | grep -v '^#' | grep -v '^\[' | grep '^\S'
echo ""
echo "CONCERN: --only-group test may exclude these dependencies, breaking tests."
else
echo "✓ No runtime dependencies declared"
fi
echo ""
echo "=== Checking for runtime dependencies in [project] dependencies array ==="
python3 << 'EOF'
import tomllib
with open('pyproject.toml', 'rb') as f:
data = tomllib.load(f)
deps = data.get('project', {}).get('dependencies', [])
if deps:
print(f"✗ Runtime dependencies found: {deps}")
print("\nCONCERN: --only-group test may exclude these dependencies, breaking tests.")
else:
print("✓ No runtime dependencies in dependencies array")
EOFRepository: tjorim/pyrail
Length of output: 402
🏁 Script executed:
cat pyproject.tomlRepository: tjorim/pyrail
Length of output: 1620
🏁 Script executed:
# Check the structure of dependency groups and how they're defined
python3 << 'EOF'
import tomllib
with open('pyproject.toml', 'rb') as f:
data = tomllib.load(f)
print("=== Project Dependencies (runtime) ===")
runtime_deps = data.get('project', {}).get('dependencies', [])
print(runtime_deps if runtime_deps else "None")
print("\n=== Dependency Groups ===")
dep_groups = data.get('dependency-groups', {})
if dep_groups:
for group_name, deps in dep_groups.items():
print(f"\n[{group_name}]")
for dep in deps:
print(f" {dep}")
else:
print("No dependency-groups found")
print("\n=== Check for [project.optional-dependencies] ===")
opt_deps = data.get('project', {}).get('optional-dependencies', {})
if opt_deps:
for group_name, deps in opt_deps.items():
print(f"\n[{group_name}]")
for dep in deps:
print(f" {dep}")
else:
print("None")
EOFRepository: tjorim/pyrail
Length of output: 385
🌐 Web query:
uv sync --only-group behavior local package dependencies
💡 Result:
In uv, uv sync --only-group <name> installs only the dependencies from the specified dependency group(s), omitting the project itself. The semantics match --only-dev: “the project will not be included” and --only-group also excludes default groups [1][2].\n\nHowever, when your dependency graph includes local package dependencies, uv may still need to evaluate/build packages outside the selected group during resolution/lockfile creation, because it must compute dependencies transitively and/or build metadata. uv’s own maintainers and issue reports indicate that even when a group is excluded, uv can still fetch/build to compute dependencies (and those packages may be “downloaded and tried to build” even if not ultimately installed) [3][4][5].\n\nKey takeaways for “local package dependencies”:\n1) “Only-group” controls what ends up installed; it does not necessarily prevent uv from resolving/inspecting other parts of the dependency graph during lockfile/resolution.\n- uv’s docs describe exclusion of the project itself, and exclusion of default groups for --only-group [1][2].\n- Issue reports show cases where uv still evaluates or downloads/builds packages from excluded groups or sources while computing dependency information [3][5].\n\n2) If you want to avoid re-resolving/evaluating after the lockfile is created, use --frozen (or otherwise rely on an up-to-date uv.lock). Maintainers note that uv will resolve to update the lockfile unless you freeze it [6].\n\nPractical guidance:\n- If you run uv sync --only-group <grp> and you observe local-path dependencies getting built/evaluated that “shouldn’t be there,” that is likely part of resolution/metadata evaluation, not necessarily final installation.\n- For CI/docker-style installs where you want deterministic behavior and minimal evaluation, generate uv.lock once, then use uv sync --frozen --only-group <grp>.
Citations:
- 1: https://docs.astral.sh/uv/concepts/projects/sync/
- 2: https://github.com/astral-sh/uv/blob/262a50bb/docs/concepts/projects/sync.md
- 3: uv sync includes packages from excluded dependency group when using
--no-group/--only-groupastral-sh/uv#16396 - 4: uv run with only a dependency-group astral-sh/uv#8771
- 5: uv sync --only-group and --no-extra still evaluates other package sources not specified, source = path astral-sh/uv#11675
- 6: Dependency resolution: unclear behaviour of
--only-groupastral-sh/uv#9211
Use uv sync --group test --locked to include the package and its runtime dependencies.
The --only-group test flag installs only the test dependency group while omitting the project itself and its runtime dependencies. Since pyrail declares runtime dependencies (aiohttp>=3.13.5,<4.0.0 and mashumaro[orjson]>=3.21,<4.0.0), the tests will fail with import errors when the package tries to import these modules.
Change to uv sync --group test --locked to ensure both the package and its runtime dependencies are installed alongside the test dependencies.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/test.yml at line 26, The workflow currently runs "uv sync
--only-group test --locked", which installs only test dependencies and omits the
package and its runtime deps; update the GitHub Actions step to use "uv sync
--group test --locked" so the package itself and its runtime dependencies (e.g.,
aiohttp, mashumaro[orjson]) are installed alongside the test group, preventing
import errors during tests.
The project already uses Astral tools (
ruff,ty) but still executed parts of development and release workflows through Poetry. This PR completes the migration touv-based workflows and removes remaining Poetry packaging usage so linting, typing, testing, building, and publishing are aligned.CI execution moved from Poetry to
uvlint.ymlto install/run tooling viauv:uv sync --only-group dev --lockeduv run ruff check .uv run ty check .test.ymlto install/run test dependencies viauv:uv sync --only-group test --lockeduv run pytestbuild.ymlto build distributions withuv build.Devcontainer tooling aligned with
uvuvfeature.postCreateCommandfrompoetry installto lockfile-based sync:uv sync --all-groups --lockedLockfile and metadata for reproducible environments
uv.lock.[project]and[dependency-groups]metadata inpyproject.tomlsouvcan lock/sync dev and test groups.Packaging backend migrated off Poetry
[tool.poetry*]sections frompyproject.toml.[build-system]frompoetry-coretohatchling.pyrailmodule.Release publishing workflow migrated from Poetry to
uvpublish.ymlto use:uv sync --lockeduv builduv publishpoetry version/lockwith a guarded inline update of[project].versionfrom the tag-derivedVERSION.VERSIONand strict single-substitution checks before committing the version bump.Developer docs updated to match new commands
uv run ...for:tytype checksuv sync --all-groups --lockeduv run ruff check ..Summary by CodeRabbit
Chores
Documentation