Each feature lives under src/<feature-name>/ and has a parallel test directory at test/<feature-name>/:
src/<feature-name>/
devcontainer-feature.json # Metadata, mounts, env vars, postCreateCommand
install.sh # Runs at image build time (root, inside container)
NOTES.md # Human-written design notes — update when making meaningful changes
README.md # Auto-generated — DO NOT edit directly, run `mise run docs`
test/<feature-name>/
test.sh # Integration test run inside container after feature install
- Create
src/<feature-name>/devcontainer-feature.json,install.sh, andNOTES.md - Add
test/<feature-name>/test.shcovering every installed binary and configured file - Add the new feature to the top-level
README.mdfeatures list - Run
mise run docsto generatesrc/<feature-name>/README.md
- Shebang:
#!/usr/bin/bash;set -eat the top - Detect distro by sourcing
/etc/os-releaseand switching on$ID - Support Debian, Ubuntu, and Fedora at minimum;
exit 1on unknown distros - Watch for package name differences across distros (e.g.
openssh-clientvsopenssh-clients)
See src/personal-setup/install.sh for the reference pattern.
Tests use dev-container-features-test-lib (injected by the devcontainer test runner):
source dev-container-features-test-lib
check "label" bash -c "..."
reportResults- Add a
checkfor every binary installed and every file/env var configured - Always write tests for new functionality before considering it complete
- Run tests:
mise run test(tests against debian, ubuntu, fedora-toolbox, devcontainers/base:ubuntu)
mise run lint-shell # ShellCheck all .sh files
mise run docs # Regenerate README.md from devcontainer-feature.json + NOTES.md
mise run test # Full integration test suite (requires Docker)Update src/<feature-name>/NOTES.md when:
- Adding or removing a package and there's a non-obvious reason why
- Changing the dotfiles/mount/RCM strategy
- Documenting a tradeoff or design decision for future reference
README.md is auto-generated and will include the contents of NOTES.md — so write NOTES.md as if it's public-facing prose.