Skip to content

ci: simplify workflows with uv - #1

Open
jakob1379 wants to merge 3 commits into
mainfrom
ci/uv-simplify
Open

ci: simplify workflows with uv#1
jakob1379 wants to merge 3 commits into
mainfrom
ci/uv-simplify

Conversation

@jakob1379

Copy link
Copy Markdown
Owner

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.yml drops 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 uvsetup-uv supplies the interpreter, so actions/setup-python is redundant; uv run syncs on demand, so the standalone uv sync step is too. Every job goes from 4-5 setup steps to 2.

- uses: actions/checkout@v4
- uses: astral-sh/setup-uv@v7
- name: Run PostgreSQL integration tests
  env: { … }
  run: uv run --extra postgres pytest tests/test_postgresql.py --timeout=120

Also: uv build replaces pip install build && python -m build, and UV_LOCKED at workflow level makes CI fail on a stale uv.lock.

ci(release): build the package with uv build — same swap in release.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's dist/sqlit_tui-${VERSION}.tar.gz lookup is unaffected.

ci: cut redundant workflow config — four deletions:

  • setup-uv v5 → v7, which defaults enable-cache to auto, removing 15 explicit lines. 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.
  • -v dropped from every pytest call — pyproject.toml already sets addopts = "-v".
  • The trailing docker stop/rm Cleanup steps in test-ssh/test-turso are gone. Runners are ephemeral, and the four other docker run jobs 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-level env and action defaults instead.

Behaviour note

The old jobs ran uv sync --group test --no-dev and then a bare uv run, which re-syncs the default (dev) group — so --no-dev never took effect and CI has always installed dev. That is preserved here. An earlier draft "fixed" it with UV_NO_DEV=1 and silently skipped the 11 tests/performance tests, since Faker lives in dev and the file skipifs itself away. Making --no-dev real needs Faker/pytest-benchmark moved into the test group — a pyproject.toml change, deliberately not bundled here.

Verification

actionlint clean on both files. Locally, with UV_LOCKED=1:

uv build                             → sqlit_tui-<ver>.tar.gz + .whl
uv run --no-dev python -c "…"        → CLI import OK
uv run pytest tests/test_sqlite.py   → 25 passed, 6 skipped
uv run --extra duckdb …test_duckdb   → 29 passed, 5 skipped
uv run pytest tests/ <12 ignores>    → 1756 passed, 420 skipped, 1 failed
uv lock --check                      → in sync, so UV_LOCKED is safe

The one failure, test_detect_strategy_pip_user_fallback, is pre-existing and environment-dependent — the probe reads real interpreter state and my machine reports externally-managed where it expects pip-user. Fails identically on unmodified main.

Left for separate PRs

  • The 13 near-identical DB jobs. A matrix would work (services: accepts matrix expressions) but four jobs use raw docker run, mssql needs a wait step, mariadb needs apt, firebird has no healthcheck. The resulting include: block is harder to read than 13 explicit jobs.
  • build builds the same py3-none-any wheel four times. Could collapse to one job and widen test-unit's matrix to all four versions instead — fewer jobs, more real coverage, but roughly double the unit-job wall time.
  • The 12-line --ignore list. tests/integration/ already exists and pytest.mark.integration is already declared in pyproject.toml; the DB test files use neither. Marking or moving them turns the list into -m "not integration".
  • softprops/action-gh-release@v1 in release.yml — actionlint flags it as too old to run (node16). Pre-existing, one-character fix, own PR.

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.
@coderabbitai

coderabbitai Bot commented Aug 10, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Summary by CodeRabbit

  • Chores
    • Updated continuous integration workflows to use streamlined Python environment and dependency management.
    • Improved build and command-line validation across supported Python configurations.
    • Updated database integration test execution to include required optional components.
    • Simplified the release packaging workflow with a modern, consistent build process.

Walkthrough

The CI workflow now uses locked uv environments, matrix-specific Python versions, and database extras for integration tests. The release workflow uses uv to build the package.

Changes

UV Workflow Migration

Layer / File(s) Summary
Core CI setup and checks
.github/workflows/ci.yml
CI uses setup-uv@v7, locked dependency resolution, matrix-specific Python settings, and uv run for builds, CLI checks, and tests.
Database integration job migration
.github/workflows/ci.yml
Database jobs use setup-uv@v7 and pass database-specific extras to uv run test commands.
Release build migration
.github/workflows/release.yml
The release job uses setup-uv@v5 with Python 3.12 and runs uv build.

Estimated code review effort: 3 (Moderate) | ~20 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely describes the main change: simplifying CI workflows with uv.
Description check ✅ Passed The description directly explains the workflow changes, preserved behavior, verification results, and remaining work.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches 💡 1
🛠️ Fix failing CI checks 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch ci/uv-simplify

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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

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

📥 Commits

Reviewing files that changed from the base of the PR and between 28d73ed and 27cdbb1.

📒 Files selected for processing (2)
  • .github/workflows/ci.yml
  • .github/workflows/release.yml

Comment thread .github/workflows/ci.yml
Comment on lines 15 to +28
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

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔒 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

Comment thread .github/workflows/ci.yml
Comment on lines 26 to +28
- 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

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔒 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

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔒 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 || true

Repository: 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:


🌐 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:


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

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