This commit is contained in:
Mateo Wang 2026-10-28 08:26:59 -07:00 • committed by GitHub
commit 4a4e772679
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 120 additions and 14 deletions

9
.github/AGENTS.md vendored Normal file
View file

@ -0,0 +1,9 @@
# Checkout history
Use shallow checkouts by default. `actions/checkout` defaults to one commit, so omitting `fetch-depth` is fine. For comparisons, fetch only the required commits with `--no-tags --depth=1` and preserve the existing baseline semantics. Fetching two shallow endpoints does not make `git merge-base` work across missing ancestry
Use deeper checkout, `fetch-depth: 0`, or `--unshallow` only when the consuming command needs history. For new or changed exceptions, state the consumer and why a targeted fetch cannot preserve its behavior beside that checkout or fetch. Keep bounded retries and timeouts on network operations, and never skip a required check when its baseline is unavailable
Current exceptions are the depth-two parent diff in `test-linting.yml`, Linear's commit-history scan in `linear-release.yml`, and the historical GitGuardian repository scan in `test-linting.yml`. Do not remove release history or reduce secret-scanning coverage just to make checkout shallow
Mateo requested this default on 2026-10-27 after a full-history unit checkout timed out before tests started

View file

@ -543,7 +543,7 @@ jobs:
run: uv run --no-sync pytest -q --noconftest -p no:cacheprovider -c /dev/null tests/code_coverage_tests/test_workflow_job_name_collisions.py
- name: test_unit_passed_gate
run: uv run --no-sync pytest -q --noconftest -p no:cacheprovider -c /dev/null tests/code_coverage_tests/test_unit_passed_gate.py
run: uv run --no-sync pytest -q --noconftest -p no:cacheprovider -c /dev/null tests/code_coverage_tests/test_unit_passed_gate.py tests/code_coverage_tests/test_schema_compatibility_cli.py
- name: test_e2e_idp_stack
run: uv run --no-sync pytest -q --noconftest -p no:cacheprovider -c /dev/null tests/code_coverage_tests/test_e2e_idp_stack.py

View file

@ -956,13 +956,37 @@ jobs:
timeout-minutes: ${{ matrix.shard == 'db-and-spend' && 10 || 3 }}
with:
persist-credentials: false
fetch-depth: ${{ matrix.shard == 'db-and-spend' && '0' || '1' }}
fetch-depth: 1
- name: Detect relevant changes
id: changes
timeout-minutes: 2
uses: ./.github/actions/detect-changes
- name: Fetch schema comparison baseline
if: matrix.shard == 'db-and-spend' && steps.changes.outputs.decision != 'skip'
timeout-minutes: 3
env:
GH_TOKEN: ${{ github.token }}
REPO: ${{ github.repository }}
DEFAULT_BRANCH: ${{ github.event.repository.default_branch }}
CHECKED_OUT_SHA: ${{ github.sha }}
run: |
for attempt in 1 2 3; do
if baseline="$(gh api "repos/${REPO}/compare/${DEFAULT_BRANCH}...${CHECKED_OUT_SHA}?per_page=1" --jq '.merge_base_commit.sha')" \
&& [[ "$baseline" =~ ^[0-9a-f]{40}$ ]] \
&& git fetch --no-tags --depth=1 origin "$baseline"; then
printf 'SCHEMA_BASE_COMMIT=%s\n' "$baseline" >> "$GITHUB_ENV"
exit 0
fi
if [ "$attempt" -lt 3 ]; then
echo "Schema baseline fetch failed, retrying attempt $((attempt + 1))/3"
sleep "$((attempt * 5))"
fi
done
echo "::error::Could not resolve and fetch the schema baseline after 3 attempts"
exit 1
- name: Set up Python
if: steps.changes.outputs.decision != 'skip'
timeout-minutes: 3
@ -995,7 +1019,6 @@ jobs:
env:
RUST_BRIDGE_ARTIFACT: ${{ needs.rust-bridge.outputs.artifact }}
UNIT_SHARD: ${{ matrix.shard }}
SCHEMA_BASE_REF: origin/${{ github.event.repository.default_branch }}
run: |
diff -u model_prices_and_context_window.json litellm/model_prices_and_context_window_backup.json
if [ -z "$RUST_BRIDGE_ARTIFACT" ]; then
@ -1008,7 +1031,7 @@ jobs:
fi
uv run --no-sync python -c 'import os, sys; print(sys.version); assert f"{sys.version_info.major}.{sys.version_info.minor}" == os.environ["UV_PYTHON"]'
if [ "$UNIT_SHARD" = "db-and-spend" ]; then
uv run --no-sync python scripts/check_schema_compatibility.py --base-ref "$SCHEMA_BASE_REF"
uv run --no-sync python scripts/check_schema_compatibility.py --base-commit "$SCHEMA_BASE_COMMIT"
fi
- name: Cache Prisma binaries

