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
7 changes: 6 additions & 1 deletion .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -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: ["*"]
Expand Down
3 changes: 2 additions & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
3 changes: 2 additions & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,8 @@ included), at `ghcr.io/scaleapi/agentenv-<name>:src-<hex>` 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
Expand Down
10 changes: 10 additions & 0 deletions tst/unit/test_release_infra_images.py
Original file line number Diff line number Diff line change
Expand Up @@ -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"])
Loading