Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 0 additions & 5 deletions .gitattributes

This file was deleted.

18 changes: 0 additions & 18 deletions .gitignore

This file was deleted.

652 changes: 0 additions & 652 deletions CHANGELOG.md

This file was deleted.

1 change: 0 additions & 1 deletion CODEOWNERS

This file was deleted.

46 changes: 0 additions & 46 deletions CONTRIBUTING.md

This file was deleted.

22 changes: 0 additions & 22 deletions LICENSE.txt

This file was deleted.

225 changes: 33 additions & 192 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,225 +1,66 @@
# Dev Container CLI
# Devcontainer CLI Native Port

This repository is a Rust port of [devcontainer](https://github.com/devcontainers/cli) CLI. Work in progress, use at own risk.
This repository hosts a **project-owned native migration** of the Dev Containers CLI, with compatibility targeted against the upstream TypeScript implementation stored in the `upstream/` git submodule.

## Repository layout and upstream compatibility

This repo now tracks the upstream TypeScript implementation as a git submodule at [`upstream/`](./upstream). The pinned submodule commit is the compatibility baseline for this project: when we say we are compatible with upstream, we mean compatible with that exact revision.
`upstream/` exists so we can track the canonical upstream sources at an exact pinned commit while keeping native-port and migration work reviewable in this repository.

- `upstream/`: unmodified upstream devcontainers/cli sources (baseline under test).
- repository root: project-owned Rust port, migration tooling, compatibility tests, and docs.
- `upstream/`: canonical upstream devcontainers/cli TypeScript baseline.
- repository root: project-owned native implementation, migration checks, docs, and readiness tests.

When updating upstream, prefer an explicit workflow:
1. Bump the `upstream/` submodule commit.
2. Run parity/compatibility tests against the new pinned revision.
3. Fix regressions in project-owned code.
4. Merge once CI is green.
Compatibility contract: this repository targets the **exact** submodule revision pinned at `HEAD:upstream`.

Recommended command sequence:
## Submodule initialization and recovery

```bash
git submodule update --init --recursive
git -C upstream fetch origin
git -C upstream checkout <new-upstream-commit>
git add upstream
git rev-parse HEAD:upstream
npm run check-upstream-compatibility
npm test
```

If `npm run check-upstream-compatibility` reports a commit change, update
[`docs/upstream/compatibility-baseline.json`](./docs/upstream/compatibility-baseline.json)
in the same change after parity checks pass.

If you clone this repository without submodules, initialize them before building/testing:
If you clone this repository without submodules, initialize them before running checks/builds:

```bash
git submodule update --init --recursive
```

To inspect the exact compatibility target currently pinned by this repo:

```bash
git rev-parse HEAD:upstream
```

## Context

A development container allows you to use a container as a full-featured development environment. It can be used to run an application, to separate tools, libraries, or runtimes needed for working with a codebase, and to aid in continuous integration and testing. Dev containers can be run locally or remotely, in a private or public cloud.

![Diagram of inner and outerloop development with dev containers](/images/dev-container-stages.png)

This CLI is in active development. Current status:

- [x] `devcontainer build` - Enables building/pre-building images
- [x] `devcontainer up` - Spins up containers with `devcontainer.json` settings applied
- [x] `devcontainer run-user-commands` - Runs lifecycle commands like `postCreateCommand`
- [x] `devcontainer read-configuration` - Outputs current configuration for workspace
- [x] `devcontainer exec` - Executes a command in a container with `userEnvProbe`, `remoteUser`, `remoteEnv`, and other properties applied
- [x] `devcontainer features <...>` - Tools to assist in authoring and testing [Dev Container Features](https://containers.dev/implementors/features/)
- [x] `devcontainer templates <...>` - Tools to assist in authoring and testing [Dev Container Templates](https://containers.dev/implementors/templates/)
- [ ] `devcontainer stop` - Stops containers
- [ ] `devcontainer down` - Stops and deletes containers

## Try it out

We'd love for you to try out the dev container CLI and let us know what you think. You can quickly try it out in just a few simple steps, either by using the install script, installing its npm package, or building the CLI repo from sources (see "[Build from sources](#build-from-sources)").

### Install script

You can install the CLI with a standalone script that downloads a bundled Node.js runtime, so no pre-installed Node.js is required. It works on Linux and macOS (x64 and arm64):

```bash
curl -fsSL https://raw.githubusercontent.com/devcontainers/cli/main/scripts/install.sh | sh
```

Then add the install location to your PATH:

```bash
export PATH="$HOME/.devcontainers/bin:$PATH"
```

You can also specify a version, a custom install directory, or update/uninstall an existing installation:

```bash
# Install a specific version
sh install.sh --version 0.82.0

# Install to a custom directory
sh install.sh --prefix ~/.local/devcontainers

# Update to latest
sh install.sh --update

# Uninstall
sh install.sh --uninstall
```

### npm install
If tooling reports that `upstream/` is missing/uninitialized, run the same command again and re-run checks.

To install the npm package you will need Python and C/C++ installed to build one of the dependencies (see, e.g., [here](https://github.com/microsoft/vscode/wiki/How-to-Contribute) for instructions).
## Upstream compatibility workflow

```bash
npm install -g @devcontainers/cli
```

Verify you can run the CLI and see its help text:
When updating upstream, use an explicit bump-and-verify flow:

```bash
devcontainer <command>

Commands:
devcontainer up Create and run dev container
devcontainer build [path] Build a dev container image
devcontainer run-user-commands Run user commands
devcontainer read-configuration Read configuration
devcontainer features Features commands
devcontainer templates Templates commands
devcontainer exec <cmd> [args..] Execute a command on a running dev container

Options:
--help Show help [boolean]
--version Show version number [boolean]
git submodule update --init --recursive
git -C upstream fetch origin
git -C upstream checkout <new-upstream-commit>
git add upstream
git rev-parse HEAD:upstream
npm run check-upstream-submodule
npm run check-upstream-compatibility
npm test
```

### Try out the CLI
If the compatibility baseline check reports a commit delta, update:

Once you have the CLI, you can try it out with a sample project, like this [Rust sample](https://github.com/microsoft/vscode-remote-try-rust).
- `docs/upstream/compatibility-baseline.json`

Clone the Rust sample to your machine, and start a dev container with the CLI's `up` command:
## Local development

```bash
git clone https://github.com/microsoft/vscode-remote-try-rust
devcontainer up --workspace-folder <path-to-vscode-remote-try-rust>
```

This will download the container image from a container registry and start the container. Your Rust container should now be running:

```bash
[88 ms] dev-containers-cli 0.1.0.
[165 ms] Start: Run: docker build -f /home/node/vscode-remote-try-rust/.devcontainer/Dockerfile -t vsc-vscode-remote-try-rust-89420ad7399ba74f55921e49cc3ecfd2 --build-arg VARIANT=bullseye /home/node/vscode-remote-try-rust/.devcontainer
[+] Building 0.5s (5/5) FINISHED
=> [internal] load build definition from Dockerfile 0.0s
=> => transferring dockerfile: 38B 0.0s
=> [internal] load .dockerignore 0.0s
=> => transferring context: 2B 0.0s
=> [internal] load metadata for mcr.microsoft.com/vscode/devcontainers/r 0.4s
=> CACHED [1/1] FROM mcr.microsoft.com/vscode/devcontainers/rust:1-bulls 0.0s
=> exporting to image 0.0s
=> => exporting layers 0.0s
=> => writing image sha256:39873ccb81e6fb613975e11e37438eee1d49c963a436d 0.0s
=> => naming to docker.io/library/vsc-vscode-remote-try-rust-89420ad7399 0.0s
[1640 ms] Start: Run: docker run --sig-proxy=false -a STDOUT -a STDERR --mount type=bind,source=/home/node/vscode-remote-try-rust,target=/workspaces/vscode-remote-try-rust -l devcontainer.local_folder=/home/node/vscode-remote-try-rust --cap-add=SYS_PTRACE --security-opt seccomp=unconfined --entrypoint /bin/sh vsc-vscode-remote-try-rust-89420ad7399ba74f55921e49cc3ecfd2-uid -c echo Container started
Container started
{"outcome":"success","containerId":"f0a055ff056c1c1bb99cc09930efbf3a0437c54d9b4644695aa23c1d57b4bd11","remoteUser":"vscode","remoteWorkspaceFolder":"/workspaces/vscode-remote-try-rust"}
```

You can then run commands in this dev container:
Install dependencies and run project tests:

```bash
devcontainer exec --workspace-folder <path-to-vscode-remote-try-rust> cargo run
npm install
npm test
```

This will compile and run the Rust sample, outputting:
Run focused migration/readiness checks:

```bash
[33 ms] dev-containers-cli 0.1.0.
Compiling hello_remote_world v0.1.0 (/workspaces/vscode-remote-try-rust)
Finished dev [unoptimized + debuginfo] target(s) in 1.06s
Running `target/debug/hello_remote_world`
Hello, VS Code Remote - Containers!
{"outcome":"success"}
npm test -- --grep "upstream submodule cutover"
```

Congrats, you've just run the dev container CLI and seen it in action!

## More CLI examples

The [example-usage](./example-usage) folder contains some simple shell scripts to illustrate how the CLI can be used to:

- Inject tools for use inside a development container
- Use a dev container as your CI build environment to build an application (even if it is not deployed as a container)
- Build a container image from a devcontainer.json file that includes [dev container features](https://containers.dev/implementors/features/#devcontainer-json-properties)

## Build from sources

This repository has a [dev container configuration](https://github.com/devcontainers/cli/tree/main/.devcontainer), which you can use to ensure you have the right dependencies installed.

If you have not initialized submodules yet, run:

```sh
git submodule update --init --recursive
```

Compile the CLI with yarn:
```sh
yarn
yarn compile
```

Verify you can run the CLI and see its help text:
```sh
node devcontainer.js --help
```

## Specification

The dev container CLI is part of the [Development Containers Specification](https://github.com/devcontainers/spec). This spec seeks to find ways to enrich existing formats with common development specific settings, tools, and configuration while still providing a simplified, un-orchestrated single container option – so that they can be used as coding environments or for continuous integration and testing.

Learn more on the [dev container spec website](https://devcontainers.github.io/).

## Additional resources

You may review other resources part of the specification in the [`devcontainers` GitHub organization](https://github.com/devcontainers).

### Documentation

- Additional information on using the built-in [Features testing command](./docs/features/test.md).

## Contributing
## Project status

Check out how to contribute to the CLI in [CONTRIBUTING.md](CONTRIBUTING.md).
Current work focuses on:

## License
- native CLI migration and parity tracking,
- upstream submodule cutover guardrails,
- compatibility baseline visibility and CI checks.

This project is under an [MIT license](LICENSE.txt).
See `TODO.md` for phased migration/cutover tracking.
21 changes: 11 additions & 10 deletions TODO.md
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,7 @@ Move all vendored upstream TypeScript CLI sources out of repo root and treat `up
- Added `collectDuplicateUpstreamPaths(...)` + `evaluateUpstreamSubmoduleCutoverReadiness(...)` with tests so duplicate upstream-owned paths outside `upstream/` are detected from filesystem layout.
- [x] Remove duplicated upstream-owned files currently checked in at repository root once replacements are wired.
- Removed root-level duplicated TypeScript sources/tests that are now sourced exclusively from `upstream/` for upstream-owned logic.
- Removed root-level files that were byte-for-byte duplicates of `upstream/` (`CHANGELOG.md`, `CODEOWNERS`, `CONTRIBUTING.md`, `LICENSE.txt`, `ThirdPartyNotices.txt`, `devcontainer.js`, `eslint.config.mjs`, `tsconfig.base.json`, `tsfmt.json`, `yarn.lock`, `.gitignore`, `.gitattributes`).
- [x] Keep only project-owned integration/porting assets at repository root (Rust code, migration docs, compatibility harness, and project-specific tests).
- Root `src/` now contains only migration/readiness contract helpers and project-owned tests.
- [x] Add/refresh `.gitmodules` and contributor guidance so updating upstream is intentional and reviewable.
Expand All @@ -212,16 +213,16 @@ Move all vendored upstream TypeScript CLI sources out of repo root and treat `up
- Expanded `README.md` with a concrete command sequence for submodule bump, compatibility checks, parity tests, and baseline update expectations.

### 4) Documentation updates
- [ ] Update `README.md` with:
- [ ] why `upstream/` exists,
- [ ] how to clone/init submodules,
- [ ] what to run when submodule is not initialized,
- [ ] how compatibility testing maps to the pinned upstream revision.
- [ ] Add/update root `AGENTS.md` with contributor/agent rules for:
- [ ] where upstream code must live (`upstream/` only),
- [ ] where project-owned changes should be made,
- [ ] how to perform/validate submodule bumps.
- [ ] Add a short migration note in changelog or docs index once root-level upstream code is removed.
- [x] Update `README.md` with:
- [x] why `upstream/` exists,
- [x] how to clone/init submodules,
- [x] what to run when submodule is not initialized,
- [x] how compatibility testing maps to the pinned upstream revision.
- [x] Add/update root `AGENTS.md` with contributor/agent rules for:
- [x] where upstream code must live (`upstream/` only),
- [x] where project-owned changes should be made,
- [x] how to perform/validate submodule bumps.
- [x] Add a short migration note in changelog or docs index once root-level upstream code is removed.

### 5) Execution plan and rollout
- [ ] Land this as staged PRs to reduce risk:
Expand Down
Loading