diff --git a/.github/dependabot.yml b/.github/dependabot.yml index bd63201a..34cc5e0c 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -31,8 +31,10 @@ updates: groups: npm-minor-and-patch: update-types: ["minor", "patch"] - # The infra images the release publishes. Each base is pinned by digest, and a release rebuilds an image only when its + # The images the release publishes. Each base is pinned by digest, and a release rebuilds an image only when its # sources change, so a bump here is what picks up a base's fixes: the next release builds and publishes the image. + # Only its fixes: a new digest or patch release of the version it's on. A major or minor version (postgres 16 to 18, + # python 3.12 to 3.15) is an upgrade, made by hand with whatever the images run on it. - package-ecosystem: "docker" directories: - "/src/agent_env/env/gateway" @@ -42,6 +44,9 @@ updates: schedule: interval: "weekly" open-pull-requests-limit: 5 + ignore: + - dependency-name: "*" + update-types: ["version-update:semver-major", "version-update:semver-minor"] groups: infra-base-images: patterns: ["*"] diff --git a/AGENTS.md b/AGENTS.md index db9a5064..240e6413 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -285,7 +285,8 @@ Its jobs that run agent-env (`.github/scripts/infra_images.py`) hold no token th images or publish to PyPI install nothing and check what they're handed (`.github/scripts/infra_build.py`, standard library and the docker CLI only). Actions are pinned to commit SHAs; Dependabot updates them, the pinned uv, `uv.lock`, the UI's npm packages and -the infra images' base images, each pinned by digest so that a bump rebuilds and republishes the image. +the infra images' base images, each pinned by digest so that a bump rebuilds and republishes the image; Dependabot +proposes only a base's digest and patch updates, and a major or minor upgrade is made by hand. ## Conventions diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 9a802f62..10c77d64 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -94,7 +94,8 @@ included), at `ghcr.io/scaleapi/agentenv-:src-` for linux/amd64 and linux/arm64, where the tag is the build context's source digest, so an unchanged Dockerfile is not built again. The Claude Code image installs the `agentenv-framework-protocol` its release pins, which is one of its sources, so each release builds it again, once the protocol is on PyPI and before `agentenv-framework` is published. -Each of them pins its base images by digest, and Dependabot bumps those pins, so a base's fixes reach the published +Each of them pins its base images by digest, and Dependabot bumps those pins within each base's major and minor +version (an upgrade, such as postgres 16 to 18, is made by hand), so a base's fixes reach the published image: a bump changes the sources, and the next release builds it again. Installs pull them instead of building the infra images: a run on local stores registers a kind's images when GHCR has every one for the sources installed, by the digest the wheel records or, with no record, the one GHCR serves, and diff --git a/tst/unit/test_release_infra_images.py b/tst/unit/test_release_infra_images.py index 58854d71..bdd26182 100644 --- a/tst/unit/test_release_infra_images.py +++ b/tst/unit/test_release_infra_images.py @@ -208,3 +208,13 @@ def test_every_infra_image_pins_its_bases_by_digest_and_dependabot_bumps_them(): if ref not in stages] assert bases and all(re.search(r"@sha256:[0-9a-f]{64}$", ref) for ref in bases), (image.name, bases) assert f"/{image.dockerfile.parent.relative_to(REPO)}" in docker["directories"], image.name + + +def test_dependabot_proposes_a_bases_fixes_and_never_an_upgrade(): + """A base's digest and patch updates are its fixes; its next major or minor version (postgres 16 to 18) changes what + the images run on, and is made by hand.""" + dependabot = yaml.safe_load((REPO / ".github" / "dependabot.yml").read_text()) + (docker,) = [update for update in dependabot["updates"] if update["package-ecosystem"] == "docker"] + + assert {"dependency-name": "*", "update-types": ["version-update:semver-major", "version-update:semver-minor"]} in ( + docker["ignore"])