fix: set default base image in Dockerfiles and improve syntax handling - #1271
Open
Kaniska244 wants to merge 2 commits into
Open
fix: set default base image in Dockerfiles and improve syntax handling#1271Kaniska244 wants to merge 2 commits into
Kaniska244 wants to merge 2 commits into
Conversation
Kaniska244
marked this pull request as ready for review
July 28, 2026 09:24
abdurriq
reviewed
Jul 28, 2026
| }); | ||
|
|
||
| // returns the names of any ARGs used in a `FROM` that lack a default declared before them. | ||
| function findFromArgsWithoutDefault(dockerfile: string): string[] { |
Contributor
There was a problem hiding this comment.
Do we not also want to use this for other features?
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What this PR does
Related #1229. Fixes the
InvalidDefaultArgInFrombuild warning emitted by Docker/BuildKit when building dev containers. The warning is raised whenever aFROMinstruction references a buildARGthat has no in-scope default value at parse time.This warning does not come from the user's project Dockerfile — it originates from the internal Dockerfiles the CLI generates (and the static
updateUID.Dockerfile), whereFROMreferenced_DEV_CONTAINERS_BASE_IMAGE/BASE_IMAGEwithout a declared default.Root cause
Two patterns were triggering the linter:
scripts/updateUID.DockerfiledeclaredARG BASE_IMAGE(no default) and then usedFROM $BASE_IMAGE.FROM ${_DEV_CONTAINERS_BASE_IMAGE:-scratch}. The${VAR:-scratch}form is a runtime shell expansion; it is not recognized as anARGdefault by the static linter, so the warning persisted even when a globalARG ... = placeholderwas declared.The fix
Declare the base-image
ARGwith a real default (scratchfor the generated files,placeholderfor the UID script) immediately before it's used, and reference it plainly as$VAR— the form the linter recognizes as having a valid default.src/spec-configuration/containerFeaturesConfiguration.ts— addARG _DEV_CONTAINERS_BASE_IMAGE=scratchbefore theFROMstages in the generated feature base Dockerfile (theFROMlines already reference the ARG directly).src/spec-node/containerFeatures.ts— change the prefixARGdefault fromplaceholdertoscratchin bothgetImageBuildOptions(no-features path) andgetFeaturesBuildOptions(features path).scripts/updateUID.Dockerfile— changeARG BASE_IMAGE→ARG BASE_IMAGE=placeholder.Behavior is unchanged at build time
The CLI always passes the real image via
--build-arg(_DEV_CONTAINERS_BASE_IMAGE=<image>, andBASE_IMAGE=<image>for the UID Dockerfile), so thescratch/placeholderdefaults only ever exist to satisfy the static linter and never affect the actual build.Tests
Added a daemon-free unit test suite in
src/test/container-features/generateFeaturesConfig.test.ts(validate generated Dockerfiles avoid InvalidDefaultArgInFrom) that:findFromArgsWithoutDefault()helper mimicking theInvalidDefaultArgInFromrule (flags anyARGused in aFROMwithout a default declared before it)._DEV_CONTAINERS_BASE_IMAGEwith a default, references it directly, and does not use the${VAR:-default}shell fallback.scripts/updateUID.DockerfiledeclaresBASE_IMAGEwith a default beforeFROM.These run without Docker, so they execute in CI as part of
npm test.Files changed
src/spec-configuration/containerFeaturesConfiguration.tsARG _DEV_CONTAINERS_BASE_IMAGE=scratchbeforeFROMsrc/spec-node/containerFeatures.tsplaceholder→scratchin both build-option pathsscripts/updateUID.DockerfileARG BASE_IMAGE→ARG BASE_IMAGE=placeholdersrc/test/container-features/generateFeaturesConfig.test.tsInvalidDefaultArgInFromregression testsNotes / follow-ups
getImageBuildOptionsno-features path is covered indirectly (its ARG default was corrected), but its Dockerfile string is built inline and isn't directly unit-tested. A small follow-up could extract that string into an exported helper to unit-test it the same way..devcontainer/devcontainer-lock.jsonshows a trailing-newline-only change; consider reverting that if it's unintentional.