CI and the release gate: uv is installed unpinned, and one Python of the three declared is tested #14

Closed
opened 2026-10-01 10:47:58 +00:00 by tiagoagueda · 0 comments
Owner

Found on 2026-09-29 in a read-only review of postulo-imap at cc09c6381, comparing its workflows with the core's.

Both workflows install whatever uv is newest on the day they run, which the core stopped doing in postulo/postulo#233, and both run the tests on Python 3.14 only although the package declares >=3.12. A uv release can therefore turn this repository red, or change what uv sync --locked installs, with no commit here; and nothing shows the plugin works on the two older Pythons the core supports and tests.

Related to postulo/postulo#233 (closed), which pinned uv in the core's workflows, pre-commit configuration and Dockerfile, and did not reach the plugin repositories.

  • Where:
    • .forgejo/workflows/ci.yml:45-48 and .forgejo/workflows/release.yml:38-41: curl -LsSf https://astral.sh/uv/install.sh | sh, the unversioned installer.
    • .forgejo/workflows/ci.yml:53 and .forgejo/workflows/release.yml:44: uv sync --locked --python 3.14, the only interpreter either workflow uses.
    • pyproject.toml:6: requires-python = ">=3.12".
  • What happens: the core's .forgejo/workflows/ci.yml names UV_VERSION: "0.12.17" once, installs https://astral.sh/uv/${UV_VERSION}/install.sh, and says why: "a lock file read by an unpinned tool is pinned only in name (#233)". Here the comment above uv sync --locked makes the same argument about the lock ("a resolution nobody reviewed") while the tool reading the lock is not chosen by anybody. When uv changes its lock revision or how it judges a lock stale, the core's CI is unaffected and this repository's CI and release gate pass or fail on a version no commit named. Separately, the core's test job runs a matrix of 3.12, 3.13 and 3.14; a plugin is installed into the core's environment, so a person running Postulo on 3.12 installs a plugin that was never run there.
  • Why it matters: the release gate is the last check before a tag, and it should not depend on the day it runs. The declared Python range is a promise the workflows do not check.
  • Fix: add env: UV_VERSION to both workflows with the version the core names, install the versioned installer, and note that it is bumped together with the core's. Add 3.12 and 3.13 legs to the test job (a matrix on --python, as in the core), or raise requires-python to what is tested. The same unversioned line is in the workflows of postulo-apprise, postulo-dav, postulo-helloworld, postulo-mcp and postulo-paperless, and the same single --python 3.14 in all of those but postulo-mcp; they are best changed together.

Done when

  • grep -rn "astral.sh/uv/install.sh" .forgejo/ finds nothing, and both workflows install the uv version the core's UV_VERSION names.
  • The test job in .forgejo/workflows/ci.yml runs on every Python that requires-python admits, or requires-python admits only what the job runs.
Found on 2026-09-29 in a read-only review of postulo-imap at cc09c6381, comparing its workflows with the core's. Both workflows install whatever uv is newest on the day they run, which the core stopped doing in postulo/postulo#233, and both run the tests on Python 3.14 only although the package declares `>=3.12`. A uv release can therefore turn this repository red, or change what `uv sync --locked` installs, with no commit here; and nothing shows the plugin works on the two older Pythons the core supports and tests. Related to postulo/postulo#233 (closed), which pinned uv in the core's workflows, pre-commit configuration and Dockerfile, and did not reach the plugin repositories. - **Where:** - `.forgejo/workflows/ci.yml:45-48` and `.forgejo/workflows/release.yml:38-41`: `curl -LsSf https://astral.sh/uv/install.sh | sh`, the unversioned installer. - `.forgejo/workflows/ci.yml:53` and `.forgejo/workflows/release.yml:44`: `uv sync --locked --python 3.14`, the only interpreter either workflow uses. - `pyproject.toml:6`: `requires-python = ">=3.12"`. - **What happens:** the core's `.forgejo/workflows/ci.yml` names `UV_VERSION: "0.12.17"` once, installs `https://astral.sh/uv/${UV_VERSION}/install.sh`, and says why: "a lock file read by an unpinned tool is pinned only in name (#233)". Here the comment above `uv sync --locked` makes the same argument about the lock ("a resolution nobody reviewed") while the tool reading the lock is not chosen by anybody. When uv changes its lock revision or how it judges a lock stale, the core's CI is unaffected and this repository's CI and release gate pass or fail on a version no commit named. Separately, the core's test job runs a matrix of 3.12, 3.13 and 3.14; a plugin is installed into the core's environment, so a person running Postulo on 3.12 installs a plugin that was never run there. - **Why it matters:** the release gate is the last check before a tag, and it should not depend on the day it runs. The declared Python range is a promise the workflows do not check. - **Fix:** add `env: UV_VERSION` to both workflows with the version the core names, install the versioned installer, and note that it is bumped together with the core's. Add 3.12 and 3.13 legs to the `test` job (a matrix on `--python`, as in the core), or raise `requires-python` to what is tested. The same unversioned line is in the workflows of postulo-apprise, postulo-dav, postulo-helloworld, postulo-mcp and postulo-paperless, and the same single `--python 3.14` in all of those but postulo-mcp; they are best changed together. ## Done when - `grep -rn "astral.sh/uv/install.sh" .forgejo/` finds nothing, and both workflows install the uv version the core's `UV_VERSION` names. - The `test` job in `.forgejo/workflows/ci.yml` runs on every Python that `requires-python` admits, or `requires-python` admits only what the job runs.
tiagoagueda added this to the 0.6.0 milestone 2026-10-01 10:47:58 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
Postulo/postulo-imap#14
No description provided.