mirror of
https://github.com/coder/registry.git
synced 2026-06-03 04:58:15 +00:00
Compare commits
8 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 11a64e9b08 | |||
| 0fd0d08d2f | |||
| 817238ea64 | |||
| d0ef879e5f | |||
| 872fdbcf35 | |||
| acdbd5777f | |||
| 8bd24f8b44 | |||
| 79cef2ecfc |
@@ -37,7 +37,7 @@ jobs:
|
||||
all:
|
||||
- '**'
|
||||
- name: Set up Terraform
|
||||
uses: coder/coder/.github/actions/setup-tf@f7650296ceb9b020c79cd525ac7bd3c7f252ae1d # v2.31.6
|
||||
uses: coder/coder/.github/actions/setup-tf@1a774ab7ce99063a2e01beb94de3fcbccaf84dbe # v2.31.5
|
||||
- name: Set up Bun
|
||||
uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2
|
||||
with:
|
||||
@@ -87,7 +87,7 @@ jobs:
|
||||
bun-version: latest
|
||||
# Need Terraform for its formatter
|
||||
- name: Install Terraform
|
||||
uses: coder/coder/.github/actions/setup-tf@f7650296ceb9b020c79cd525ac7bd3c7f252ae1d # v2.31.6
|
||||
uses: coder/coder/.github/actions/setup-tf@1a774ab7ce99063a2e01beb94de3fcbccaf84dbe # v2.31.5
|
||||
- name: Install dependencies
|
||||
run: bun install
|
||||
- name: Validate formatting
|
||||
@@ -106,7 +106,7 @@ jobs:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6
|
||||
uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6
|
||||
with:
|
||||
go-version: "1.24.0"
|
||||
- name: Validate contributors
|
||||
|
||||
@@ -15,7 +15,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
- uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6
|
||||
- uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6
|
||||
with:
|
||||
go-version: stable
|
||||
- name: golangci-lint
|
||||
|
||||
@@ -31,7 +31,7 @@ jobs:
|
||||
bun-version: latest
|
||||
|
||||
- name: Set up Terraform
|
||||
uses: coder/coder/.github/actions/setup-tf@f7650296ceb9b020c79cd525ac7bd3c7f252ae1d # v2.31.6
|
||||
uses: coder/coder/.github/actions/setup-tf@1a774ab7ce99063a2e01beb94de3fcbccaf84dbe # v2.31.5
|
||||
|
||||
- name: Install dependencies
|
||||
run: bun install
|
||||
|
||||
@@ -13,7 +13,7 @@ Run [OpenCode](https://opencode.ai) AI coding assistant in your workspace for in
|
||||
```tf
|
||||
module "opencode" {
|
||||
source = "registry.coder.com/coder-labs/opencode/coder"
|
||||
version = "0.1.2"
|
||||
version = "0.1.1"
|
||||
agent_id = coder_agent.main.id
|
||||
workdir = "/home/coder/project"
|
||||
}
|
||||
@@ -34,7 +34,7 @@ resource "coder_ai_task" "task" {
|
||||
|
||||
module "opencode" {
|
||||
source = "registry.coder.com/coder-labs/opencode/coder"
|
||||
version = "0.1.2"
|
||||
version = "0.1.1"
|
||||
agent_id = coder_agent.main.id
|
||||
workdir = "/home/coder/project"
|
||||
|
||||
@@ -89,7 +89,7 @@ Run OpenCode as a command-line tool without web interface or task reporting:
|
||||
```tf
|
||||
module "opencode" {
|
||||
source = "registry.coder.com/coder-labs/opencode/coder"
|
||||
version = "0.1.2"
|
||||
version = "0.1.1"
|
||||
agent_id = coder_agent.main.id
|
||||
workdir = "/home/coder"
|
||||
report_tasks = false
|
||||
|
||||
@@ -39,7 +39,7 @@ install_opencode() {
|
||||
if [ "$ARG_OPENCODE_VERSION" = "latest" ]; then
|
||||
curl -fsSL https://opencode.ai/install | bash
|
||||
else
|
||||
curl -fsSL https://opencode.ai/install | VERSION="${ARG_OPENCODE_VERSION}" bash
|
||||
VERSION=$ARG_OPENCODE_VERSION curl -fsSL https://opencode.ai/install | bash
|
||||
fi
|
||||
export PATH=/home/coder/.opencode/bin:$PATH
|
||||
printf "Opencode location: %s\n" "$(which opencode)"
|
||||
|
||||
@@ -13,7 +13,7 @@ Run the [Claude Code](https://docs.anthropic.com/en/docs/agents-and-tools/claude
|
||||
```tf
|
||||
module "claude-code" {
|
||||
source = "registry.coder.com/coder/claude-code/coder"
|
||||
version = "4.8.2"
|
||||
version = "4.8.1"
|
||||
agent_id = coder_agent.main.id
|
||||
workdir = "/home/coder/project"
|
||||
claude_api_key = "xxxx-xxxxx-xxxx"
|
||||
@@ -60,7 +60,7 @@ By default, when `enable_boundary = true`, the module uses `coder boundary` subc
|
||||
```tf
|
||||
module "claude-code" {
|
||||
source = "registry.coder.com/coder/claude-code/coder"
|
||||
version = "4.8.2"
|
||||
version = "4.8.1"
|
||||
agent_id = coder_agent.main.id
|
||||
workdir = "/home/coder/project"
|
||||
enable_boundary = true
|
||||
@@ -81,7 +81,7 @@ For tasks integration with AI Bridge, add `enable_aibridge = true` to the [Usage
|
||||
```tf
|
||||
module "claude-code" {
|
||||
source = "registry.coder.com/coder/claude-code/coder"
|
||||
version = "4.8.2"
|
||||
version = "4.8.1"
|
||||
agent_id = coder_agent.main.id
|
||||
workdir = "/home/coder/project"
|
||||
enable_aibridge = true
|
||||
@@ -110,7 +110,7 @@ data "coder_task" "me" {}
|
||||
|
||||
module "claude-code" {
|
||||
source = "registry.coder.com/coder/claude-code/coder"
|
||||
version = "4.8.2"
|
||||
version = "4.8.1"
|
||||
agent_id = coder_agent.main.id
|
||||
workdir = "/home/coder/project"
|
||||
ai_prompt = data.coder_task.me.prompt
|
||||
@@ -133,7 +133,7 @@ This example shows additional configuration options for version pinning, custom
|
||||
```tf
|
||||
module "claude-code" {
|
||||
source = "registry.coder.com/coder/claude-code/coder"
|
||||
version = "4.8.2"
|
||||
version = "4.8.1"
|
||||
agent_id = coder_agent.main.id
|
||||
workdir = "/home/coder/project"
|
||||
|
||||
@@ -189,7 +189,7 @@ Run and configure Claude Code as a standalone CLI in your workspace.
|
||||
```tf
|
||||
module "claude-code" {
|
||||
source = "registry.coder.com/coder/claude-code/coder"
|
||||
version = "4.8.2"
|
||||
version = "4.8.1"
|
||||
agent_id = coder_agent.main.id
|
||||
workdir = "/home/coder/project"
|
||||
install_claude_code = true
|
||||
@@ -211,7 +211,7 @@ variable "claude_code_oauth_token" {
|
||||
|
||||
module "claude-code" {
|
||||
source = "registry.coder.com/coder/claude-code/coder"
|
||||
version = "4.8.2"
|
||||
version = "4.8.1"
|
||||
agent_id = coder_agent.main.id
|
||||
workdir = "/home/coder/project"
|
||||
claude_code_oauth_token = var.claude_code_oauth_token
|
||||
@@ -284,7 +284,7 @@ resource "coder_env" "bedrock_api_key" {
|
||||
|
||||
module "claude-code" {
|
||||
source = "registry.coder.com/coder/claude-code/coder"
|
||||
version = "4.8.2"
|
||||
version = "4.8.1"
|
||||
agent_id = coder_agent.main.id
|
||||
workdir = "/home/coder/project"
|
||||
model = "global.anthropic.claude-sonnet-4-5-20250929-v1:0"
|
||||
@@ -341,7 +341,7 @@ resource "coder_env" "google_application_credentials" {
|
||||
|
||||
module "claude-code" {
|
||||
source = "registry.coder.com/coder/claude-code/coder"
|
||||
version = "4.8.2"
|
||||
version = "4.8.1"
|
||||
agent_id = coder_agent.main.id
|
||||
workdir = "/home/coder/project"
|
||||
model = "claude-sonnet-4@20250514"
|
||||
|
||||
@@ -287,7 +287,7 @@ resource "coder_env" "claude_code_oauth_token" {
|
||||
}
|
||||
|
||||
resource "coder_env" "claude_api_key" {
|
||||
count = (var.enable_aibridge || (var.claude_api_key != "")) ? 1 : 0
|
||||
count = local.claude_api_key != "" ? 1 : 0
|
||||
|
||||
agent_id = var.agent_id
|
||||
name = "CLAUDE_API_KEY"
|
||||
|
||||
@@ -416,6 +416,7 @@ run "test_disable_state_persistence" {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
run "test_no_api_key_no_env" {
|
||||
command = plan
|
||||
|
||||
@@ -430,18 +431,3 @@ run "test_no_api_key_no_env" {
|
||||
error_message = "CLAUDE_API_KEY should not be created when no API key is provided and aibridge is disabled"
|
||||
}
|
||||
}
|
||||
|
||||
run "test_api_key_count_with_aibridge_no_override" {
|
||||
command = plan
|
||||
|
||||
variables {
|
||||
agent_id = "test-agent-count"
|
||||
workdir = "/home/coder/test"
|
||||
enable_aibridge = true
|
||||
}
|
||||
|
||||
assert {
|
||||
condition = length(coder_env.claude_api_key) == 1
|
||||
error_message = "CLAUDE_API_KEY env should be created when aibridge is enabled, regardless of session_token value"
|
||||
}
|
||||
}
|
||||
@@ -14,7 +14,7 @@ Automatically install [code-server](https://github.com/coder/code-server) in a w
|
||||
module "code-server" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/code-server/coder"
|
||||
version = "1.4.4"
|
||||
version = "1.4.3"
|
||||
agent_id = coder_agent.example.id
|
||||
}
|
||||
```
|
||||
@@ -29,7 +29,7 @@ module "code-server" {
|
||||
module "code-server" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/code-server/coder"
|
||||
version = "1.4.4"
|
||||
version = "1.4.3"
|
||||
agent_id = coder_agent.example.id
|
||||
install_version = "4.106.3"
|
||||
}
|
||||
@@ -43,7 +43,7 @@ Install the Dracula theme from [OpenVSX](https://open-vsx.org/):
|
||||
module "code-server" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/code-server/coder"
|
||||
version = "1.4.4"
|
||||
version = "1.4.3"
|
||||
agent_id = coder_agent.example.id
|
||||
extensions = [
|
||||
"dracula-theme.theme-dracula"
|
||||
@@ -61,7 +61,7 @@ Configure VS Code's [settings.json](https://code.visualstudio.com/docs/getstarte
|
||||
module "code-server" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/code-server/coder"
|
||||
version = "1.4.4"
|
||||
version = "1.4.3"
|
||||
agent_id = coder_agent.example.id
|
||||
extensions = ["dracula-theme.theme-dracula"]
|
||||
settings = {
|
||||
@@ -72,13 +72,13 @@ module "code-server" {
|
||||
|
||||
### Install multiple extensions
|
||||
|
||||
Install multiple extensions from [OpenVSX](https://open-vsx.org/) by adding them to the `extensions` list:
|
||||
Just run code-server in the background, don't fetch it from GitHub:
|
||||
|
||||
```tf
|
||||
module "code-server" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/code-server/coder"
|
||||
version = "1.4.4"
|
||||
version = "1.4.3"
|
||||
agent_id = coder_agent.example.id
|
||||
extensions = ["dracula-theme.theme-dracula", "ms-azuretools.vscode-docker"]
|
||||
}
|
||||
@@ -92,7 +92,7 @@ You can pass additional command-line arguments to code-server using the `additio
|
||||
module "code-server" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/code-server/coder"
|
||||
version = "1.4.4"
|
||||
version = "1.4.3"
|
||||
agent_id = coder_agent.example.id
|
||||
additional_args = "--disable-workspace-trust"
|
||||
}
|
||||
@@ -108,7 +108,7 @@ Run an existing copy of code-server if found, otherwise download from GitHub:
|
||||
module "code-server" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/code-server/coder"
|
||||
version = "1.4.4"
|
||||
version = "1.4.3"
|
||||
agent_id = coder_agent.example.id
|
||||
use_cached = true
|
||||
extensions = ["dracula-theme.theme-dracula", "ms-azuretools.vscode-docker"]
|
||||
@@ -121,7 +121,7 @@ Just run code-server in the background, don't fetch it from GitHub:
|
||||
module "code-server" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/code-server/coder"
|
||||
version = "1.4.4"
|
||||
version = "1.4.3"
|
||||
agent_id = coder_agent.example.id
|
||||
offline = true
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ Under the hood, this module uses the [coder dotfiles](https://coder.com/docs/v2/
|
||||
module "dotfiles" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/dotfiles/coder"
|
||||
version = "1.4.1"
|
||||
version = "1.4.0"
|
||||
agent_id = coder_agent.example.id
|
||||
}
|
||||
```
|
||||
@@ -31,7 +31,7 @@ module "dotfiles" {
|
||||
module "dotfiles" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/dotfiles/coder"
|
||||
version = "1.4.1"
|
||||
version = "1.4.0"
|
||||
agent_id = coder_agent.example.id
|
||||
}
|
||||
```
|
||||
@@ -42,7 +42,7 @@ module "dotfiles" {
|
||||
module "dotfiles" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/dotfiles/coder"
|
||||
version = "1.4.1"
|
||||
version = "1.4.0"
|
||||
agent_id = coder_agent.example.id
|
||||
user = "root"
|
||||
}
|
||||
@@ -54,14 +54,14 @@ module "dotfiles" {
|
||||
module "dotfiles" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/dotfiles/coder"
|
||||
version = "1.4.1"
|
||||
version = "1.4.0"
|
||||
agent_id = coder_agent.example.id
|
||||
}
|
||||
|
||||
module "dotfiles-root" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/dotfiles/coder"
|
||||
version = "1.4.1"
|
||||
version = "1.4.0"
|
||||
agent_id = coder_agent.example.id
|
||||
user = "root"
|
||||
dotfiles_uri = module.dotfiles.dotfiles_uri
|
||||
@@ -90,7 +90,7 @@ You can set a default dotfiles repository for all users by setting the `default_
|
||||
module "dotfiles" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/dotfiles/coder"
|
||||
version = "1.4.1"
|
||||
version = "1.4.0"
|
||||
agent_id = coder_agent.example.id
|
||||
default_dotfiles_uri = "https://github.com/coder/dotfiles"
|
||||
}
|
||||
|
||||
@@ -56,21 +56,6 @@ describe("dotfiles", async () => {
|
||||
}
|
||||
});
|
||||
|
||||
it("command uses bash for fish shell compatibility", async () => {
|
||||
const state = await runTerraformApply(import.meta.dir, {
|
||||
agent_id: "foo",
|
||||
manual_update: "true",
|
||||
dotfiles_uri: "https://github.com/test/dotfiles",
|
||||
});
|
||||
|
||||
const app = state.resources.find(
|
||||
(r) => r.type === "coder_app" && r.name === "dotfiles",
|
||||
);
|
||||
|
||||
expect(app).toBeDefined();
|
||||
expect(app?.instances[0]?.attributes?.command).toContain("/bin/bash -c");
|
||||
});
|
||||
|
||||
it("set custom order for coder_parameter", async () => {
|
||||
const order = 99;
|
||||
const state = await runTerraformApply(import.meta.dir, {
|
||||
|
||||
@@ -164,12 +164,12 @@ resource "coder_app" "dotfiles" {
|
||||
icon = "/icon/dotfiles.svg"
|
||||
order = var.order
|
||||
group = var.group
|
||||
command = "/bin/bash -c \"$(echo ${base64encode(templatefile("${path.module}/run.sh", {
|
||||
command = templatefile("${path.module}/run.sh", {
|
||||
DOTFILES_URI : local.dotfiles_uri,
|
||||
DOTFILES_USER : local.user,
|
||||
DOTFILES_BRANCH : local.dotfiles_branch,
|
||||
POST_CLONE_SCRIPT : local.encoded_post_clone_script
|
||||
}))} | base64 -d)\""
|
||||
})
|
||||
}
|
||||
|
||||
output "dotfiles_uri" {
|
||||
|
||||
@@ -14,7 +14,7 @@ This module adds JetBrains IDE buttons to launch IDEs directly from the dashboar
|
||||
module "jetbrains" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/jetbrains/coder"
|
||||
version = "1.3.1"
|
||||
version = "1.3.0"
|
||||
agent_id = coder_agent.main.id
|
||||
folder = "/home/coder/project"
|
||||
}
|
||||
@@ -39,7 +39,7 @@ When `default` contains IDE codes, those IDEs are created directly without user
|
||||
module "jetbrains" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/jetbrains/coder"
|
||||
version = "1.3.1"
|
||||
version = "1.3.0"
|
||||
agent_id = coder_agent.main.id
|
||||
folder = "/home/coder/project"
|
||||
default = ["PY", "IU"] # Pre-configure PyCharm and IntelliJ IDEA
|
||||
@@ -52,7 +52,7 @@ module "jetbrains" {
|
||||
module "jetbrains" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/jetbrains/coder"
|
||||
version = "1.3.1"
|
||||
version = "1.3.0"
|
||||
agent_id = coder_agent.main.id
|
||||
folder = "/home/coder/project"
|
||||
# Show parameter with limited options
|
||||
@@ -66,7 +66,7 @@ module "jetbrains" {
|
||||
module "jetbrains" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/jetbrains/coder"
|
||||
version = "1.3.1"
|
||||
version = "1.3.0"
|
||||
agent_id = coder_agent.main.id
|
||||
folder = "/home/coder/project"
|
||||
default = ["IU", "PY"]
|
||||
@@ -81,7 +81,7 @@ module "jetbrains" {
|
||||
module "jetbrains" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/jetbrains/coder"
|
||||
version = "1.3.1"
|
||||
version = "1.3.0"
|
||||
agent_id = coder_agent.main.id
|
||||
folder = "/workspace/project"
|
||||
|
||||
@@ -108,7 +108,7 @@ module "jetbrains" {
|
||||
module "jetbrains_pycharm" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/jetbrains/coder"
|
||||
version = "1.3.1"
|
||||
version = "1.3.0"
|
||||
agent_id = coder_agent.main.id
|
||||
folder = "/workspace/project"
|
||||
|
||||
@@ -128,7 +128,7 @@ Add helpful tooltip text that appears when users hover over the IDE app buttons:
|
||||
module "jetbrains" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/jetbrains/coder"
|
||||
version = "1.3.1"
|
||||
version = "1.3.0"
|
||||
agent_id = coder_agent.main.id
|
||||
folder = "/home/coder/project"
|
||||
default = ["IU", "PY"]
|
||||
|
||||
@@ -125,7 +125,7 @@ variable "download_base_link" {
|
||||
}
|
||||
|
||||
data "http" "jetbrains_ide_versions" {
|
||||
for_each = local.selected_ides
|
||||
for_each = length(var.default) == 0 ? var.options : var.default
|
||||
url = "${var.releases_base_link}/products/releases?code=${each.key}&type=${var.channel}${var.major_version == "latest" ? "&latest=true" : ""}"
|
||||
}
|
||||
|
||||
@@ -174,14 +174,9 @@ variable "ide_config" {
|
||||
}
|
||||
|
||||
locals {
|
||||
# Determine the user's actual IDE selection.
|
||||
# This is computed before the HTTP data source so that version lookups
|
||||
# are only performed for IDEs the user chose — not every option.
|
||||
selected_ides = length(var.default) == 0 ? toset(jsondecode(coalesce(data.coder_parameter.jetbrains_ides[0].value, "[]"))) : toset(var.default)
|
||||
|
||||
# Parse HTTP responses once with error handling for air-gapped environments
|
||||
parsed_responses = {
|
||||
for code in local.selected_ides : code => try(
|
||||
for code in length(var.default) == 0 ? var.options : var.default : code => try(
|
||||
jsondecode(data.http.jetbrains_ide_versions[code].response_body),
|
||||
{} # Return empty object if API call fails
|
||||
)
|
||||
@@ -189,7 +184,7 @@ locals {
|
||||
|
||||
# Filter the parsed response for the requested major version if not "latest"
|
||||
filtered_releases = {
|
||||
for code in local.selected_ides : code => [
|
||||
for code in length(var.default) == 0 ? var.options : var.default : code => [
|
||||
for r in try(local.parsed_responses[code][keys(local.parsed_responses[code])[0]], []) :
|
||||
r if var.major_version == "latest" || r.majorVersion == var.major_version
|
||||
]
|
||||
@@ -197,13 +192,13 @@ locals {
|
||||
|
||||
# Select the latest release for the requested major version (first item in the filtered list)
|
||||
selected_releases = {
|
||||
for code in local.selected_ides : code =>
|
||||
for code in length(var.default) == 0 ? var.options : var.default : code =>
|
||||
length(local.filtered_releases[code]) > 0 ? local.filtered_releases[code][0] : null
|
||||
}
|
||||
|
||||
# Dynamically generate IDE configurations based on selected IDEs with fallback to ide_config
|
||||
# Dynamically generate IDE configurations based on options with fallback to ide_config
|
||||
options_metadata = {
|
||||
for code in local.selected_ides : code => {
|
||||
for code in length(var.default) == 0 ? var.options : var.default : code => {
|
||||
icon = var.ide_config[code].icon
|
||||
name = var.ide_config[code].name
|
||||
identifier = code
|
||||
@@ -216,6 +211,9 @@ locals {
|
||||
json_data = local.selected_releases[code]
|
||||
}
|
||||
}
|
||||
|
||||
# Convert the parameter value to a set for for_each
|
||||
selected_ides = length(var.default) == 0 ? toset(jsondecode(coalesce(data.coder_parameter.jetbrains_ides[0].value, "[]"))) : toset(var.default)
|
||||
}
|
||||
|
||||
data "coder_parameter" "jetbrains_ides" {
|
||||
|
||||
@@ -15,7 +15,7 @@ Automatically installs [Node.js](https://github.com/nodejs/node) via [`nvm`](htt
|
||||
module "nodejs" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/thezoker/nodejs/coder"
|
||||
version = "1.0.13"
|
||||
version = "1.1.0"
|
||||
agent_id = coder_agent.example.id
|
||||
}
|
||||
```
|
||||
@@ -28,17 +28,55 @@ This installs multiple versions of Node.js:
|
||||
module "nodejs" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/thezoker/nodejs/coder"
|
||||
version = "1.0.13"
|
||||
version = "1.1.0"
|
||||
agent_id = coder_agent.example.id
|
||||
node_versions = [
|
||||
"18",
|
||||
"20",
|
||||
"node"
|
||||
]
|
||||
default_node_version = "1.0.13"
|
||||
default_node_version = "20"
|
||||
}
|
||||
```
|
||||
|
||||
## Pre and Post Install Scripts
|
||||
|
||||
Use `pre_install_script` and `post_install_script` to run custom scripts before and after Node.js installation.
|
||||
|
||||
```tf
|
||||
module "nodejs" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/thezoker/nodejs/coder"
|
||||
version = "1.1.0"
|
||||
agent_id = coder_agent.example.id
|
||||
|
||||
pre_install_script = "echo 'Setting up prerequisites...'"
|
||||
post_install_script = "npm install -g yarn pnpm"
|
||||
}
|
||||
```
|
||||
|
||||
## Cross-Module Dependency Ordering
|
||||
|
||||
This module uses `coder exp sync` to coordinate execution ordering with other modules. It exposes the following outputs for use with `coder exp sync want`:
|
||||
|
||||
- `install_script_name` — the sync name for the main Node.js installation script
|
||||
- `pre_install_script_name` — the sync name for the pre-install script
|
||||
- `post_install_script_name` — the sync name for the post-install script
|
||||
|
||||
For example, to ensure another module waits for Node.js to be fully installed:
|
||||
|
||||
```tf
|
||||
module "nodejs" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/thezoker/nodejs/coder"
|
||||
version = "1.1.0"
|
||||
agent_id = coder_agent.example.id
|
||||
}
|
||||
|
||||
# In another module's coder_script, wait for Node.js installation:
|
||||
# coder exp sync want my-script ${module.nodejs[0].install_script_name}
|
||||
```
|
||||
|
||||
## Full example
|
||||
|
||||
A example with all available options:
|
||||
@@ -47,15 +85,17 @@ A example with all available options:
|
||||
module "nodejs" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/thezoker/nodejs/coder"
|
||||
version = "1.0.13"
|
||||
version = "1.1.0"
|
||||
agent_id = coder_agent.example.id
|
||||
nvm_version = "1.0.13"
|
||||
nvm_version = "v0.39.7"
|
||||
nvm_install_prefix = "/opt/nvm"
|
||||
node_versions = [
|
||||
"16",
|
||||
"18",
|
||||
"20",
|
||||
"node"
|
||||
]
|
||||
default_node_version = "1.0.13"
|
||||
default_node_version = "20"
|
||||
pre_install_script = "echo 'Pre-install setup'"
|
||||
post_install_script = "npm install -g typescript"
|
||||
}
|
||||
```
|
||||
|
||||
@@ -38,15 +38,125 @@ variable "default_node_version" {
|
||||
default = "node"
|
||||
}
|
||||
|
||||
resource "coder_script" "nodejs" {
|
||||
agent_id = var.agent_id
|
||||
display_name = "Node.js:"
|
||||
script = templatefile("${path.module}/run.sh", {
|
||||
NVM_VERSION : var.nvm_version,
|
||||
INSTALL_PREFIX : var.nvm_install_prefix,
|
||||
NODE_VERSIONS : join(",", var.node_versions),
|
||||
DEFAULT : var.default_node_version,
|
||||
variable "pre_install_script" {
|
||||
type = string
|
||||
description = "Custom script to run before installing Node.js."
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "post_install_script" {
|
||||
type = string
|
||||
description = "Custom script to run after installing Node.js."
|
||||
default = null
|
||||
}
|
||||
|
||||
locals {
|
||||
encoded_pre_install_script = var.pre_install_script != null ? base64encode(var.pre_install_script) : ""
|
||||
encoded_post_install_script = var.post_install_script != null ? base64encode(var.post_install_script) : ""
|
||||
|
||||
install_script = templatefile("${path.module}/run.sh", {
|
||||
NVM_VERSION = var.nvm_version,
|
||||
INSTALL_PREFIX = var.nvm_install_prefix,
|
||||
NODE_VERSIONS = join(",", var.node_versions),
|
||||
DEFAULT = var.default_node_version,
|
||||
})
|
||||
encoded_install_script = base64encode(local.install_script)
|
||||
|
||||
pre_install_script_name = "nodejs-pre_install_script"
|
||||
install_script_name = "nodejs-install_script"
|
||||
post_install_script_name = "nodejs-post_install_script"
|
||||
|
||||
module_dir_path = "$HOME/.nodejs-module"
|
||||
|
||||
pre_install_path = "${local.module_dir_path}/pre_install.sh"
|
||||
pre_install_log_path = "${local.module_dir_path}/pre_install.log"
|
||||
install_path = "${local.module_dir_path}/install.sh"
|
||||
install_log_path = "${local.module_dir_path}/install.log"
|
||||
post_install_path = "${local.module_dir_path}/post_install.sh"
|
||||
post_install_log_path = "${local.module_dir_path}/post_install.log"
|
||||
}
|
||||
|
||||
resource "coder_script" "pre_install_script" {
|
||||
count = var.pre_install_script == null ? 0 : 1
|
||||
agent_id = var.agent_id
|
||||
display_name = "Node.js: Pre-Install"
|
||||
run_on_start = true
|
||||
script = <<-EOT
|
||||
#!/bin/bash
|
||||
set -o errexit
|
||||
set -o pipefail
|
||||
|
||||
mkdir -p ${local.module_dir_path}
|
||||
|
||||
trap 'coder exp sync complete ${local.pre_install_script_name}' EXIT
|
||||
coder exp sync start ${local.pre_install_script_name}
|
||||
|
||||
echo -n '${local.encoded_pre_install_script}' | base64 -d > ${local.pre_install_path}
|
||||
chmod +x ${local.pre_install_path}
|
||||
|
||||
${local.pre_install_path} 2>&1 | tee ${local.pre_install_log_path}
|
||||
EOT
|
||||
}
|
||||
|
||||
resource "coder_script" "nodejs" {
|
||||
agent_id = var.agent_id
|
||||
display_name = "Node.js: Install"
|
||||
script = <<-EOT
|
||||
#!/bin/bash
|
||||
set -o errexit
|
||||
set -o pipefail
|
||||
|
||||
mkdir -p ${local.module_dir_path}
|
||||
|
||||
trap 'coder exp sync complete ${local.install_script_name}' EXIT
|
||||
%{if var.pre_install_script != null~}
|
||||
coder exp sync want ${local.install_script_name} ${local.pre_install_script_name}
|
||||
%{endif~}
|
||||
coder exp sync start ${local.install_script_name}
|
||||
|
||||
echo -n '${local.encoded_install_script}' | base64 -d > ${local.install_path}
|
||||
chmod +x ${local.install_path}
|
||||
|
||||
${local.install_path} 2>&1 | tee ${local.install_log_path}
|
||||
EOT
|
||||
run_on_start = true
|
||||
start_blocks_login = true
|
||||
}
|
||||
|
||||
resource "coder_script" "post_install_script" {
|
||||
count = var.post_install_script != null ? 1 : 0
|
||||
agent_id = var.agent_id
|
||||
display_name = "Node.js: Post-Install"
|
||||
run_on_start = true
|
||||
script = <<-EOT
|
||||
#!/bin/bash
|
||||
set -o errexit
|
||||
set -o pipefail
|
||||
|
||||
mkdir -p ${local.module_dir_path}
|
||||
|
||||
trap 'coder exp sync complete ${local.post_install_script_name}' EXIT
|
||||
coder exp sync want ${local.post_install_script_name} ${local.install_script_name}
|
||||
coder exp sync start ${local.post_install_script_name}
|
||||
|
||||
echo -n '${local.encoded_post_install_script}' | base64 -d > ${local.post_install_path}
|
||||
chmod +x ${local.post_install_path}
|
||||
|
||||
${local.post_install_path} 2>&1 | tee ${local.post_install_log_path}
|
||||
EOT
|
||||
}
|
||||
|
||||
output "pre_install_script_name" {
|
||||
description = "The name of the pre-install script for coder exp sync coordination."
|
||||
value = local.pre_install_script_name
|
||||
}
|
||||
|
||||
output "install_script_name" {
|
||||
description = "The name of the install script for coder exp sync coordination."
|
||||
value = local.install_script_name
|
||||
}
|
||||
|
||||
output "post_install_script_name" {
|
||||
description = "The name of the post-install script for coder exp sync coordination."
|
||||
value = local.post_install_script_name
|
||||
}
|
||||
|
||||
@@ -0,0 +1,137 @@
|
||||
run "test_nodejs_basic" {
|
||||
command = plan
|
||||
|
||||
variables {
|
||||
agent_id = "test-agent-123"
|
||||
}
|
||||
|
||||
assert {
|
||||
condition = var.agent_id == "test-agent-123"
|
||||
error_message = "Agent ID variable should be set correctly"
|
||||
}
|
||||
|
||||
assert {
|
||||
condition = var.nvm_version == "master"
|
||||
error_message = "nvm_version should default to master"
|
||||
}
|
||||
|
||||
assert {
|
||||
condition = var.default_node_version == "node"
|
||||
error_message = "default_node_version should default to node"
|
||||
}
|
||||
|
||||
assert {
|
||||
condition = var.pre_install_script == null
|
||||
error_message = "pre_install_script should default to null"
|
||||
}
|
||||
|
||||
assert {
|
||||
condition = var.post_install_script == null
|
||||
error_message = "post_install_script should default to null"
|
||||
}
|
||||
|
||||
assert {
|
||||
condition = output.install_script_name == "nodejs-install_script"
|
||||
error_message = "install_script_name output should be set"
|
||||
}
|
||||
}
|
||||
|
||||
run "test_with_scripts" {
|
||||
command = plan
|
||||
|
||||
variables {
|
||||
agent_id = "test-agent-scripts"
|
||||
pre_install_script = "echo 'Pre-install script'"
|
||||
post_install_script = "echo 'Post-install script'"
|
||||
}
|
||||
|
||||
assert {
|
||||
condition = var.pre_install_script == "echo 'Pre-install script'"
|
||||
error_message = "Pre-install script should be set correctly"
|
||||
}
|
||||
|
||||
assert {
|
||||
condition = var.post_install_script == "echo 'Post-install script'"
|
||||
error_message = "Post-install script should be set correctly"
|
||||
}
|
||||
|
||||
assert {
|
||||
condition = output.pre_install_script_name == "nodejs-pre_install_script"
|
||||
error_message = "pre_install_script_name output should be set"
|
||||
}
|
||||
|
||||
assert {
|
||||
condition = output.post_install_script_name == "nodejs-post_install_script"
|
||||
error_message = "post_install_script_name output should be set"
|
||||
}
|
||||
}
|
||||
|
||||
run "test_custom_options" {
|
||||
command = plan
|
||||
|
||||
variables {
|
||||
agent_id = "test-agent-custom"
|
||||
nvm_version = "v0.39.7"
|
||||
nvm_install_prefix = ".custom-nvm"
|
||||
node_versions = ["18", "20", "node"]
|
||||
default_node_version = "20"
|
||||
}
|
||||
|
||||
assert {
|
||||
condition = var.nvm_version == "v0.39.7"
|
||||
error_message = "nvm_version should be set to v0.39.7"
|
||||
}
|
||||
|
||||
assert {
|
||||
condition = var.nvm_install_prefix == ".custom-nvm"
|
||||
error_message = "nvm_install_prefix should be set correctly"
|
||||
}
|
||||
|
||||
assert {
|
||||
condition = length(var.node_versions) == 3
|
||||
error_message = "node_versions should have 3 entries"
|
||||
}
|
||||
|
||||
assert {
|
||||
condition = var.default_node_version == "20"
|
||||
error_message = "default_node_version should be set to 20"
|
||||
}
|
||||
}
|
||||
|
||||
run "test_with_pre_install_only" {
|
||||
command = plan
|
||||
|
||||
variables {
|
||||
agent_id = "test-agent-pre"
|
||||
pre_install_script = "echo 'pre-install'"
|
||||
}
|
||||
|
||||
assert {
|
||||
condition = var.pre_install_script != null
|
||||
error_message = "Pre-install script should be set"
|
||||
}
|
||||
|
||||
assert {
|
||||
condition = var.post_install_script == null
|
||||
error_message = "Post-install script should default to null"
|
||||
}
|
||||
}
|
||||
|
||||
run "test_with_post_install_only" {
|
||||
command = plan
|
||||
|
||||
variables {
|
||||
agent_id = "test-agent-post"
|
||||
post_install_script = "echo 'post-install'"
|
||||
}
|
||||
|
||||
assert {
|
||||
condition = var.pre_install_script == null
|
||||
error_message = "Pre-install script should default to null"
|
||||
}
|
||||
|
||||
assert {
|
||||
condition = var.post_install_script != null
|
||||
error_message = "Post-install script should be set"
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user