Repository navigation
fix(features): write Feature ENV lines and options in declared order - #68
Merged
Merged
Conversation
aledbf
force-pushed
the
align-env-order
branch
from
November 13, 2026 01:17
0d5006a to
3c0cdaf
Compare
The image's ENV lines for a Feature's containerEnv and the config's
containerEnv, and the user's options in devcontainer-features.env, were
written in sorted key order. The reference CLI writes them in JS
property order (integer-index keys ascending, then declaration order).
Besides the order itself, a Feature's ENV line that uses a variable an
earlier line sets, such as PATH=${SDKMAN_DIR}/bin:${PATH} after
SDKMAN_DIR, expanded to a different value when the sort put it first,
so the built image's environment differed.
The member order is now recorded where the documents are parsed
(devcontainer-feature.json, devcontainer.json and its override,
--additional-features) and carried to the generated Dockerfile through
features.PropertyOrder.
The two ts-oracle cases recorded as unresolved divergences now match
TS, a TS-generated ts-features-build golden pins the dependent ENV
lines, and a runtime parity case compares the built image's env and
devcontainer-features.env with the reference.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Co-Authored-By: Claude Opus 5.5 <[email protected]>
aledbf
force-pushed
the
align-env-order
branch
from
November 13, 2026 02:04
3c0cdaf to
76f495c
Compare
CodeQL's go/allocation-size-overflow flagged the sum of two lengths used as a make capacity. The hint bought nothing measurable, so the slice grows on append instead. Co-Authored-By: Claude Opus 5.5 <[email protected]>
This was referenced Nov 13, 2026
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.
Aligns key order with the official CLI. The ts-oracle goldens had recorded this drift as two "unresolved" divergences.
Problem. Go wrote these in sorted key order, where TS uses JS property order (integer-index keys ascending, then declaration order):
ENVlines for a Feature'scontainerEnv;containerEnv;devcontainer-features.env.Besides the order, this changed the built image: an
ENVline that uses a variable an earlier line sets expanded differently once sorting moved it first.PATH=/usr/local/sdkman/bin:/usr/local/sbin:…,ZED=1,ALPHA=2PATH=/bin:/usr/local/sbin:…(SDKMAN_DIR not yet set),ALPHA=2,ZED=1devcontainer-features.env: TS and now Go writeVERSION, ZZ, AA; Go wroteVERSION, AA, ZZ.Design. The member order is recorded where documents are parsed, following the pattern
Feature.DependsOnOrderalready uses:devcontainer-feature.json;devcontainer.jsonplus its override, merged asdeepMergeConfigdoes;--additional-features.It is emitted through one helper,
features.PropertyOrder, on top of the existingjsObject.jsonc.MemberNamesgains a path argument.Tests
imagemeta.jsonnow match, and two new cases (dependent variable, integer keys first) are checked against TS.ts-features-build/declaration-order/, made with the repo'sgen.tsagainst v0.90.0. The existing goldens regenerate byte-identical.TestFetchedFeaturesKeepTheDeclaredOrder: real local Features through to the Dockerfile.--additional-features,PropertyOrderandMemberNames.build.features-env-declaration-order-success, which compares the built image env anddevcontainer-features.envwith TS. It fails with the pre-change binary.Still sorted (follow-up):
containerEnvinside thedevcontainer.metadatalabel, the Featurevaluekey order inread-configuration,installOrderoptions infeatures resolve-dependencies, and the mergedcontainerEnvin the compose override.Validation (local)
task lint,task spec:compliance,task testdata:ts-oracle:check: pass.task test:racewithTMPDIRoutside/tmp: pass.task parity:contract: only the 2 known/tmp/.gitcases fail.TestE2Epass in a full run with a longer timeout. Thetask test:e2e5m budget ran out under load from parallel runs on the shared daemon.🤖 Generated with Claude Code