This repository contains devcontainer features to assist teams in adopting GitHub Codespaces. Features are reusable "plugins" that can be installed into devcontainers to add tools, languages, or services.
/src/- Contains all feature implementations, each in its own subdirectory/test/- Contains test scenarios for each feature, plus global integration tests/.github/workflows/- CI/CD automation for testing and releasing features
Each feature in /src/{feature-name}/ contains:
devcontainer-feature.json- Feature metadata, options, and configurationinstall.sh- Installation script (main implementation)README.md- Feature documentation (auto-generated, do not edit manually)- Optional:
NOTES.md- Implementation notes that get included in README.md generation (auto-generated, do not edit manually)
/test/{feature-name}/- Feature-specific tests withscenarios.jsonand test scripts/test/_global/- Integration tests that test multiple features together- Test scenarios are defined in
scenarios.jsonfiles and executed using the devcontainer CLI
| Feature | Description |
|---|---|
artifacts-helper |
Azure Artifacts credential helper for Codespace authentication |
devtool |
Microsoft DevTool (internal only) |
docfx |
DocFX documentation generation tool |
external-repository |
Handles external git repository integration in Codespaces |
go |
Go language with Mariner Linux support |
microsoft-git |
Microsoft's Git distribution with Scalar and GVFS |
Features use semantic versioning (SemVer):
- MAJOR version for incompatible API changes
- MINOR version for backward-compatible functionality additions
- PATCH version for backward-compatible bug fixes
When making changes to a feature:
- Update the
versionfield indevcontainer-feature.json - Follow SemVer guidelines based on the type of change
- Document breaking changes in the feature description or NOTES.md
- Create directory structure:
/src/{feature-name}/ - Write
devcontainer-feature.jsonwith proper metadata:{ "id": "feature-name", "version": "1.0.0", "name": "Feature Display Name", "description": "Brief description", "options": { /* configuration options */ }, "installsAfter": ["ghcr.io/devcontainers/features/common-utils"] } - Implement
install.shwith proper error handling and logging - Create comprehensive tests in
/test/{feature-name}/
- Error Handling: Always check exit codes and handle failures gracefully
- Logging: Use consistent logging format with feature name and version
- Idempotency: Features should handle multiple installations safely
- Cross-Platform: Test on Ubuntu, Debian, and Mariner Linux base images
- Dependencies: Use
installsAfterfor proper installation order
- Create
scenarios.jsonwith comprehensive test cases - Test on multiple base images: Ubuntu, Debian, Mariner
- Include edge cases: version conflicts, reinstallation, error conditions
- Use descriptive test names that explain what is being validated
# Test single feature on specific base image
devcontainer features test -f {feature-name} -i {base-image} .
# Test feature autogenerated scenarios only (CI pattern)
devcontainer features test --skip-scenarios -f {feature-name} -i {base-image} .
# Test feature custom scenarios only (CI pattern)
devcontainer features test -f {feature-name} --skip-autogenerated .
# Test all global scenarios
devcontainer features test --global-scenarios-only .
# Common base images used in CI
# - mcr.microsoft.com/devcontainers/base:ubuntu
# - mcr.microsoft.com/devcontainers/base:debian
# - mcr.microsoft.com/cbl-mariner/base/core:2.0test-pr.yaml- Tests changed features on pull requests using path filteringtest-all.yaml- Comprehensive testing on main branch across all features- Tests run on Ubuntu, Debian, and Mariner base images automatically
- Separate jobs for autogenerated tests and custom scenarios
release.yaml- Publishes features to GitHub Container Registry- Features are versioned using semantic versioning
- Each feature is published independently
- Use
set -efor error handling - Quote variables properly:
"${VARIABLE}" - Check for required tools before using them
- Provide meaningful error messages
- Follow consistent indentation and formatting
- Use proper JSON validation
- Follow devcontainer feature schema
- Include comprehensive option descriptions
- Specify version constraints clearly
# Check for package manager
if command -v apt-get >/dev/null 2>&1; then
package_manager="apt"
elif command -v tdnf >/dev/null 2>&1; then
package_manager="tdnf"
fi# Auto-detect latest version
if [ "${VERSION}" = "latest" ] || [ "${VERSION}" = "lts" ]; then
VERSION=$(curl -s API_ENDPOINT | jq -r .tag_name | sed 's/^v//')
fi- Test on Ubuntu (apt), Debian (apt), and Mariner (tdnf)
- Handle different package names across distributions
- Account for different default paths and permissions
- Network timeouts: Features may fail in environments with restricted internet
- Package conflicts: Check for existing installations before proceeding
- Permission issues: Ensure proper file permissions and user context
- Path problems: Verify PATH updates and binary locations
- Check feature logs in devcontainer build output
- Test locally using devcontainer CLI
- Use
docker execto inspect container state - Review GitHub Actions logs for CI failures
- Validate all input parameters
- Use secure download methods (HTTPS, signature verification)
- Avoid hardcoded credentials or secrets
- Follow principle of least privilege
- Pin dependency versions for reproducibility
- Use devcontainer secrets for sensitive data
- Never commit credentials to the repository
- Support both build-time and runtime authentication methods
- Create feature branch from
main - Implement feature with comprehensive tests
- Update the
versionfield indevcontainer-feature.jsonfollowing semantic versioning - Ensure all CI checks pass
- Update documentation as needed
- Request review from maintainers
- Feature follows repository conventions
- Tests cover success and failure scenarios
- Cross-platform compatibility verified
- Security best practices followed
- Documentation is complete and accurate
When working on this repository, focus on creating reliable, cross-platform features that enhance the Codespaces development experience while following established patterns and best practices.