View file

@ -7,14 +7,20 @@ import sys
from collections.abc import Iterator, Mapping
from pathlib import Path
from types import MappingProxyType
from typing import Final
from typing import Final, TypeAlias
from pydantic import TypeAdapter
from pydantic import BaseModel, ConfigDict, TypeAdapter
Schema = Mapping[str, Mapping[str, str]]
Schema: TypeAlias = Mapping[str, Mapping[str, str]]
MODELS: Final = re.compile(r"^[ \t]*model\s+(\w+)\s*\{(.*?)^[ \t]*\}", re.MULTILINE | re.DOTALL)
class _Options(BaseModel):
model_config = ConfigDict(frozen=True)
base_ref: str | None
base_commit: str | None
def parse_model_fields(schema: str) -> Schema:
def fields(body: str) -> Mapping[str, str]:
parts: Final = tuple(line.split() for line in body.splitlines())
@ -54,12 +60,20 @@ def check_breaking_changes(old_schema: Schema, new_schema: Schema) -> tuple[str,
def main() -> int:
parser: Final = argparse.ArgumentParser()
parser.add_argument("--base-ref", required=True)
options: Final = parser.parse_args()
base_ref: Final = TypeAdapter(str).validate_python(options.base_ref)
base: Final = subprocess.run(
("git", "merge-base", "HEAD", base_ref), capture_output=True, text=True, check=True
).stdout.strip()
baseline: Final = parser.add_mutually_exclusive_group(required=True)
baseline.add_argument("--base-ref")
baseline.add_argument("--base-commit")
options: Final = _Options.model_validate(vars(parser.parse_args()))
base: Final = (
options.base_commit
if options.base_commit is not None
else subprocess.run(
("git", "merge-base", "HEAD", TypeAdapter(str).validate_python(options.base_ref)),
capture_output=True,
text=True,
check=True,
).stdout.strip()
)
previous: Final = subprocess.run(
("git", "show", f"{base}:schema.prisma"), capture_output=True, text=True, check=True
).stdout
@ -69,7 +83,7 @@ def main() -> int:
if changes:
sys.stderr.write("\n".join(changes) + "\n")
return 1
sys.stdout.write(f"Schema compatibility passed against merge base {base}\n")
sys.stdout.write(f"Schema compatibility passed against baseline {base}\n")
return 0

View file

@ -0,0 +1,60 @@
import subprocess
import sys
from pathlib import Path
from typing import Final
import pytest
CHECKER: Final = Path(__file__).resolve().parents[2] / "scripts/check_schema_compatibility.py"
SCHEMA: Final = "model Item {\n id String @id\n label String?\n}\n"
def _git(root: Path, *args: str) -> str:
return subprocess.run(
("git", "-C", str(root), *args), capture_output=True, text=True, check=True, timeout=30
).stdout.strip()
@pytest.mark.parametrize("baseline_option", ("--base-ref", "--base-commit"))
@pytest.mark.parametrize(("schema", "expected"), ((SCHEMA, 0), ("model Item {\n id String @id\n}\n", 1)))
def test_schema_check_preserves_break_detection_with_or_without_history(
tmp_path: Path, schema: str, expected: int, baseline_option: str
) -> None:
source: Final = tmp_path / "source"
source.mkdir()
_git(source, "init", "--initial-branch=main")
_git(source, "config", "user.name", "Schema test")
_git(source, "config", "user.email", "schema-test@example.invalid")
_git(source, "config", "commit.gpgsign", "false")
(source / "schema.prisma").write_text(SCHEMA)
_git(source, "add", "schema.prisma")
_git(source, "commit", "-m", "baseline")
baseline: Final = _git(source, "rev-parse", "HEAD")
(source / "schema.prisma").write_text(schema)
_git(source, "add", "schema.prisma")
_git(source, "commit", "--allow-empty", "-m", "candidate")
checkout: Final = tmp_path / "checkout"
_git(tmp_path, "clone", "--depth=1", source.as_uri(), str(checkout))
_git(checkout, "fetch", "--no-tags", "--depth=1", "origin", baseline)
if baseline_option == "--base-ref":
_git(checkout, "fetch", "--unshallow", "origin", "main")
result: Final = subprocess.run(
(sys.executable, "-I", str(CHECKER), baseline_option, baseline),
cwd=checkout,
capture_output=True,
text=True,
check=False,
timeout=30,
)
assert result.returncode == expected, result.stdout + result.stderr
assert _git(checkout, "rev-parse", "--is-shallow-repository") == (
"true" if baseline_option == "--base-commit" else "false"
)
expected_output: Final = (
f"Schema compatibility passed against baseline {baseline}"
if expected == 0
else "Breaking: Field Item.label was removed"
)
assert expected_output in result.stdout + result.stderr