From 57b04cb2394a0fce5210332449eb288f98b51f35 Mon Sep 17 00:00:00 2001 From: Alex Rosenfeld Date: Wed, 3 Jun 2026 16:53:12 -0400 Subject: [PATCH 1/6] Add support for code-server's workspace query param --- registry/coder/modules/code-server/README.md | 14 ++++++ .../code-server/code-server.tftest.hcl | 43 +++++++++++++++++++ registry/coder/modules/code-server/main.tf | 14 +++++- registry/coder/modules/code-server/run.sh | 24 ++++++++--- 4 files changed, 88 insertions(+), 7 deletions(-) diff --git a/registry/coder/modules/code-server/README.md b/registry/coder/modules/code-server/README.md index 0589ec3d4..d135c6bef 100644 --- a/registry/coder/modules/code-server/README.md +++ b/registry/coder/modules/code-server/README.md @@ -84,6 +84,20 @@ module "code-server" { } ``` +### Open a Workspace File + +Open a [`.code-workspace`](https://coder.com/docs/code-server/FAQ#how-does-code-server-decide-what-workspace-or-folder-to-open) file instead of a folder. `folder` and `workspace` are mutually exclusive. + +```tf +module "code-server" { + count = data.coder_workspace.me.start_count + source = "registry.coder.com/coder/code-server/coder" + version = "1.4.4" + agent_id = coder_agent.example.id + workspace = "/home/coder/project/my.code-workspace" +} +``` + ### Pass Additional Arguments You can pass additional command-line arguments to code-server using the `additional_args` variable. For example, to disable workspace trust: diff --git a/registry/coder/modules/code-server/code-server.tftest.hcl b/registry/coder/modules/code-server/code-server.tftest.hcl index ebbb71755..2db6d16e7 100644 --- a/registry/coder/modules/code-server/code-server.tftest.hcl +++ b/registry/coder/modules/code-server/code-server.tftest.hcl @@ -48,3 +48,46 @@ run "url_with_folder_query" { error_message = "coder_app URL must include encoded folder query param" } } + +run "url_with_workspace_query" { + command = plan + + variables { + agent_id = "foo" + workspace = "/home/coder/project/my.code-workspace" + port = 13337 + } + + assert { + condition = resource.coder_app.code-server.url == "http://localhost:13337/?workspace=%2Fhome%2Fcoder%2Fproject%2Fmy.code-workspace" + error_message = "coder_app URL must include encoded workspace query param" + } +} + +run "url_with_no_target" { + command = plan + + variables { + agent_id = "foo" + port = 13337 + } + + assert { + condition = resource.coder_app.code-server.url == "http://localhost:13337/" + error_message = "coder_app URL must omit query string when neither folder nor workspace is set" + } +} + +run "folder_and_workspace_conflict" { + command = plan + + variables { + agent_id = "foo" + folder = "/home/coder/project" + workspace = "/home/coder/project/my.code-workspace" + } + + expect_failures = [ + resource.coder_script.code-server + ] +} diff --git a/registry/coder/modules/code-server/main.tf b/registry/coder/modules/code-server/main.tf index 090b6a53a..2b64d86a9 100644 --- a/registry/coder/modules/code-server/main.tf +++ b/registry/coder/modules/code-server/main.tf @@ -56,6 +56,12 @@ variable "folder" { default = "" } +variable "workspace" { + type = string + description = "The path to a `.code-workspace` file to open in code-server. Mutually exclusive with `folder`." + default = "" +} + variable "install_prefix" { type = string description = "The prefix to install code-server to." @@ -173,6 +179,7 @@ resource "coder_script" "code-server" { USE_CACHED_EXTENSIONS : var.use_cached_extensions, EXTENSIONS_DIR : var.extensions_dir, FOLDER : var.folder, + WORKSPACE : var.workspace, AUTO_INSTALL_EXTENSIONS : var.auto_install_extensions, ADDITIONAL_ARGS : var.additional_args, }) @@ -188,6 +195,11 @@ resource "coder_script" "code-server" { condition = !var.offline || !var.use_cached error_message = "Offline and Use Cached can not be used together" } + + precondition { + condition = var.folder == "" || var.workspace == "" + error_message = "folder and workspace are mutually exclusive; set at most one" + } } } @@ -195,7 +207,7 @@ resource "coder_app" "code-server" { agent_id = var.agent_id slug = var.slug display_name = var.display_name - url = "http://localhost:${var.port}/${var.folder != "" ? "?folder=${urlencode(var.folder)}" : ""}" + url = "http://localhost:${var.port}/${var.folder != "" ? "?folder=${urlencode(var.folder)}" : var.workspace != "" ? "?workspace=${urlencode(var.workspace)}" : ""}" icon = "/icon/code.svg" subdomain = var.subdomain share = var.share diff --git a/registry/coder/modules/code-server/run.sh b/registry/coder/modules/code-server/run.sh index 33a6972a6..2373ffe43 100644 --- a/registry/coder/modules/code-server/run.sh +++ b/registry/coder/modules/code-server/run.sh @@ -122,15 +122,27 @@ if [ "${AUTO_INSTALL_EXTENSIONS}" = true ]; then exit 0 fi - WORKSPACE_DIR="$HOME" - if [ -n "${FOLDER}" ]; then - WORKSPACE_DIR="${FOLDER}" + RECOMMENDATIONS_FILE="" + RECOMMENDATIONS_QUERY=".recommendations[]" + if [ -n "${WORKSPACE}" ]; then + if [ -f "${WORKSPACE}" ]; then + RECOMMENDATIONS_FILE="${WORKSPACE}" + RECOMMENDATIONS_QUERY=".extensions.recommendations[]?" + fi + else + WORKSPACE_DIR="$HOME" + if [ -n "${FOLDER}" ]; then + WORKSPACE_DIR="${FOLDER}" + fi + if [ -f "$WORKSPACE_DIR/.vscode/extensions.json" ]; then + RECOMMENDATIONS_FILE="$WORKSPACE_DIR/.vscode/extensions.json" + fi fi - if [ -f "$WORKSPACE_DIR/.vscode/extensions.json" ]; then - printf "🧩 Installing extensions from %s/.vscode/extensions.json...\n" "$WORKSPACE_DIR" + if [ -n "$RECOMMENDATIONS_FILE" ]; then + printf "🧩 Installing extensions from %s...\n" "$RECOMMENDATIONS_FILE" # Use sed to remove single-line comments before parsing with jq - extensions=$(sed 's|//.*||g' "$WORKSPACE_DIR"/.vscode/extensions.json | jq -r '.recommendations[]') + extensions=$(sed 's|//.*||g' "$RECOMMENDATIONS_FILE" | jq -r "$RECOMMENDATIONS_QUERY") for extension in $extensions; do if extension_installed "$extension"; then continue From b0b51418c0b64c5dfd0f504b2b9b9e88f11891b1 Mon Sep 17 00:00:00 2001 From: Alex Rosenfeld Date: Wed, 3 Jun 2026 16:53:43 -0400 Subject: [PATCH 2/6] chore: bump module versions (patch) --- registry/coder/modules/code-server/README.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/registry/coder/modules/code-server/README.md b/registry/coder/modules/code-server/README.md index d135c6bef..1d36ca0f2 100644 --- a/registry/coder/modules/code-server/README.md +++ b/registry/coder/modules/code-server/README.md @@ -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.5" 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.5" 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.5" 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.5" agent_id = coder_agent.example.id extensions = ["dracula-theme.theme-dracula"] settings = { @@ -78,7 +78,7 @@ Install multiple extensions from [OpenVSX](https://open-vsx.org/) by adding them 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.5" agent_id = coder_agent.example.id extensions = ["dracula-theme.theme-dracula", "ms-azuretools.vscode-docker"] } @@ -92,7 +92,7 @@ Open a [`.code-workspace`](https://coder.com/docs/code-server/FAQ#how-does-code- 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.5" agent_id = coder_agent.example.id workspace = "/home/coder/project/my.code-workspace" } @@ -106,7 +106,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.5" agent_id = coder_agent.example.id additional_args = "--disable-workspace-trust" } @@ -122,7 +122,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.5" agent_id = coder_agent.example.id use_cached = true extensions = ["dracula-theme.theme-dracula", "ms-azuretools.vscode-docker"] @@ -135,7 +135,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.5" agent_id = coder_agent.example.id offline = true } From 22d1a5dfb636f4f913d35614db53fca65fbea9d8 Mon Sep 17 00:00:00 2001 From: Alex Rosenfeld Date: Fri, 5 Jun 2026 12:24:36 -0400 Subject: [PATCH 3/6] validation blocks Co-authored-by: 35C4n0r <70096901+35C4n0r@users.noreply.github.com> --- registry/coder/modules/code-server/main.tf | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/registry/coder/modules/code-server/main.tf b/registry/coder/modules/code-server/main.tf index 2b64d86a9..cca1727c5 100644 --- a/registry/coder/modules/code-server/main.tf +++ b/registry/coder/modules/code-server/main.tf @@ -1,5 +1,5 @@ terraform { - required_version = ">= 1.0" + required_version = ">= 1.9" required_providers { coder = { @@ -60,8 +60,15 @@ variable "workspace" { type = string description = "The path to a `.code-workspace` file to open in code-server. Mutually exclusive with `folder`." default = "" + validation { + condition = var.workspace == "" || endswith(var.workspace, ".code-workspace") + error_message = "workspace must be a path to a .code-workspace file" + } + validation { + condition = var.folder == "" || var.workspace == "" + error_message = "folder and workspace are mutually exclusive; set at most one" + } } - variable "install_prefix" { type = string description = "The prefix to install code-server to." From aebf9fba5d64e154faf74e73170db06423631cce Mon Sep 17 00:00:00 2001 From: Alex Rosenfeld Date: Fri, 5 Jun 2026 13:11:12 -0400 Subject: [PATCH 4/6] Apply suggestions from code review Co-authored-by: 35C4n0r <70096901+35C4n0r@users.noreply.github.com> --- registry/coder/modules/code-server/code-server.tftest.hcl | 2 +- registry/coder/modules/code-server/run.sh | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/registry/coder/modules/code-server/code-server.tftest.hcl b/registry/coder/modules/code-server/code-server.tftest.hcl index 2db6d16e7..7141712d8 100644 --- a/registry/coder/modules/code-server/code-server.tftest.hcl +++ b/registry/coder/modules/code-server/code-server.tftest.hcl @@ -88,6 +88,6 @@ run "folder_and_workspace_conflict" { } expect_failures = [ - resource.coder_script.code-server + var.workspace ] } diff --git a/registry/coder/modules/code-server/run.sh b/registry/coder/modules/code-server/run.sh index 2373ffe43..5af5a0046 100644 --- a/registry/coder/modules/code-server/run.sh +++ b/registry/coder/modules/code-server/run.sh @@ -128,6 +128,8 @@ if [ "${AUTO_INSTALL_EXTENSIONS}" = true ]; then if [ -f "${WORKSPACE}" ]; then RECOMMENDATIONS_FILE="${WORKSPACE}" RECOMMENDATIONS_QUERY=".extensions.recommendations[]?" + else + echo "⚠️ Workspace file ${WORKSPACE} not found, skipping extension recommendations." fi else WORKSPACE_DIR="$HOME" From 7c1563cbb7b24678c94dda9353d75956c3b9ccb0 Mon Sep 17 00:00:00 2001 From: Alex Rosenfeld Date: Fri, 5 Jun 2026 16:06:03 -0400 Subject: [PATCH 5/6] Apply suggestions from code review Co-authored-by: 35C4n0r <70096901+35C4n0r@users.noreply.github.com> --- .../coder/modules/code-server/code-server.tftest.hcl | 9 +++++++++ registry/coder/modules/code-server/main.tf | 5 ----- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/registry/coder/modules/code-server/code-server.tftest.hcl b/registry/coder/modules/code-server/code-server.tftest.hcl index 7141712d8..209a0f39d 100644 --- a/registry/coder/modules/code-server/code-server.tftest.hcl +++ b/registry/coder/modules/code-server/code-server.tftest.hcl @@ -91,3 +91,12 @@ run "folder_and_workspace_conflict" { var.workspace ] } + +run "workspace_extension_rejected" { + command = plan + variables { + agent_id = "foo" + workspace = "/home/coder/project/settings.json" + } + expect_failures = [var.workspace] +} diff --git a/registry/coder/modules/code-server/main.tf b/registry/coder/modules/code-server/main.tf index cca1727c5..a0cd9c0f3 100644 --- a/registry/coder/modules/code-server/main.tf +++ b/registry/coder/modules/code-server/main.tf @@ -202,11 +202,6 @@ resource "coder_script" "code-server" { condition = !var.offline || !var.use_cached error_message = "Offline and Use Cached can not be used together" } - - precondition { - condition = var.folder == "" || var.workspace == "" - error_message = "folder and workspace are mutually exclusive; set at most one" - } } } From c62642d27b25bf74c8b5d1e42d282059be706e7c Mon Sep 17 00:00:00 2001 From: Alex Rosenfeld Date: Sat, 6 Jun 2026 09:14:08 -0400 Subject: [PATCH 6/6] bump to 1.5.0 --- registry/coder/modules/code-server/README.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/registry/coder/modules/code-server/README.md b/registry/coder/modules/code-server/README.md index 1d36ca0f2..07758fdc7 100644 --- a/registry/coder/modules/code-server/README.md +++ b/registry/coder/modules/code-server/README.md @@ -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.5" + version = "1.5.0" 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.5" + version = "1.5.0" 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.5" + version = "1.5.0" 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.5" + version = "1.5.0" agent_id = coder_agent.example.id extensions = ["dracula-theme.theme-dracula"] settings = { @@ -78,7 +78,7 @@ Install multiple extensions from [OpenVSX](https://open-vsx.org/) by adding them module "code-server" { count = data.coder_workspace.me.start_count source = "registry.coder.com/coder/code-server/coder" - version = "1.4.5" + version = "1.5.0" agent_id = coder_agent.example.id extensions = ["dracula-theme.theme-dracula", "ms-azuretools.vscode-docker"] } @@ -92,7 +92,7 @@ Open a [`.code-workspace`](https://coder.com/docs/code-server/FAQ#how-does-code- module "code-server" { count = data.coder_workspace.me.start_count source = "registry.coder.com/coder/code-server/coder" - version = "1.4.5" + version = "1.5.0" agent_id = coder_agent.example.id workspace = "/home/coder/project/my.code-workspace" } @@ -106,7 +106,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.5" + version = "1.5.0" agent_id = coder_agent.example.id additional_args = "--disable-workspace-trust" } @@ -122,7 +122,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.5" + version = "1.5.0" agent_id = coder_agent.example.id use_cached = true extensions = ["dracula-theme.theme-dracula", "ms-azuretools.vscode-docker"] @@ -135,7 +135,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.5" + version = "1.5.0" agent_id = coder_agent.example.id offline = true }