ci: simplify workflows with uv - #1
Conversation
setup-uv provides the interpreter, so actions/setup-python is redundant; uv run syncs the environment on demand, so the separate uv sync step is too. Every job drops from 4-5 setup steps to 2. - drop actions/setup-python (setup-uv's python-version replaces it) - fold "Install dependencies" into the test step via uv run --extra - uv build instead of pip install build && python -m build - UV_LOCKED at workflow level: CI now fails if uv.lock is stale - enable-cache on setup-uv Behaviour is unchanged: the old jobs ran `uv sync --group test --no-dev` and then a bare `uv run`, which re-synced the default (dev) group anyway, so dev is what CI has always installed. The build job keeps --no-dev since it only ever installed runtime deps.
Drops actions/setup-python and the pip install build bootstrap. Same
backend, same PEP 625 artifact names, so the AUR job's
dist/sqlit_tui-${VERSION}.tar.gz lookup is unaffected.
Four deletions, no behaviour change: - setup-uv v5 -> v7, which defaults enable-cache to "auto" (on for GitHub-hosted runners), so 15 explicit enable-cache lines go away. v7 is the newest moving major tag that actually exists; v8/v9 are published only as full version tags. - UV_PYTHON at workflow level, overridden per matrix job, replaces 15 copies of setup-uv's python-version input. uv provisions the interpreter either way. - Drop -v from every pytest call; pyproject already sets addopts = "-v". - Drop the trailing "docker stop/rm" Cleanup steps from test-ssh and test-turso. Runners are ephemeral, and the four other docker-run jobs never had them.
📝 WalkthroughSummary by CodeRabbit
WalkthroughThe CI workflow now uses locked ChangesUV Workflow Migration
Estimated code review effort: 3 (Moderate) | ~20 minutes 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches 💡 1🛠️ Fix failing CI checks 💡
🧪 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/ci.yml:
- Around line 26-28: Update the workflow action references for actions/checkout
and astral-sh/setup-uv to use full immutable commit SHAs instead of mutable
version tags, and configure or use the repository’s established action pinning
update tool to maintain these SHA pins.
- Around line 15-28: Restrict the workflow token by adding workflow-level
permissions with contents: read, and update every actions/checkout step to set
persist-credentials: false. Apply both changes across the CI workflow without
altering the existing build matrix or setup steps.
In @.github/workflows/release.yml:
- Line 54: Update the setup-uv action step in the release workflow from
astral-sh/setup-uv@v5 to the intended v7 release, pinned using that release’s
full immutable commit SHA instead of a mutable tag.
🪄 Autofix
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: Organization UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: a02e3595-d0e6-4581-aa85-1de9c0412299
📒 Files selected for processing (2)
.github/workflows/ci.yml.github/workflows/release.yml
| jobs: | ||
| build: | ||
| runs-on: ubuntu-latest | ||
| strategy: | ||
| matrix: | ||
| python-version: ["3.10", "3.11", "3.12", "3.13"] | ||
|
|
||
| env: | ||
| UV_PYTHON: ${{ matrix.python-version }} | ||
|
|
||
| steps: | ||
| - uses: actions/checkout@v4 | ||
|
|
||
| - name: Set up Python ${{ matrix.python-version }} | ||
| uses: actions/setup-python@v5 | ||
| with: | ||
| python-version: ${{ matrix.python-version }} | ||
|
|
||
| - name: Install dependencies | ||
| run: | | ||
| python -m pip install --upgrade pip | ||
| pip install build | ||
| pip install -e . | ||
| - uses: astral-sh/setup-uv@v7 |
There was a problem hiding this comment.
🔒 Security & Privacy | 🟠 Major | ⚡ Quick win
Restrict the workflow token and remove persisted checkout credentials.
Default permissions can grant more access than these build and test jobs need. actions/checkout also persists the token in local Git configuration. Build and test processes can read that credential.
Set workflow permissions to contents: read. Set persist-credentials: false on every checkout step.
Proposed fix
env:
UV_LOCKED: "1"
UV_PYTHON: "3.12"
+permissions:
+ contents: read
+
jobs:
build:
@@
- - uses: actions/checkout@v4
+ - uses: actions/checkout@v4
+ with:
+ persist-credentials: false🧰 Tools
🪛 zizmor (1.29.0)
[warning] 26-26: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false
(artipacked)
[error] 26-26: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)
(unpinned-uses)
[error] 28-28: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)
(unpinned-uses)
[info] 16-16: workflow or action definition without a name (anonymous-definition): this job
(anonymous-definition)
🤖 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/ci.yml around lines 15 - 28, Restrict the workflow token
by adding workflow-level permissions with contents: read, and update every
actions/checkout step to set persist-credentials: false. Apply both changes
across the CI workflow without altering the existing build matrix or setup
steps.
Source: Linters/SAST tools
| - uses: actions/checkout@v4 | ||
|
|
||
| - name: Set up Python ${{ matrix.python-version }} | ||
| uses: actions/setup-python@v5 | ||
| with: | ||
| python-version: ${{ matrix.python-version }} | ||
|
|
||
| - name: Install dependencies | ||
| run: | | ||
| python -m pip install --upgrade pip | ||
| pip install build | ||
| pip install -e . | ||
| - uses: astral-sh/setup-uv@v7 |
There was a problem hiding this comment.
🔒 Security & Privacy | 🟠 Major | ⚡ Quick win
Pin GitHub Actions to commit SHAs.
actions/checkout@v4 and astral-sh/setup-uv@v7 use mutable tags. Pin every action reference to a full commit SHA, and use an update tool to maintain those pins.
🧰 Tools
🪛 zizmor (1.29.0)
[warning] 26-26: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false
(artipacked)
[error] 26-26: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)
(unpinned-uses)
[error] 28-28: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)
(unpinned-uses)
🤖 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/ci.yml around lines 26 - 28, Update the workflow action
references for actions/checkout and astral-sh/setup-uv to use full immutable
commit SHAs instead of mutable version tags, and configure or use the
repository’s established action pinning update tool to maintain these SHA pins.
Source: Linters/SAST tools
|
|
||
| - name: Set up Python | ||
| uses: actions/setup-python@v5 | ||
| - uses: astral-sh/setup-uv@v5 |
There was a problem hiding this comment.
🔒 Security & Privacy | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== files =="
git ls-files '.github/workflows/*' || true
echo "== release.yml =="
cat -n .github/workflows/release.yml 2>/dev/null | sed -n '1,90p' || true
echo "== ci.yml relevant setup-uv lines =="
if [ -f .github/workflows/ci.yml ]; then
rg -n "astral-sh/setup-uv|setup-uv|uv build|disable-cache|build-hashes" .github/workflows/ci.yml -C 3
fi
echo "== search setup-uv references =="
rg -n "astral-sh/setup-uv@|setup-uv@|uv build" .github/workflows || trueRepository: jakob1379/sqlit
Length of output: 6985
🌐 Web query:
Astral setup-uv docs GitHub integration pin commit SHA enable-cache
💡 Result:
To use the official astral-sh/setup-uv GitHub Action, it is standard practice to pin the action to a specific commit SHA to ensure reproducible builds [1][2]. Caching Configuration: The setup-uv action includes built-in support for persisting the uv cache using the enable-cache input [3][4][2]. 1. Enabling Cache: Set enable-cache to true [1][2]. - This input accepts: true, false, or auto (the default, which automatically enables caching on GitHub-hosted runners and disables it on self-hosted runners) [3][5]. 2. Customization: You can further control caching with additional inputs: - cache-dependency-glob: Defines which files (e.g., pyproject.toml, uv.lock) trigger a cache invalidation when changed [3][4]. - cache-suffix: Adds an optional suffix to the cache key [3][4]. - prune-cache: Set to true if you wish to prune the uv cache before saving it to the GitHub Actions cache [3][4]. Example Usage: - name: Install uv uses: astral-sh/setup-uv@c771a70 # v9.0.0 with: enable-cache: true cache-dependency-glob: "/pyproject.toml" When enabled, the action automatically manages the UV_CACHE_DIR environment variable to store the cache [4][6]. If you require manual control, you can alternatively use the standard actions/cache action, though the built-in setup-uv implementation is generally recommended for simplicity [1][2].
Citations:
- 1: https://docs.astral.sh/uv/guides/integration/github/index.md
- 2: https://docs.astral.sh/uv/guides/integration/github/
- 3: https://github.com/astral-sh/setup-uv?tab=readme-ov-file
- 4: https://github.com/astral-sh/setup-uv/blob/main/docs/caching.md
- 5: https://github.com/astral-sh/setup-uv
- 6: https://github.com/astral-sh/setup-uv/blob/main/docs/environment-and-tools.md
🌐 Web query:
astral-sh/setup-uv v7 commit SHA
💡 Result:
The astral-sh/setup-uv version v7.0.0 was released on October 7, 2025 [1]. As a release tag, v7.0.0 is associated with a specific commit in the repository's history, which can be viewed via the official GitHub releases page [1][2]. Please note that in the context of GitHub Actions, using a version tag (e.g., v7.0.0) is generally considered mutable, as tags can be moved. For production workflows, it is recommended to pin to a specific commit SHA to ensure immutability and security [3]. While there is no single "v7" commit (as v7 evolved through multiple minor releases like v7.4.0, v7.5.0, and v7.6.0) [2][4][5][6], you can identify the exact commit SHA for any specific v7 tag by viewing the tag's page on GitHub [1].
Citations:
- 1: https://github.com/astral-sh/setup-uv/releases/tag/v7.0.0
- 2: https://github.com/astral-sh/setup-uv/releases
- 3: https://github.com/astral-sh/setup-uv/releases/tag/v8.0.0
- 4: https://github.com/astral-sh/setup-uv/releases/tag/v7.6.0
- 5: https://github.com/astral-sh/setup-uv/releases/tag/v7.5.0
- 6: https://github.com/astral-sh/setup-uv/releases/tag/v7.4.0
Use the intended setup-uv v7 action and pin it to an immutable commit SHA.
.github/workflows/release.yml still uses astral-sh/setup-uv@v5, while CI uses @v7 and this workflow should not rely on the mutable tag. Replace it with the full commit SHA for the intended v7 release.
🧰 Tools
🪛 zizmor (1.29.0)
[error] 54-54: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)
(unpinned-uses)
[error] 54-54: runtime artifacts potentially vulnerable to a cache poisoning attack (cache-poisoning): enables caching by default
(cache-poisoning)
🤖 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/release.yml at line 54, Update the setup-uv action step in
the release workflow from astral-sh/setup-uv@v5 to the intended v7 release,
pinned using that release’s full immutable commit SHA instead of a mutable tag.
Source: Linters/SAST tools
Reimplementation of the CI half of Maxteabag#157, which was closed as "several separate ideas bundled together". Split into focused commits so they can go upstream one at a time.
ci.ymldrops from 607 to 486 lines with no change in what CI covers. Job names are unchanged, so required status checks keep matching.Commits
ci: drive CI entirely through uv—setup-uvsupplies the interpreter, soactions/setup-pythonis redundant;uv runsyncs on demand, so the standaloneuv syncstep is too. Every job goes from 4-5 setup steps to 2.Also:
uv buildreplacespip install build && python -m build, andUV_LOCKEDat workflow level makes CI fail on a staleuv.lock.ci(release): build the package with uv build— same swap inrelease.yml. Nothing else in that workflow is touched; publish and AUR are left alone deliberately. Same backend, same PEP 625 artifact names, so the AUR job'sdist/sqlit_tui-${VERSION}.tar.gzlookup is unaffected.ci: cut redundant workflow config— four deletions:setup-uvv5 → v7, which defaultsenable-cachetoauto, removing 15 explicit lines. v7 is the newest moving major tag that actually exists; v8/v9 are published only as full version tags.UV_PYTHONat workflow level (overridden per matrix job) replaces 15 copies of setup-uv'spython-versioninput.-vdropped from every pytest call —pyproject.tomlalready setsaddopts = "-v".docker stop/rmCleanup steps intest-ssh/test-tursoare gone. Runners are ephemeral, and the four otherdocker runjobs never had them.What Maxteabag#157 got wrong
Its dedup relied on YAML anchors (
&checkout-step/*checkout-step). GitHub Actions doesn't expand aliases, so that approach could never have worked. This PR gets the deduplication from workflow-levelenvand action defaults instead.Behaviour note
The old jobs ran
uv sync --group test --no-devand then a bareuv run, which re-syncs the default (dev) group — so--no-devnever took effect and CI has always installeddev. That is preserved here. An earlier draft "fixed" it withUV_NO_DEV=1and silently skipped the 11tests/performancetests, sinceFakerlives indevand the fileskipifs itself away. Making--no-devreal needsFaker/pytest-benchmarkmoved into thetestgroup — apyproject.tomlchange, deliberately not bundled here.Verification
actionlintclean on both files. Locally, withUV_LOCKED=1:The one failure,
test_detect_strategy_pip_user_fallback, is pre-existing and environment-dependent — the probe reads real interpreter state and my machine reportsexternally-managedwhere it expectspip-user. Fails identically on unmodifiedmain.Left for separate PRs
services:accepts matrix expressions) but four jobs use rawdocker run, mssql needs a wait step, mariadb needs apt, firebird has no healthcheck. The resultinginclude:block is harder to read than 13 explicit jobs.buildbuilds the samepy3-none-anywheel four times. Could collapse to one job and widentest-unit's matrix to all four versions instead — fewer jobs, more real coverage, but roughly double the unit-job wall time.--ignorelist.tests/integration/already exists andpytest.mark.integrationis already declared inpyproject.toml; the DB test files use neither. Marking or moving them turns the list into-m "not integration".softprops/action-gh-release@v1inrelease.yml— actionlint flags it as too old to run (node16). Pre-existing, one-character fix, own PR.