Skip to content
This repository was archived by the owner on May 15, 2025. It is now read-only.

feat(devcontainers-cli): add devcontainers-cli module #425

Merged
merged 16 commits into from
Apr 16, 2025
Merged
Show file tree
Hide file tree
Changes from 2 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
2 changes: 2 additions & 0 deletions .icons/devcontainers.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
24 changes: 24 additions & 0 deletions devcontainers-cli/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
---
display_name: devcontainers-cli
description: devcontainers-cli module provides an easy way to install @devcontainers/cli into a workspace
icon: ../.icons/devcontainers.svg
verified: true
tags: [devcontainers]
---

# devcontainers-cli

The devcontainers-cli module provides an easy way to install @devcontainers/cli into a workspace. It can be used within any workspace as it runs only if
@devcontainers/cli is not installed yet.
npm is required and should be installed in order for the module to work.


## Examples

```tf
module "devcontainers-cli" {
source = "registry.coder.com/modules/devcontainers-cli/coder"
version = "1.0.0"
agent_id = coder_agent.example.id
}
```
66 changes: 66 additions & 0 deletions devcontainers-cli/main.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import { describe, expect, it } from "bun:test";
import {
execContainer,
executeScriptInContainer,
findResourceInstance,
runContainer,
runTerraformApply,
runTerraformInit,
testRequiredVariables,
type TerraformState,
} from "../test";

const executeScriptInContainerWithNPM = async (
state: TerraformState,
image: string,
shell = "sh",
): Promise<{
exitCode: number;
stdout: string[];
stderr: string[];
}> => {
const instance = findResourceInstance(state, "coder_script");
const id = await runContainer(image);
const respPipx = await execContainer(id, [shell, "-c", "apk add nodejs npm"]);
const resp = await execContainer(id, [shell, "-c", instance.script]);
const stdout = resp.stdout.trim().split("\n");
const stderr = resp.stderr.trim().split("\n");
return {
exitCode: resp.exitCode,
stdout,
stderr,
};
};

describe("devcontainers-cli", async () => {
await runTerraformInit(import.meta.dir);

testRequiredVariables(import.meta.dir, {
agent_id: "some-agent-id",
});

it("misses npm", async () => {
const state = await runTerraformApply(import.meta.dir, {
agent_id: "some-agent-id",
});
const output = await executeScriptInContainer(state, "alpine");
expect(output.exitCode).toBe(1);
expect(output.stdout).toEqual([
"Installing @devcontainers/cli ...",
"npm is not installed, please install npm first",
]);
});

it("installs devcontainers-cli", async () => {
const state = await runTerraformApply(import.meta.dir, {
agent_id: "some-agent-id",
});

const output = await executeScriptInContainerWithNPM(state, "alpine");
expect(output.exitCode).toBe(0);

expect(output.stdout[0]).toEqual("Installing @devcontainers/cli ...");
expect(output.stdout[1]).toEqual("Running npm install -g @devcontainers/cli ...");
expect(output.stdout[4]).toEqual("🥳 @devcontainers/cli has been installed !");
});
});
23 changes: 23 additions & 0 deletions devcontainers-cli/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
terraform {
required_version = ">= 1.0"

required_providers {
coder = {
source = "coder/coder"
version = ">= 0.17"
}
}
}

variable "agent_id" {
type = string
description = "The ID of a Coder agent."
}

resource "coder_script" "devcontainers-cli" {
agent_id = var.agent_id
display_name = "devcontainers-cli"
icon = "/icon/devcontainers.svg"
script = templatefile("${path.module}/run.sh", {})
run_on_start = true
}
22 changes: 22 additions & 0 deletions devcontainers-cli/run.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#!/usr/bin/env sh

echo "Installing @devcontainers/cli ..."

# If @devcontainers/cli is already installed, we can skip
if command -v devcontainers > /dev/null 2>&1; then
echo "🥳 @devcontainers/cli is already installed"
exit 1
fi

# If npm is not installed, we should skip
if ! command -v npm > /dev/null 2>&1; then
echo "npm is not installed, please install npm first"
exit 1
fi

# If @devcontainers/cli is not installed, we should install it
echo "Running npm install -g @devcontainers/cli ..."
npm install -g @devcontainers/cli \
&& echo "🥳 @devcontainers/cli has been installed !"

exit 0
Loading