Added a new CI job that validates all built-in default images exist#40
Conversation
📝 WalkthroughWalkthroughAdds a new CI job "default-images" that runs a Python script to validate built-in default container images via the docker CLI; also refactors default-image constants to be produced by a function that respects environment overrides. Changes
Sequence Diagram(s)sequenceDiagram
participant GH as "GitHub Actions"
participant Runner as "CI Runner"
participant Script as "check_default_images.py"
participant Docker as "docker CLI"
participant Registry as "Image Registry"
GH->>Runner: start "default-images" job
Runner->>Runner: setup Python 3.12, install deps
Runner->>Script: run script
Script->>Docker: docker manifest inspect <image> (per image)
Docker->>Registry: fetch manifest
Registry-->>Docker: manifest / error
Docker-->>Script: success / error
Script-->>Runner: aggregate results, exit code
Runner-->>GH: job success/failure
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches
🧪 Generate unit tests (beta)
📝 Coding Plan
Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
scripts/check_default_images.py (1)
12-26: Avoid duplicating the image override key list here.This becomes a second source of truth next to
src/vibepod/constants.py. If a new image override is added there and not here, this script can end up validating an overridden image instead of the built-in default.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@scripts/check_default_images.py` around lines 12 - 26, The list of image override env keys is duplicated in _unset_image_env_overrides; instead of hardcoding the tuple, import and reuse the canonical list from src.vibepod.constants (e.g. IMAGE_OVERRIDE_ENV_KEYS) and iterate over that constant inside the _unset_image_env_overrides function so the script stays in sync with the single source of truth in constants.py.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@scripts/check_default_images.py`:
- Around line 29-39: The `_check_image_exists` function currently calls
`subprocess.run(["docker", "manifest", "inspect", image], ...)` without a
timeout and can hang; add a reasonable timeout argument to the `subprocess.run`
call and handle `subprocess.TimeoutExpired` by returning (False, "<timeout
message>") so CI fails fast. Update `_check_image_exists` to pass e.g.
`timeout=<n_seconds>` to `subprocess.run`, and wrap the call in a try/except
catching `subprocess.TimeoutExpired` to produce a clear error string (and also
preserve the existing stderr/stdout/error fallback handling for non-zero return
codes).
---
Nitpick comments:
In `@scripts/check_default_images.py`:
- Around line 12-26: The list of image override env keys is duplicated in
_unset_image_env_overrides; instead of hardcoding the tuple, import and reuse
the canonical list from src.vibepod.constants (e.g. IMAGE_OVERRIDE_ENV_KEYS) and
iterate over that constant inside the _unset_image_env_overrides function so the
script stays in sync with the single source of truth in constants.py.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 9386114f-22e9-4a60-9f0a-ff7231e7ab51
📒 Files selected for processing (2)
.github/workflows/ci.ymlscripts/check_default_images.py
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
scripts/check_default_images.py (1)
48-51: Move environment override cleanup before importing fromvibepod.constants.The
from vibepod.constants import ...statement on line 48 triggers module initialization, which eagerly setsDEFAULT_IMAGES = get_default_images()at module scope. Since this occurs before_unset_image_env_overrides()clears theVP_IMAGE_*variables on line 50, any pre-set overrides are captured in the module-levelDEFAULT_IMAGESdictionary. This leaves the module state inconsistent with the canonical defaults this script intends to validate.Reorder the code to clear environment overrides before the import statement.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@scripts/check_default_images.py` around lines 48 - 51, Call _unset_image_env_overrides to clear VP_IMAGE_* before vibepod.constants is imported: move the env-cleanup so it runs before importing get_default_images/IMAGE_OVERRIDE_ENV_KEYS, e.g., remove the top-level "from vibepod.constants import IMAGE_OVERRIDE_ENV_KEYS, get_default_images", call _unset_image_env_overrides(...) first, then dynamically import the module (importlib.import_module("vibepod.constants")) and read IMAGE_OVERRIDE_ENV_KEYS and get_default_images from that module so DEFAULT_IMAGES isn't initialized with overridden env vars; reference _unset_image_env_overrides, IMAGE_OVERRIDE_ENV_KEYS and get_default_images when making these changes.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/vibepod/constants.py`:
- Around line 84-86: The default value for the "datasette" mapping is a too-long
inline f-string causing an E501 lint error; split/wrap the default expression so
the line is under the max length by formatting the os.environ.get call across
multiple lines (e.g., use parentheses and break the f-string or concatenate the
components) where the key "datasette" and the call
os.environ.get("VP_DATASETTE_IMAGE", f"{os.environ.get('VP_IMAGE_NAMESPACE',
'vibepod')}/datasette:latest") appear so Ruff accepts the file.
---
Nitpick comments:
In `@scripts/check_default_images.py`:
- Around line 48-51: Call _unset_image_env_overrides to clear VP_IMAGE_* before
vibepod.constants is imported: move the env-cleanup so it runs before importing
get_default_images/IMAGE_OVERRIDE_ENV_KEYS, e.g., remove the top-level "from
vibepod.constants import IMAGE_OVERRIDE_ENV_KEYS, get_default_images", call
_unset_image_env_overrides(...) first, then dynamically import the module
(importlib.import_module("vibepod.constants")) and read IMAGE_OVERRIDE_ENV_KEYS
and get_default_images from that module so DEFAULT_IMAGES isn't initialized with
overridden env vars; reference _unset_image_env_overrides,
IMAGE_OVERRIDE_ENV_KEYS and get_default_images when making these changes.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 1047d5d7-97d8-45c6-9d6d-e15cb990793c
📒 Files selected for processing (3)
.github/workflows/ci.ymlscripts/check_default_images.pysrc/vibepod/constants.py
There was a problem hiding this comment.
🧹 Nitpick comments (1)
src/vibepod/constants.py (1)
55-91: Inconsistent default namespace across images.The
VP_IMAGE_NAMESPACEfallback defaults to'vibepod'for some images (claude, codex, datasette, proxy) but'nezhar'for others (gemini, opencode, devstral, auggie, copilot). This means settingVP_IMAGE_NAMESPACE=myregistrywon't override the hardcoded fallback for images that don't have an explicit override env var set.If this is intentional (images live in different registries), consider documenting it. If not, unify the defaults.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/vibepod/constants.py` around lines 55 - 91, The get_default_images mapping uses two different hardcoded fallback namespaces ('vibepod' and 'nezhar'), causing VP_IMAGE_NAMESPACE to not override some images; update the get_default_images function so every image key (e.g., "claude", "gemini", "opencode", "devstral", "auggie", "copilot", "codex", "datasette", "proxy") constructs its default from the same os.environ.get('VP_IMAGE_NAMESPACE', '<chosen-default>') value (pick a single default like 'vibepod' or make per-image namespace env vars explicit), ensuring VP_IMAGE_NAMESPACE consistently overrides defaults or add a clear comment documenting intentional differences.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@src/vibepod/constants.py`:
- Around line 55-91: The get_default_images mapping uses two different hardcoded
fallback namespaces ('vibepod' and 'nezhar'), causing VP_IMAGE_NAMESPACE to not
override some images; update the get_default_images function so every image key
(e.g., "claude", "gemini", "opencode", "devstral", "auggie", "copilot", "codex",
"datasette", "proxy") constructs its default from the same
os.environ.get('VP_IMAGE_NAMESPACE', '<chosen-default>') value (pick a single
default like 'vibepod' or make per-image namespace env vars explicit), ensuring
VP_IMAGE_NAMESPACE consistently overrides defaults or add a clear comment
documenting intentional differences.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: f845badb-779c-4f2d-a9c0-bf8df3a65bf0
📒 Files selected for processing (3)
.github/workflows/ci.ymlscripts/check_default_images.pysrc/vibepod/constants.py
This pull request introduces a new CI job to validate that the built-in default container images are available in their respective registries. It adds a Python script to perform the validation and integrates it into the GitHub Actions workflow.
CI workflow enhancements:
default-imagesjob to.github/workflows/ci.ymlthat checks out the repository, sets up Python, installs dependencies, and runs the image validation script.Image validation tooling:
scripts/check_default_images.py, a script that verifies the existence of default container images by inspecting their manifests via Docker. It ensures canonical defaults by clearing relevant environment variables and reports any missing images.Summary by CodeRabbit
New Features
Chores