Continuous Integration
Continuous Integration
devsy ci builds an ephemeral devcontainer, runs a command inside it, and tears
the workspace down afterwards. It lets you verify that your devcontainer.json
still builds.
How it works
- Resolves an workspace from the current directory (or a given source).
- Builds and starts the devcontainer (equivalent to
devsy up, without launching an IDE or touching your SSH config). - Runs the given command inside the running container.
- Deletes the workspace — always, even when the command fails — unless
--keepis passed.
A non-zero exit from the command propagates as the exit code of devsy ci, so a
failing test or build fails the CI job.
Usage
devsy ci [flags] [workspace-path|workspace-name] -- <cmd> [args...]
Run the test suite inside the devcontainer for the current project:
devsy ci -- make test
Target a specific project folder and pass environment variables:
devsy ci ./service -- npm test
devsy ci --remote-env CI=true --remote-env NODE_ENV=test -- npm test
Select a specific devcontainer config (e.g. a named .devcontainer/<name> profile):
devsy ci --devcontainer id:ci -- make test
Keep the workspace around for debugging when the command fails:
devsy ci --keep -- ./run-integration-tests.sh
Common flags
| Flag | Description |
|---|---|
--run-cmd | Shell command run inside the container via sh -c (alternative to an explicit argv after --). |
--remote-env KEY=VALUE | Set an environment variable in the container at run time. Repeatable. |
--keep | Keep the workspace instead of tearing it down. |
--devcontainer | Select the devcontainer config source: none, image:<ref>, id:<name>, or a path to a devcontainer.json. |
--no-cache | Build without using the cache. |
--cache-from | Reuse a pre-built image as a build cache source. Repeatable. |
--platform | Run the container under a specific platform via emulation (e.g. linux/amd64). |
--workspace-env KEY=VALUE | Env variables available at build and lifecycle time (not just at run time). Repeatable. |
--workspace-env-file | File(s) of KEY=VALUE build/lifecycle env variables. |
--init-env KEY=VALUE | Env variables injected during workspace initialization. Repeatable. |
--secrets-file | JSON file ({"KEY":"value"}) of secrets injected into lifecycle commands. |
--feature-secrets-file | JSON file of secret values for features. |
--secret | Stored Devsy secret to inject, as NAME[,type=env|mount][,target=X]. Repeatable. |
--env | Stored Devsy env var to inject, as NAME[=TARGET]. Repeatable. |
--build-secret | Stored Devsy secret exposed to the build via BuildKit. Repeatable. |
--git-token | Stored Devsy secret with an access token for cloning a private HTTP repository. |
--git-token-username | Username for --git-token (default inferred from the repo host). |
Pre-building and pushing images
devsy ci focuses on running a command. To pre-build and publish a devcontainer
image for reuse as a build cache, use devsy build:
devsy build --repository ghcr.io/my-org/my-devcontainer --tag latest --push
Downstream CI jobs can then reference that image via --cache-from to speed up
builds.
GitHub Actions
Install the CLI, configure the docker provider, then run devsy ci:
name: Devcontainer CI
on:
push:
branches: [main]
pull_request:
jobs:
devcontainer:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install Devsy
run: |
curl -fsSL https://github.com/devsy-org/devsy/releases/latest/download/devsy-linux-amd64 -o /usr/local/bin/devsy
chmod +x /usr/local/bin/devsy
- name: Run CI in devcontainer
run: |
devsy provider add docker && devsy provider use docker
devsy ci -- make test