Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,11 @@ Every shared `prek` command runs through `tools/cooled_prek.sh`, which the `cool
passes `--config .pre-commit-config.yaml`. Without it, prek prefers a root `prek.toml` and also runs nested
configurations, which no guard checks.

Hook environments install under the same seven-day upload cutoff, with the repository's uv settings ignored. A package
with a `packages.<name>.uploaded-prior-to` exception in `[tool.nab]` is admitted up to that date in hook environments
too, so a hook dependency pinned to a release newer than the cutoff, such as `sphinx` for `docstrfmt`, needs the same
temporary exception the release lock uses. Delete the exception once the release is a week old.

## Start with a caller

The [release preparation workflow](.github/workflows/prepare-release.yaml) in this repository calls the reusable
Expand Down
3 changes: 3 additions & 0 deletions changelog.d/+cooled-prek-exceptions.change.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Admit the `[tool.nab]` per-package `uploaded-prior-to` exceptions in `cooled-prek` hook environments, so a hook
dependency pinned past the seven-day cutoff installs the same way as the release lock. Before, prepare failed on such a
pin.
39 changes: 39 additions & 0 deletions tests/cooled_prek/test_cooled_prek.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,3 +89,42 @@ def test_cooled_prek_isolates_hook_installs(tmp_path: Path) -> None:
"UV_NO_SOURCES": "1",
}
assert not leaked.keys() & environment.keys()


def test_cooled_prek_admits_nab_cutoff_exceptions(tmp_path: Path) -> None:
fake = tmp_path / "prek"
fake.write_text('#!/bin/sh\ncat "$UV_CONFIG_FILE" >config\n')
fake.chmod(0o755)
(tmp_path / "pyproject.toml").write_text(
'[tool.nab]\nuploaded-prior-to = "P7D"\npackages.sphinx.uploaded-prior-to = 2026-10-21T00:05:13Z\n'
'packages.release-creator.uploaded-prior-to = "2026-10-26T18:24:46Z"\npackages.uv.decision-order = "stable"\n'
)

subprocess.run(
[str(Path(__file__).resolve().parents[2] / "tools/cooled_prek.sh"), "install-hooks"],
cwd=tmp_path,
env=os.environ | {"PATH": f"{tmp_path}:{os.environ['PATH']}"},
check=True,
)

assert (tmp_path / "config").read_text().splitlines() == [
"[exclude-newer-package]",
'"release-creator" = "2026-10-26T18:24:46Z"',
'"sphinx" = "2026-10-21T00:05:13Z"',
]


def test_cooled_prek_without_exceptions_sets_no_config_file(tmp_path: Path) -> None:
fake = tmp_path / "prek"
fake.write_text('#!/bin/sh\nprintf "%s" "${UV_CONFIG_FILE-unset}" >config\n')
fake.chmod(0o755)
(tmp_path / "pyproject.toml").write_text('[tool.nab]\nuploaded-prior-to = "P7D"\n')

subprocess.run(
[str(Path(__file__).resolve().parents[2] / "tools/cooled_prek.sh"), "install-hooks"],
cwd=tmp_path,
env=os.environ | {"PATH": f"{tmp_path}:{os.environ['PATH']}", "UV_CONFIG_FILE": "/leak/uv.toml"},
check=True,
)

assert (tmp_path / "config").read_text() == "unset"
25 changes: 24 additions & 1 deletion tools/cooled_prek.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,28 @@ unset UV_CONFIG_FILE UV_INDEX UV_INDEX_URL UV_DEFAULT_INDEX UV_EXTRA_INDEX_URL
unset UV_FIND_LINKS UV_EXCLUDE_NEWER_PACKAGE
unset UV_INSECURE_HOST UV_SYSTEM_CERTS SSL_CERT_FILE SSL_CERT_DIR
export UV_EXCLUDE_NEWER="7 days" UV_NO_CONFIG=1 UV_NO_SOURCES=1
echo "Running prek $* with hook environments built under the 7 days cutoff, repository uv settings ignored"
# uv pip, which prek calls, reads per-package cutoffs only from a config file, so the [tool.nab] exceptions the
# release lock already admits are written to one that holds nothing else.
exceptions=$(
python3 -I - <<'PY'
import pathlib
import tomllib

path = pathlib.Path("pyproject.toml")
packages = tomllib.loads(path.read_text()).get("tool", {}).get("nab", {}).get("packages", {}) if path.is_file() else {}
for name, settings in sorted(packages.items()):
if (cutoff := settings.get("uploaded-prior-to")) is not None:
value = cutoff.isoformat().replace("+00:00", "Z") if hasattr(cutoff, "isoformat") else str(cutoff)
print(f'"{name}" = "{value}"')
PY
)
if [[ -n "$exceptions" ]]; then
config=$(mktemp)
printf '[exclude-newer-package]\n%s\n' "$exceptions" >"$config"
export UV_CONFIG_FILE="$config"
echo "Running prek $* with hook environments built under the 7 days cutoff, repository uv settings ignored," \
"[tool.nab] cutoff exceptions admitted: $(tr '\n' ' ' <<<"$exceptions")"
else
echo "Running prek $* with hook environments built under the 7 days cutoff, repository uv settings ignored"
fi
exec prek --config .pre-commit-config.yaml "$@"