Contributing
Adding a New Feature
Section titled “Adding a New Feature”1. Create the Feature Directory
Section titled “1. Create the Feature Directory”Create a new directory under src/ with your feature ID:
src/my-feature/├── devcontainer-feature.json├── install.sh├── activate-feature.yml└── hosts.yml2. Define Feature Metadata
Section titled “2. Define Feature Metadata”Create devcontainer-feature.json with your feature’s metadata:
{ "name": "my-feature", "id": "my-feature", "version": "1.0.0", "description": "Installs My Tool on Red Hat UBI DevContainers.", "options": { "target_version": { "type": "string", "default": "1.0.0", "description": "Select the version to install" } }, "containerEnv": { "PATH": "/home/vscode/.local/bin:${PATH}" }, "installsAfter": []}3. Write the Install Script
Section titled “3. Write the Install Script”Create install.sh following the standard pattern:
#!/usr/bin/env bashset -euo pipefail
FEATURE_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# Validate UV is availablecommand -v uv >/dev/null 2>&1 || { echo "ERROR: uv is not installed"; exit 1; }
# Run Ansible playbookuv run --with ansible-core \ ansible-playbook "${FEATURE_DIR}/activate-feature.yml" \ -i "${FEATURE_DIR}/hosts.yml" \ -e "my_tool_version=${TARGET_VERSION:-1.0.0}"4. Write the Ansible Playbook
Section titled “4. Write the Ansible Playbook”Create activate-feature.yml with the installation tasks. Use Ansible modules for downloading, extracting, and configuring the tool.
5. Create the Ansible Inventory
Section titled “5. Create the Ansible Inventory”Create hosts.yml:
all: hosts: localhost: ansible_connection: local6. Add Tests
Section titled “6. Add Tests”Create test files under test/my-feature/:
#!/bin/bashset -esource dev-container-features-test-lib
check "my-tool is installed" bash -c "my-tool --version"
reportResults7. Update the CI Matrix
Section titled “7. Update the CI Matrix”Add your feature to the test matrix in .github/workflows/test-all.yaml.
Running Tests Locally
Section titled “Running Tests Locally”# Build the base imagemake build-test-base
# Test your featuremake test-feature FEATURE=my-feature
# Test scenarios (if applicable)make test-scenarios FEATURE=my-featureCode Style
Section titled “Code Style”- install.sh: Use
set -euo pipefail, validate inputs, and delegate to Ansible - Ansible playbooks: Use YAML style with explicit task names
- Options: Use
target_versionfor version pinning,target_checksumfor SHA256 verification - Paths: Install to
~/.local/binor~/.local/share/<tool>