Skip to content

fix(features)!: map and refuse legacy Feature ids as the reference does - #66

Merged
aledbf merged 1 commit into
mainfrom
align-feature-shorthand
Nov 13, 2026
Merged

aledbf merged 1 commit into
mainfrom
align-feature-shorthand

Conversation

@aledbf

@aledbf aledbf commented Nov 13, 2026

Copy link
Copy Markdown
Member

Aligns legacy and shorthand Feature ids with the official CLI (TS getBackwardCompatibleFeatureId, getFeatureIdType, updateDeprecatedFeaturesIntoOptions). This was drift, not a deliberate fix. Breaking: see docs/migration.md.

id Before (Go) After (Go = TS)
node, golang, … (exact legacy names) mapped silently mapped to ghcr.io/devcontainers/features/<new>:1 + (!) WARNING: Using the deprecated '<id>' Feature. See …
node:18, node:1 mapped to …/node:18 Legacy feature '<id>' not supported, exit 1
my-custom-feature refused, except in outdated/resolve-dependencies (ghcr lookup) refused everywhere
gradle, maven, jupyterlab handled one by one folded into the java/python Feature's options before resolution, with TS's warning
owner/repo/feat ghcr.io/owner/repo/feat OCI reference with registry owner
--skip-feature-auto-mapping turned the mapping off accepted and ignored (TS never passes it down; its own test expects node to map)
outdated, legacy ids looked up on ghcr left out (getRef on the id as written)
outdated, Feature with no versions left out reported empty ({} / -)

The lockfile integrity is now looked up by the mapped id, as in TS.

Tests

  • New ts-oracle golden internal/features/testdata/ts-oracle/legacy.json (generated from the reference) pins the three TS functions (TestTSOracleLegacyFeatureIDs).
  • 5 parity cases. 3 are hermetic: read-configuration.legacy-feature-id-with-tag-error, read-configuration.deprecated-feature-into-options-error, outdated.legacy-ids-success. 2 need the network: read-configuration.feature-shorthand-registry-error, read-configuration.skip-feature-auto-mapping-success. All 5 fail with the pre-change binary.
  • Unit tests for install, metadata, resolve-dependencies and outdated; the old-mapping assertions are updated.

Not changed (known): no GitHub Releases fallback (already documented, so the last error line differs from TS while the exit code matches), and Features are still resolved in id order rather than configuration order.

Validation (local)

  • task lint: 0 issues.
  • task spec:compliance: pass.
  • task test:race with TMPDIR outside /tmp: pass (two Docker-backed interop tests flaked under load and pass on a rerun).
  • task parity:contract: only the 2 known /tmp/.git cases fail locally.
  • Network parity: the new cases and the affected outdated/upgrade cases pass.

🤖 Generated with Claude Code

Legacy and shorthand Feature ids now follow the reference CLI's
getBackwardCompatibleFeatureId, getFeatureIdType and
updateDeprecatedFeaturesIntoOptions in up, build, read-configuration,
upgrade, features resolve-dependencies, features info and outdated:

- Only exact legacy names (node, golang, …) map to
  ghcr.io/devcontainers/features/<name>:1, and log TS's
  "(!) WARNING: Using the deprecated '<id>' Feature" line.
- A legacy name with a tag (node:18, node:1) and any other id without a
  '/' fail with "Legacy feature '<id>' not supported".
- gradle, maven and jupyterlab move into the java/python Feature they
  are now an option of, before any Feature is resolved.
- owner/repo/feat is an OCI reference whose registry is "owner", no
  longer ghcr.io/owner/repo/feat.
- --skip-feature-auto-mapping is accepted and ignored, as in TS.
- outdated reports what getRef parses as written: legacy ids are left
  out, and a Feature without published versions is reported empty.
- The lockfile's integrity is looked up by the mapped id, so an entry
  under a legacy id doesn't pin it, as in TS.

A ts-oracle golden pins the three TS functions, and five parity cases
compare the user-visible results with the reference.

BREAKING CHANGE: node:18-style ids, other names without a '/', and
owner/repo/feat ids that relied on an implicit ghcr.io now fail or
resolve as in the official CLI; docs/migration.md says how to write
them.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
@aledbf
aledbf merged commit a5b7cbe into main Nov 13, 2026
13 checks passed
@aledbf
aledbf deleted the align-feature-shorthand branch November 13, 2026 00:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant