├── .devcontainer └── devcontainer.json ├── .github └── workflows │ ├── release.yaml │ ├── test.yaml │ └── validate.yml ├── LICENSE ├── README.md ├── src ├── color │ ├── README.md │ ├── devcontainer-feature.json │ └── install.sh └── hello │ ├── README.md │ ├── devcontainer-feature.json │ └── install.sh └── test ├── _global ├── color_and_hello.sh └── scenarios.json ├── color ├── gold.sh ├── green.sh ├── my_favorite_color_is_green.sh ├── scenarios.json └── test.sh └── hello ├── hello.sh ├── scenarios.json └── test.sh /.devcontainer/devcontainer.json: -------------------------------------------------------------------------------- 1 | { 2 | "image": "mcr.microsoft.com/devcontainers/javascript-node:1-20-bookworm", 3 | "customizations": { 4 | "vscode": { 5 | "settings": { 6 | "json.schemas": [ 7 | { 8 | "fileMatch": [ 9 | "*/devcontainer-feature.json" 10 | ], 11 | "url": "https://raw.githubusercontent.com/devcontainers/spec/main/schemas/devContainerFeature.schema.json" 12 | } 13 | ] 14 | }, 15 | "extensions": [ 16 | "mads-hartmann.bash-ide-vscode" 17 | ] 18 | } 19 | }, 20 | "features": { 21 | "ghcr.io/devcontainers/features/docker-in-docker:2": {} 22 | }, 23 | "remoteUser": "node", 24 | "updateContentCommand": "npm install -g @devcontainers/cli" 25 | } 26 | -------------------------------------------------------------------------------- /.github/workflows/release.yaml: -------------------------------------------------------------------------------- 1 | name: "Release dev container features & Generate Documentation" 2 | on: 3 | workflow_dispatch: 4 | 5 | jobs: 6 | deploy: 7 | if: ${{ github.ref == 'refs/heads/main' }} 8 | runs-on: ubuntu-latest 9 | permissions: 10 | contents: write 11 | pull-requests: write 12 | packages: write 13 | steps: 14 | - uses: actions/checkout@v4 15 | 16 | - name: "Publish Features" 17 | uses: devcontainers/action@v1 18 | with: 19 | publish-features: "true" 20 | base-path-to-features: "./src" 21 | generate-docs: "true" 22 | 23 | env: 24 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 25 | 26 | - name: Create PR for Documentation 27 | id: push_image_info 28 | env: 29 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 30 | run: | 31 | set -e 32 | echo "Start." 33 | # Configure git and Push updates 34 | git config --global user.email github-actions[bot]@users.noreply.github.com 35 | git config --global user.name github-actions[bot] 36 | git config pull.rebase false 37 | branch=automated-documentation-update-$GITHUB_RUN_ID 38 | git checkout -b $branch 39 | message='Automated documentation update' 40 | # Add / update and commit 41 | git add */**/README.md 42 | git commit -m 'Automated documentation update [skip ci]' || export NO_UPDATES=true 43 | # Push 44 | if [ "$NO_UPDATES" != "true" ] ; then 45 | git push origin "$branch" 46 | gh pr create --title "$message" --body "$message" 47 | fi 48 | -------------------------------------------------------------------------------- /.github/workflows/test.yaml: -------------------------------------------------------------------------------- 1 | name: "CI - Test Features" 2 | on: 3 | push: 4 | branches: 5 | - main 6 | pull_request: 7 | workflow_dispatch: 8 | 9 | jobs: 10 | test-autogenerated: 11 | runs-on: ubuntu-latest 12 | continue-on-error: true 13 | strategy: 14 | matrix: 15 | features: 16 | - color 17 | - hello 18 | baseImage: 19 | - debian:latest 20 | - ubuntu:latest 21 | - mcr.microsoft.com/devcontainers/base:ubuntu 22 | steps: 23 | - uses: actions/checkout@v4 24 | 25 | - name: "Install latest devcontainer CLI" 26 | run: npm install -g @devcontainers/cli 27 | 28 | - name: "Generating tests for '${{ matrix.features }}' against '${{ matrix.baseImage }}'" 29 | run: devcontainer features test --skip-scenarios -f ${{ matrix.features }} -i ${{ matrix.baseImage }} . 30 | 31 | test-scenarios: 32 | runs-on: ubuntu-latest 33 | continue-on-error: true 34 | strategy: 35 | matrix: 36 | features: 37 | - color 38 | - hello 39 | steps: 40 | - uses: actions/checkout@v4 41 | 42 | - name: "Install latest devcontainer CLI" 43 | run: npm install -g @devcontainers/cli 44 | 45 | - name: "Generating tests for '${{ matrix.features }}' scenarios" 46 | run: devcontainer features test -f ${{ matrix.features }} --skip-autogenerated --skip-duplicated . 47 | 48 | test-global: 49 | runs-on: ubuntu-latest 50 | continue-on-error: true 51 | steps: 52 | - uses: actions/checkout@v4 53 | 54 | - name: "Install latest devcontainer CLI" 55 | run: npm install -g @devcontainers/cli 56 | 57 | - name: "Testing global scenarios" 58 | run: devcontainer features test --global-scenarios-only . 59 | -------------------------------------------------------------------------------- /.github/workflows/validate.yml: -------------------------------------------------------------------------------- 1 | name: "Validate devcontainer-feature.json files" 2 | on: 3 | workflow_dispatch: 4 | pull_request: 5 | 6 | jobs: 7 | validate: 8 | runs-on: ubuntu-latest 9 | steps: 10 | - uses: actions/checkout@v4 11 | 12 | - name: "Validate devcontainer-feature.json files" 13 | uses: devcontainers/action@v1 14 | with: 15 | validate-only: "true" 16 | base-path-to-features: "./src" 17 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Microsoft Corporation 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Dev Container Features: Self Authoring Template 2 | 3 | > This repo provides a starting point and example for creating your own custom [dev container Features](https://containers.dev/implementors/features/), hosted for free on GitHub Container Registry. The example in this repository follows the [dev container Feature distribution specification](https://containers.dev/implementors/features-distribution/). 4 | > 5 | > To provide feedback to the specification, please leave a comment [on spec issue #70](https://github.com/devcontainers/spec/issues/70). For more broad feedback regarding dev container Features, please see [spec issue #61](https://github.com/devcontainers/spec/issues/61). 6 | 7 | ## Example Contents 8 | 9 | This repository contains a _collection_ of two Features - `hello` and `color`. These Features serve as simple feature implementations. Each sub-section below shows a sample `devcontainer.json` alongside example usage of the Feature. 10 | 11 | ### `hello` 12 | 13 | Running `hello` inside the built container will print the greeting provided to it via its `greeting` option. 14 | 15 | ```jsonc 16 | { 17 | "image": "mcr.microsoft.com/devcontainers/base:ubuntu", 18 | "features": { 19 | "ghcr.io/devcontainers/feature-starter/hello:1": { 20 | "greeting": "Hello" 21 | } 22 | } 23 | } 24 | ``` 25 | 26 | ```bash 27 | $ hello 28 | 29 | Hello, user. 30 | ``` 31 | 32 | ### `color` 33 | 34 | Running `color` inside the built container will print your favorite color to standard out. 35 | 36 | ```jsonc 37 | { 38 | "image": "mcr.microsoft.com/devcontainers/base:ubuntu", 39 | "features": { 40 | "ghcr.io/devcontainers/feature-starter/color:1": { 41 | "favorite": "green" 42 | } 43 | } 44 | } 45 | ``` 46 | 47 | ```bash 48 | $ color 49 | 50 | my favorite color is green 51 | ``` 52 | 53 | ## Repo and Feature Structure 54 | 55 | Similar to the [`devcontainers/features`](https://github.com/devcontainers/features) repo, this repository has a `src` folder. Each Feature has its own sub-folder, containing at least a `devcontainer-feature.json` and an entrypoint script `install.sh`. 56 | 57 | ``` 58 | ├── src 59 | │ ├── hello 60 | │ │ ├── devcontainer-feature.json 61 | │ │ └── install.sh 62 | │ ├── color 63 | │ │ ├── devcontainer-feature.json 64 | │ │ └── install.sh 65 | | ├── ... 66 | │ │ ├── devcontainer-feature.json 67 | │ │ └── install.sh 68 | ... 69 | ``` 70 | 71 | An [implementing tool](https://containers.dev/supporting#tools) will composite [the documented dev container properties](https://containers.dev/implementors/features/#devcontainer-feature-json-properties) from the feature's `devcontainer-feature.json` file, and execute in the `install.sh` entrypoint script in the container during build time. Implementing tools are also free to process attributes under the `customizations` property as desired. 72 | 73 | ### Options 74 | 75 | All available options for a Feature should be declared in the `devcontainer-feature.json`. The syntax for the `options` property can be found in the [devcontainer Feature json properties reference](https://containers.dev/implementors/features/#devcontainer-feature-json-properties). 76 | 77 | For example, the `color` feature provides an enum of three possible options (`red`, `gold`, `green`). If no option is provided in a user's `devcontainer.json`, the value is set to "red". 78 | 79 | ```jsonc 80 | { 81 | // ... 82 | "options": { 83 | "favorite": { 84 | "type": "string", 85 | "enum": [ 86 | "red", 87 | "gold", 88 | "green" 89 | ], 90 | "default": "red", 91 | "description": "Choose your favorite color." 92 | } 93 | } 94 | } 95 | ``` 96 | 97 | Options are exported as Feature-scoped environment variables. The option name is captialized and sanitized according to [option resolution](https://containers.dev/implementors/features/#option-resolution). 98 | 99 | ```bash 100 | #!/bin/bash 101 | 102 | echo "Activating feature 'color'" 103 | echo "The provided favorite color is: ${FAVORITE}" 104 | 105 | ... 106 | ``` 107 | 108 | ## Distributing Features 109 | 110 | ### Versioning 111 | 112 | Features are individually versioned by the `version` attribute in a Feature's `devcontainer-feature.json`. Features are versioned according to the semver specification. More details can be found in [the dev container Feature specification](https://containers.dev/implementors/features/#versioning). 113 | 114 | ### Publishing 115 | 116 | > NOTE: The Distribution spec can be [found here](https://containers.dev/implementors/features-distribution/). 117 | > 118 | > While any registry [implementing the OCI Distribution spec](https://github.com/opencontainers/distribution-spec) can be used, this template will leverage GHCR (GitHub Container Registry) as the backing registry. 119 | 120 | Features are meant to be easily sharable units of dev container configuration and installation code. 121 | 122 | This repo contains a **GitHub Action** [workflow](.github/workflows/release.yaml) that will publish each Feature to GHCR. 123 | 124 | *Allow GitHub Actions to create and approve pull requests* should be enabled in the repository's `Settings > Actions > General > Workflow permissions` for auto generation of `src//README.md` per Feature (which merges any existing `src//NOTES.md`). 125 | 126 | By default, each Feature will be prefixed with the `` namespace. For example, the two Features in this repository can be referenced in a `devcontainer.json` with: 127 | 128 | ``` 129 | ghcr.io/devcontainers/feature-starter/color:1 130 | ghcr.io/devcontainers/feature-starter/hello:1 131 | ``` 132 | 133 | The provided GitHub Action will also publish a third "metadata" package with just the namespace, eg: `ghcr.io/devcontainers/feature-starter`. This contains information useful for tools aiding in Feature discovery. 134 | 135 | '`devcontainers/feature-starter`' is known as the feature collection namespace. 136 | 137 | ### Marking Feature Public 138 | 139 | Note that by default, GHCR packages are marked as `private`. To stay within the free tier, Features need to be marked as `public`. 140 | 141 | This can be done by navigating to the Feature's "package settings" page in GHCR, and setting the visibility to 'public`. The URL may look something like: 142 | 143 | ``` 144 | https://github.com/users//packages/container/%2F/settings 145 | ``` 146 | 147 | image 148 | 149 | ### Adding Features to the Index 150 | 151 | If you'd like your Features to appear in our [public index](https://containers.dev/features) so that other community members can find them, you can do the following: 152 | 153 | * Go to [github.com/devcontainers/devcontainers.github.io](https://github.com/devcontainers/devcontainers.github.io) 154 | * This is the GitHub repo backing the [containers.dev](https://containers.dev/) spec site 155 | * Open a PR to modify the [collection-index.yml](https://github.com/devcontainers/devcontainers.github.io/blob/gh-pages/_data/collection-index.yml) file 156 | 157 | This index is from where [supporting tools](https://containers.dev/supporting) like [VS Code Dev Containers](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers) and [GitHub Codespaces](https://github.com/features/codespaces) surface Features for their dev container creation UI. 158 | 159 | #### Using private Features in Codespaces 160 | 161 | For any Features hosted in GHCR that are kept private, the `GITHUB_TOKEN` access token in your environment will need to have `package:read` and `contents:read` for the associated repository. 162 | 163 | Many implementing tools use a broadly scoped access token and will work automatically. GitHub Codespaces uses repo-scoped tokens, and therefore you'll need to add the permissions in `devcontainer.json` 164 | 165 | An example `devcontainer.json` can be found below. 166 | 167 | ```jsonc 168 | { 169 | "image": "mcr.microsoft.com/devcontainers/base:ubuntu", 170 | "features": { 171 | "ghcr.io/my-org/private-features/hello:1": { 172 | "greeting": "Hello" 173 | } 174 | }, 175 | "customizations": { 176 | "codespaces": { 177 | "repositories": { 178 | "my-org/private-features": { 179 | "permissions": { 180 | "packages": "read", 181 | "contents": "read" 182 | } 183 | } 184 | } 185 | } 186 | } 187 | } 188 | ``` 189 | -------------------------------------------------------------------------------- /src/color/README.md: -------------------------------------------------------------------------------- 1 | 2 | # My Favorite Color (color) 3 | 4 | A feature to remind you of your favorite color 5 | 6 | ## Example Usage 7 | 8 | ```json 9 | "features": { 10 | "ghcr.io/devcontainers/feature-starter/color:1": { 11 | "version": "latest" 12 | } 13 | } 14 | ``` 15 | 16 | ## Options 17 | 18 | | Options Id | Description | Type | Default Value | 19 | |-----|-----|-----|-----| 20 | | favorite | Choose your favorite color. | string | red | 21 | 22 | 23 | 24 | --- 25 | 26 | _Note: This file was auto-generated from the [devcontainer-feature.json](https://github.com/devcontainers/feature-starter/blob/main/src/color/devcontainer-feature.json). Add additional notes to a `NOTES.md`._ 27 | -------------------------------------------------------------------------------- /src/color/devcontainer-feature.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "My Favorite Color", 3 | "id": "color", 4 | "version": "1.0.3", 5 | "description": "A feature to remind you of your favorite color", 6 | "options": { 7 | "favorite": { 8 | "type": "string", 9 | "enum": [ 10 | "red", 11 | "gold", 12 | "green" 13 | ], 14 | "default": "red", 15 | "description": "Choose your favorite color." 16 | } 17 | }, 18 | "installsAfter": [ 19 | "ghcr.io/devcontainers/features/common-utils" 20 | ] 21 | } 22 | -------------------------------------------------------------------------------- /src/color/install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | echo "Activating feature 'color'" 5 | echo "The provided favorite color is: ${FAVORITE}" 6 | 7 | 8 | # The 'install.sh' entrypoint script is always executed as the root user. 9 | # 10 | # These following environment variables are passed in by the dev container CLI. 11 | # These may be useful in instances where the context of the final 12 | # remoteUser or containerUser is useful. 13 | # For more details, see https://containers.dev/implementors/features#user-env-var 14 | echo "The effective dev container remoteUser is '$_REMOTE_USER'" 15 | echo "The effective dev container remoteUser's home directory is '$_REMOTE_USER_HOME'" 16 | 17 | echo "The effective dev container containerUser is '$_CONTAINER_USER'" 18 | echo "The effective dev container containerUser's home directory is '$_CONTAINER_USER_HOME'" 19 | 20 | cat > /usr/local/bin/color \ 21 | << EOF 22 | #!/bin/sh 23 | echo "my favorite color is ${FAVORITE}" 24 | EOF 25 | 26 | chmod +x /usr/local/bin/color 27 | -------------------------------------------------------------------------------- /src/hello/README.md: -------------------------------------------------------------------------------- 1 | 2 | # Hello, World! (hello) 3 | 4 | A hello world feature 5 | 6 | ## Example Usage 7 | 8 | ```json 9 | "features": { 10 | "ghcr.io/devcontainers/feature-starter/hello:1": { 11 | "version": "latest" 12 | } 13 | } 14 | ``` 15 | 16 | ## Options 17 | 18 | | Options Id | Description | Type | Default Value | 19 | |-----|-----|-----|-----| 20 | | greeting | Select a pre-made greeting, or enter your own | string | hey | 21 | 22 | 23 | 24 | --- 25 | 26 | _Note: This file was auto-generated from the [devcontainer-feature.json](https://github.com/devcontainers/feature-starter/blob/main/src/hello/devcontainer-feature.json). Add additional notes to a `NOTES.md`._ 27 | -------------------------------------------------------------------------------- /src/hello/devcontainer-feature.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Hello, World!", 3 | "id": "hello", 4 | "version": "1.0.2", 5 | "description": "A hello world feature", 6 | "options": { 7 | "greeting": { 8 | "type": "string", 9 | "proposals": [ 10 | "hey", 11 | "hello", 12 | "hi", 13 | "howdy" 14 | ], 15 | "default": "hey", 16 | "description": "Select a pre-made greeting, or enter your own" 17 | } 18 | }, 19 | "installsAfter": [ 20 | "ghcr.io/devcontainers/features/common-utils" 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /src/hello/install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | echo "Activating feature 'hello'" 5 | 6 | GREETING=${GREETING:-undefined} 7 | echo "The provided greeting is: $GREETING" 8 | 9 | # The 'install.sh' entrypoint script is always executed as the root user. 10 | # 11 | # These following environment variables are passed in by the dev container CLI. 12 | # These may be useful in instances where the context of the final 13 | # remoteUser or containerUser is useful. 14 | # For more details, see https://containers.dev/implementors/features#user-env-var 15 | echo "The effective dev container remoteUser is '$_REMOTE_USER'" 16 | echo "The effective dev container remoteUser's home directory is '$_REMOTE_USER_HOME'" 17 | 18 | echo "The effective dev container containerUser is '$_CONTAINER_USER'" 19 | echo "The effective dev container containerUser's home directory is '$_CONTAINER_USER_HOME'" 20 | 21 | cat > /usr/local/bin/hello \ 22 | << EOF 23 | #!/bin/sh 24 | RED='\033[0;91m' 25 | NC='\033[0m' # No Color 26 | echo "\${RED}${GREETING}, \$(whoami)!\${NC}" 27 | EOF 28 | 29 | chmod +x /usr/local/bin/hello -------------------------------------------------------------------------------- /test/_global/color_and_hello.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # The 'test/_global' folder is a special test folder that is not tied to a single feature. 4 | # 5 | # This test file is executed against a running container constructed 6 | # from the value of 'color_and_hello' in the tests/_global/scenarios.json file. 7 | # 8 | # The value of a scenarios element is any properties available in the 'devcontainer.json'. 9 | # Scenarios are useful for testing specific options in a feature, or to test a combination of features. 10 | # 11 | # This test can be run with the following command (from the root of this repo) 12 | # devcontainer features test --global-scenarios-only . 13 | 14 | set -e 15 | 16 | # Optional: Import test library bundled with the devcontainer CLI 17 | source dev-container-features-test-lib 18 | 19 | echo -e "The result of the 'color' command will be:\n" 20 | color 21 | echo -e "The result of the 'hello' command will be:\n" 22 | hello 23 | echo -e "\n" 24 | 25 | # Feature-specific tests 26 | # The 'check' command comes from the dev-container-features-test-lib. 27 | check "check purple is my favorite color" bash -c "color | grep 'my favorite color is purple'" 28 | check "check I am greeting with 'Greetings'" bash -c "hello | grep 'Greetings, $(whoami)'" 29 | 30 | 31 | # Report result 32 | # If any of the checks above exited with a non-zero exit code, the test will fail. 33 | reportResults 34 | -------------------------------------------------------------------------------- /test/_global/scenarios.json: -------------------------------------------------------------------------------- 1 | { 2 | "color_and_hello": { 3 | "image": "mcr.microsoft.com/devcontainers/base:ubuntu", 4 | "features": { 5 | "color": { 6 | "favorite": "purple" 7 | }, 8 | "hello": { 9 | "greeting": "Greetings" 10 | } 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /test/color/gold.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # This test file will be executed against one of the scenarios devcontainer.json test that 4 | # includes the 'color' feature with "favorite": "gold" option. 5 | 6 | set -e 7 | 8 | # Optional: Import test library bundled with the devcontainer CLI 9 | source dev-container-features-test-lib 10 | 11 | # Feature-specific tests 12 | # The 'check' command comes from the dev-container-features-test-lib. 13 | check "execute command" bash -c "color | grep 'my favorite color is gold'" 14 | 15 | # Report result 16 | # If any of the checks above exited with a non-zero exit code, the test will fail. 17 | reportResults 18 | -------------------------------------------------------------------------------- /test/color/green.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # This test file will be executed against one of the scenarios devcontainer.json test that 4 | # includes the 'color' feature with "favorite": "green" option. 5 | 6 | set -e 7 | 8 | # Optional: Import test library bundled with the devcontainer CLI 9 | source dev-container-features-test-lib 10 | 11 | # Feature-specific tests 12 | # The 'check' command comes from the dev-container-features-test-lib. 13 | check "execute command" bash -c "color | grep 'my favorite color is green'" 14 | 15 | # Report result 16 | # If any of the checks above exited with a non-zero exit code, the test will fail. 17 | reportResults 18 | -------------------------------------------------------------------------------- /test/color/my_favorite_color_is_green.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # This test file will be executed against after building a container with the 4 | # 'my_favorite_color_is_green' scenario in 'test/test/color/scenarios.json'. 5 | # 6 | # For more information, see: https://github.com/devcontainers/cli/blob/main/docs/features/test.md 7 | # 8 | # This scenario first uses the 'common-utils' Features to add a new user 'octocat'. 9 | # It then installs the 'color' Feature with the FAVORITE option set to 'green' (the default FAVORITE value if none provided is 'red'). 10 | # 11 | # 12 | # This test (as well as any of the other scenarios in 'scenarios.json') can be run with the following command: 13 | # 14 | # devcontainer features test \ 15 | # --features color \ 16 | # --skip-autogenerated \ 17 | # /path/to/this/repo 18 | 19 | set -e 20 | 21 | # Optional: Import test library bundled with the devcontainer CLI 22 | # Provides the 'check' and 'reportResults' commands. 23 | source dev-container-features-test-lib 24 | 25 | # Feature-specific tests 26 | # The 'check' command comes from the dev-container-features-test-lib. 27 | check "validate favorite color" color | grep 'my favorite color is green' 28 | 29 | # Report result 30 | # If any of the checks above exited with a non-zero exit code, the test will fail. 31 | reportResults 32 | -------------------------------------------------------------------------------- /test/color/scenarios.json: -------------------------------------------------------------------------------- 1 | { 2 | "my_favorite_color_is_green": { 3 | "image": "mcr.microsoft.com/devcontainers/base:focal", 4 | "features": { 5 | "ghcr.io/devcontainers/features/common-utils:1": { 6 | "installZsh": false, 7 | "installOhMyZsh": false, 8 | "upgradePackages": false, 9 | "username": "octocat" 10 | }, 11 | "color": { 12 | "favorite": "green" 13 | } 14 | }, 15 | "remoteUser": "octocat" 16 | }, 17 | "gold": { 18 | "image": "mcr.microsoft.com/devcontainers/base:ubuntu", 19 | "features": { 20 | "color": { 21 | "favorite": "gold" 22 | } 23 | } 24 | }, 25 | "green": { 26 | "image": "mcr.microsoft.com/devcontainers/base:ubuntu", 27 | "features": { 28 | "color": { 29 | "favorite": "green" 30 | } 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /test/color/test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # This test file will be executed against an auto-generated devcontainer.json that 4 | # includes the 'color' Feature with no options. 5 | # 6 | # For more information, see: https://github.com/devcontainers/cli/blob/main/docs/features/test.md 7 | # 8 | # Eg: 9 | # { 10 | # "image": "<..some-base-image...>", 11 | # "features": { 12 | # "color": {} 13 | # }, 14 | # "remoteUser": "root" 15 | # } 16 | # 17 | # Thus, the value of all options will fall back to the default value in the 18 | # Feature's 'devcontainer-feature.json'. 19 | # For the 'color' feature, that means the default favorite color is 'red'. 20 | # 21 | # These scripts are run as 'root' by default. Although that can be changed 22 | # with the '--remote-user' flag. 23 | # 24 | # This test can be run with the following command: 25 | # 26 | # devcontainer features test \ 27 | # --features color \ 28 | # --remote-user root \ 29 | # --skip-scenarios \ 30 | # --base-image mcr.microsoft.com/devcontainers/base:ubuntu \ 31 | # /path/to/this/repo 32 | 33 | set -e 34 | 35 | # Optional: Import test library bundled with the devcontainer CLI 36 | # See https://github.com/devcontainers/cli/blob/HEAD/docs/features/test.md#dev-container-features-test-lib 37 | # Provides the 'check' and 'reportResults' commands. 38 | source dev-container-features-test-lib 39 | 40 | # Feature-specific tests 41 | # The 'check' command comes from the dev-container-features-test-lib. Syntax is... 42 | # check