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
8 changes: 7 additions & 1 deletion .github/workflows/dependency-updates.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,12 @@ jobs:
working-directory: py
run: python scripts/update-matrix-latest.py

- name: Advance uv exclude-newer cutoff
working-directory: py
run: |
cutoff=$(date -u +%Y-%m-%dT%H:%M:%SZ)
sed -i -E "s/^exclude-newer = .*/exclude-newer = \"$cutoff\"/" pyproject.toml

- name: Upgrade lockfile
working-directory: py
run: uv lock --upgrade
Expand Down Expand Up @@ -57,7 +63,7 @@ jobs:
with:
title: "chore(deps): weekly dependency update"
body: |
Automated weekly dependency update via `python scripts/update-matrix-latest.py && uv lock --upgrade`.
Automated weekly dependency update via `python scripts/update-matrix-latest.py`, advancing the `uv` `exclude-newer` cutoff, and `uv lock --upgrade`.

${{ steps.labels.outputs.needs_rerecord == 'true' && '⚠️ **Provider SDK packages changed.** A human needs to re-record cassettes locally before merging.' || '✅ Only test infrastructure deps changed. Safe to merge if CI passes.' }}
branch: deps/weekly-update-${{ steps.date.outputs.date }}
Expand Down
16 changes: 11 additions & 5 deletions py/noxfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@

_PYPROJECT = tomllib.loads((pathlib.Path(__file__).parent / "pyproject.toml").read_text())
_MATRIX = _PYPROJECT.get("tool", {}).get("braintrust", {}).get("matrix", {})
_UV_EXCLUDE_NEWER = _PYPROJECT["tool"]["uv"]["exclude-newer"]


_PROJECT_DIR = str(pathlib.Path(__file__).parent)
Expand Down Expand Up @@ -143,7 +144,7 @@ def _install_group_locked(
# all configured indexes for each exact version. Without this,
# uv may stop at PyTorch's index for unrelated packages.
install_args.extend(("--index-strategy", "unsafe-best-match"))
session.install(*install_args, silent=SILENT_INSTALLS)
_session_install(session, *install_args, silent=SILENT_INSTALLS)
finally:
os.unlink(req_file)

Expand Down Expand Up @@ -171,7 +172,7 @@ def _install_matrix_dep(session: nox.Session, prefix: str, version: str, constra
if not req:
session.error(f"Missing matrix key {key!r} in [tool.braintrust.matrix.{prefix}]")
if constraint_group is None:
session.install(req, silent=SILENT_INSTALLS)
_session_install(session, req, silent=SILENT_INSTALLS)
return

constraints = _PYPROJECT.get("dependency-groups", {}).get(constraint_group, [])
Expand All @@ -180,7 +181,12 @@ def _install_matrix_dep(session: nox.Session, prefix: str, version: str, constra
with tempfile.NamedTemporaryFile(mode="w", suffix=".txt") as constraint_file:
constraint_file.write("\n".join(constraints))
constraint_file.flush()
session.install(req, "-c", constraint_file.name, silent=SILENT_INSTALLS)
_session_install(session, req, "-c", constraint_file.name, silent=SILENT_INSTALLS)


def _session_install(session: nox.Session, *args, **kwargs) -> None:
"""Install packages with the project's reproducibility cutoff."""
session.install("--exclude-newer", _UV_EXCLUDE_NEWER, *args, **kwargs)


# ---------------------------------------------------------------------------
Expand Down Expand Up @@ -906,7 +912,7 @@ def test_types(session):
def pylint(session):
# Install the project and locked base/lint dependencies, then vendor SDKs
# at their matrix latest versions for import coverage.
session.install(".")
_session_install(session, ".")
_install_group_locked(session, "test", "lint")
# Provider latest pins intentionally coexist in the lint environment even
# when their dependency metadata conflicts. Validate the lock-resolved base
Expand Down Expand Up @@ -958,7 +964,7 @@ def _install_test_deps(session, *groups):
# spawned by ``verify_autoinstrument_script`` -- picks up site-packages
# rather than the source tree, so it would silently exercise the code from
# whenever the venv was last built.
session.install(*([_get_braintrust_wheel()] if install_wheel else ["-e", "."]))
_session_install(session, *([_get_braintrust_wheel()] if install_wheel else ["-e", "."]))

# Install base test deps (pytest, pytest-asyncio, pytest-vcr) from the
# lockfile so transitive deps are pinned and reproducible.
Expand Down
1 change: 1 addition & 0 deletions py/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,7 @@ explicit = true
# ---------------------------------------------------------------------------

[tool.uv]
exclude-newer = "2026-10-09T00:00:00Z"
conflicts = [
# Groups that pin or transitively require conflicting openai versions.
[
Expand Down
Loading
Loading