dep-check asks Docker Hub about opsdeck:rig-base, an image that is only ever built locally #25

Closed
opened 2026-08-11 09:19:07 +02:00 by julian · 0 comments
Owner

Split out of the review of #23, where it was the one non-green line in the dry run. Unrelated to that PR's bumps.

$ deno run --allow-read --allow-net --allow-env tools/dep-check/main.ts --dry-run
checking 8 dependencies
  ? opsdeck rig-base: registry answered HTTP 401
  = actions/checkout v7.0.1: up to date
  ...

Cause

docker/dev-rig/Dockerfile:10 is FROM opsdeck:rig-base. That image does not come from a registry — docker/dev-rig/up.sh:56 builds it from docker/Dockerfile and tags it locally, and nothing pushes it anywhere.

Discovery walks every Dockerfile in the tree rather than reading a hardcoded list of two paths, deliberately (discover.ts:357: a place nobody had listed is how a dependency went unwatched once already). So it finds this one, imageDependency splits opsdeck:rig-base into a name and a tag like any other reference, and the unqualified name resolves against Docker Hub, where library/opsdeck does not exist and anonymous auth answers 401.

The tag is unversioned anyway, so even if the lookup succeeded there would be nothing to compare — the honest answer for this line is "not a dependency", not "up to date".

Arrived with #10, which brought docker/dev-rig.

What it does and does not break

It does not make the run red: the exit code is failed || unwatched.length || unreachable === reports.length (main.ts:219), so one unreachable dependency out of eight still exits 0, and the weekly job and every PR's dry run stay green.

What it costs is the property the tool is built around — a run that finds nothing writes nothing, so anything it does print is worth reading. This line prints on every run and can never be resolved, and a genuine registry outage on a real dependency prints the same shape of line. Noise that is permanent is noise that gets skipped.

Options

Not prescribing one; each trades differently:

  1. A marker on the line. Nothing in FROM opsdeck:rig-base distinguishes a locally built image from a registry one, so discovery cannot infer it — it would need a comment it reads, the way it already reads # v7.0.1 on an action pin. Closest to the existing convention, and the marker is visible to the next reader of the Dockerfile.
  2. An ignore list (DEP_CHECK_IGNORE, or a field in the repo). Cheapest, and the one that ages worst: a list nobody looks at is the failure this whole arrangement exists to prevent, and an entry that outlives its Dockerfile silences a real dependency later.
  3. Report it as unwatched with a reason instead of an error. Reads correctly, but unwatched.length makes the run exit 1, so this trades permanent noise for permanent red unless unwatched is first split into "cannot be watched, deliberately" and "should be watched, isn't".
  4. Take the base as a build arg in dev-rig — ARG BASE=opsdeck:rig-base / FROM ${BASE}. Discovery skips refs containing $ (discover.ts:224) as operator indirection, so the line stops being a declaration at all. Smallest diff and up.sh already owns the build, but it makes the base implicit to someone reading the Dockerfile, and it works by side effect of a rule written for something else — which is the kind of thing that gets undone by a later cleanup that does not know it was load-bearing.

Option 1 or 3 is where I would look first; 4 is a one-line fix if this only needs to stop being noise.

Split out of the review of #23, where it was the one non-green line in the dry run. Unrelated to that PR's bumps. ``` $ deno run --allow-read --allow-net --allow-env tools/dep-check/main.ts --dry-run checking 8 dependencies ? opsdeck rig-base: registry answered HTTP 401 = actions/checkout v7.0.1: up to date ... ``` ## Cause `docker/dev-rig/Dockerfile:10` is `FROM opsdeck:rig-base`. That image does not come from a registry — `docker/dev-rig/up.sh:56` builds it from `docker/Dockerfile` and tags it locally, and nothing pushes it anywhere. Discovery walks every Dockerfile in the tree rather than reading a hardcoded list of two paths, deliberately (`discover.ts:357`: a place nobody had listed is how a dependency went unwatched once already). So it finds this one, `imageDependency` splits `opsdeck:rig-base` into a name and a tag like any other reference, and the unqualified name resolves against Docker Hub, where `library/opsdeck` does not exist and anonymous auth answers 401. The tag is unversioned anyway, so even if the lookup succeeded there would be nothing to compare — the honest answer for this line is "not a dependency", not "up to date". Arrived with #10, which brought `docker/dev-rig`. ## What it does and does not break It does **not** make the run red: the exit code is `failed || unwatched.length || unreachable === reports.length` (`main.ts:219`), so one unreachable dependency out of eight still exits 0, and the weekly job and every PR's dry run stay green. What it costs is the property the tool is built around — a run that finds nothing writes nothing, so anything it does print is worth reading. This line prints on every run and can never be resolved, and a genuine registry outage on a real dependency prints the same shape of line. Noise that is permanent is noise that gets skipped. ## Options Not prescribing one; each trades differently: 1. **A marker on the line.** Nothing in `FROM opsdeck:rig-base` distinguishes a locally built image from a registry one, so discovery cannot infer it — it would need a comment it reads, the way it already reads `# v7.0.1` on an action pin. Closest to the existing convention, and the marker is visible to the next reader of the Dockerfile. 2. **An ignore list** (`DEP_CHECK_IGNORE`, or a field in the repo). Cheapest, and the one that ages worst: a list nobody looks at is the failure this whole arrangement exists to prevent, and an entry that outlives its Dockerfile silences a real dependency later. 3. **Report it as `unwatched` with a reason** instead of an error. Reads correctly, but `unwatched.length` makes the run exit 1, so this trades permanent noise for permanent red unless `unwatched` is first split into "cannot be watched, deliberately" and "should be watched, isn't". 4. **Take the base as a build arg** in dev-rig — `ARG BASE=opsdeck:rig-base` / `FROM ${BASE}`. Discovery skips refs containing `$` (`discover.ts:224`) as operator indirection, so the line stops being a declaration at all. Smallest diff and `up.sh` already owns the build, but it makes the base implicit to someone reading the Dockerfile, and it works by side effect of a rule written for something else — which is the kind of thing that gets undone by a later cleanup that does not know it was load-bearing. Option 1 or 3 is where I would look first; 4 is a one-line fix if this only needs to stop being noise.
Sign in to join this conversation.
No labels
No milestone
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
OpsDeck/core#25
No description provided.