Modify an existing devcontainer feature: update install logic, fix bugs, change metadata — and bump the version.
Use this skill when an issue or request involves changing an existing feature (bug fix, install method update, description change, dependency update, etc.). Do not use this for creating a new feature from scratch — use create-devcontainer-feature for that.
Every change to a feature MUST include a version bump. No exceptions.
- Patch bump (default):
1.0.0→1.0.1— for bug fixes, minor install script changes, documentation fixes, dependency updates - Minor bump:
1.0.0→1.1.0— for new options, significant behavior changes, new capabilities - Major bump:
1.0.0→2.0.0— for breaking changes (e.g., different binary name, removed options, changed default behavior)
Use a patch bump unless the issue explicitly requests or the change clearly warrants a minor or major bump.
Determine which feature to modify from the issue description. The feature id matches the directory name under src/.
Read the existing files to understand the current state:
src/<FEATURE_ID>/devcontainer-feature.json— current version, options, metadatasrc/<FEATURE_ID>/install.sh— current install logicsrc/<FEATURE_ID>/NOTES.md— current documentationtest/<FEATURE_ID>/test.sh— current tests
Apply the changes described in the issue. Common change types:
- Bug fix in install.sh — fix download URL, architecture mapping, error handling, etc.
- Update install method — e.g., switch from curl to gh release
- Update metadata — description, name, options in
devcontainer-feature.json - Update documentation —
NOTES.mdcontent - Update tests — fix or improve
test.shassertions - Update helper functions — copy latest versions from https://github.com/devcontainer-community/shell-snippets
When editing devcontainer-feature.json, ensure "installsAfter" includes "ghcr.io/devcontainer-community/devcontainer-features/ca-certificates:latest" as the first entry. Add it if missing.
When modifying install.sh:
- Keep helper functions verbatim from the shell-snippets repo
- Only customize the feature-specific parts (repository, binary name, URL template, architecture mappings)
- Preserve the required header (
set -oflags) and footer (echo_banner+ install call) - Ensure the executable bit is preserved: run
chmod +xandgit update-index --chmod=+xif the file is recreated
Update the version in both locations:
Increment the "version" field:
{
"version": "1.0.1"
}Find the feature's row in the table and update the version in the last column:
| [feature-name](...) | `binary` — description | install-method | 1.0.1 |
Both files must have the same version. If they are out of sync before your change, align them to the new bumped version.
If the change affects the binary name, version output format, or install location, update test/<FEATURE_ID>/test.sh accordingly.
If the change is purely a bug fix in install logic and the test already verifies the binary works, the test likely needs no changes.
- Verify
devcontainer-feature.jsonis valid JSON and the version was bumped - Verify the version in
README.mdmatches the version indevcontainer-feature.json - Verify
install.shstill has correct shebang,set -oflags, and the executable bit - Verify
test.shstill sourcesdev-container-features-test-liband callsreportResults - Run CI tests via GitHub Actions — the test workflow automatically picks up changed features on a PR:
devcontainer features test --skip-scenarios -f <FEATURE_ID> -i debian:latest .devcontainer features test --skip-scenarios -f <FEATURE_ID> -i ubuntu:latest .devcontainer features test --skip-scenarios -f <FEATURE_ID> -i mcr.microsoft.com/devcontainers/base:ubuntu .
- Changes applied as described in the issue
- Version bumped in
src/<ID>/devcontainer-feature.json(patch unless stated otherwise) - Version bumped in root
README.md(same version, correct row) - Both versions match
-
install.shexecutable bit preserved (if file was modified) - Tests updated if affected by the change
- CI tests pass on all three base images