mirror of
https://github.com/coder/registry.git
synced 2026-06-02 20:48:14 +00:00
feat(coder/modules/jetbrains): update to latest build numbers and clean up tests (#636)
Co-authored-by: DevCats <christofer@coder.com>
This commit is contained in:
@@ -14,10 +14,9 @@ This module adds JetBrains IDE buttons to launch IDEs directly from the dashboar
|
|||||||
module "jetbrains" {
|
module "jetbrains" {
|
||||||
count = data.coder_workspace.me.start_count
|
count = data.coder_workspace.me.start_count
|
||||||
source = "registry.coder.com/coder/jetbrains/coder"
|
source = "registry.coder.com/coder/jetbrains/coder"
|
||||||
version = "1.2.1"
|
version = "1.3.0"
|
||||||
agent_id = coder_agent.main.id
|
agent_id = coder_agent.main.id
|
||||||
folder = "/home/coder/project"
|
folder = "/home/coder/project"
|
||||||
# tooltip = "You need to [Install Coder Desktop](https://coder.com/docs/user-guides/desktop#install-coder-desktop) to use this button." # Optional
|
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -40,7 +39,7 @@ When `default` contains IDE codes, those IDEs are created directly without user
|
|||||||
module "jetbrains" {
|
module "jetbrains" {
|
||||||
count = data.coder_workspace.me.start_count
|
count = data.coder_workspace.me.start_count
|
||||||
source = "registry.coder.com/coder/jetbrains/coder"
|
source = "registry.coder.com/coder/jetbrains/coder"
|
||||||
version = "1.2.1"
|
version = "1.3.0"
|
||||||
agent_id = coder_agent.main.id
|
agent_id = coder_agent.main.id
|
||||||
folder = "/home/coder/project"
|
folder = "/home/coder/project"
|
||||||
default = ["PY", "IU"] # Pre-configure GoLand and IntelliJ IDEA
|
default = ["PY", "IU"] # Pre-configure GoLand and IntelliJ IDEA
|
||||||
@@ -53,7 +52,7 @@ module "jetbrains" {
|
|||||||
module "jetbrains" {
|
module "jetbrains" {
|
||||||
count = data.coder_workspace.me.start_count
|
count = data.coder_workspace.me.start_count
|
||||||
source = "registry.coder.com/coder/jetbrains/coder"
|
source = "registry.coder.com/coder/jetbrains/coder"
|
||||||
version = "1.2.1"
|
version = "1.3.0"
|
||||||
agent_id = coder_agent.main.id
|
agent_id = coder_agent.main.id
|
||||||
folder = "/home/coder/project"
|
folder = "/home/coder/project"
|
||||||
# Show parameter with limited options
|
# Show parameter with limited options
|
||||||
@@ -67,7 +66,7 @@ module "jetbrains" {
|
|||||||
module "jetbrains" {
|
module "jetbrains" {
|
||||||
count = data.coder_workspace.me.start_count
|
count = data.coder_workspace.me.start_count
|
||||||
source = "registry.coder.com/coder/jetbrains/coder"
|
source = "registry.coder.com/coder/jetbrains/coder"
|
||||||
version = "1.2.1"
|
version = "1.3.0"
|
||||||
agent_id = coder_agent.main.id
|
agent_id = coder_agent.main.id
|
||||||
folder = "/home/coder/project"
|
folder = "/home/coder/project"
|
||||||
default = ["IU", "PY"]
|
default = ["IU", "PY"]
|
||||||
@@ -82,7 +81,7 @@ module "jetbrains" {
|
|||||||
module "jetbrains" {
|
module "jetbrains" {
|
||||||
count = data.coder_workspace.me.start_count
|
count = data.coder_workspace.me.start_count
|
||||||
source = "registry.coder.com/coder/jetbrains/coder"
|
source = "registry.coder.com/coder/jetbrains/coder"
|
||||||
version = "1.2.1"
|
version = "1.3.0"
|
||||||
agent_id = coder_agent.main.id
|
agent_id = coder_agent.main.id
|
||||||
folder = "/workspace/project"
|
folder = "/workspace/project"
|
||||||
|
|
||||||
@@ -109,7 +108,7 @@ module "jetbrains" {
|
|||||||
module "jetbrains_pycharm" {
|
module "jetbrains_pycharm" {
|
||||||
count = data.coder_workspace.me.start_count
|
count = data.coder_workspace.me.start_count
|
||||||
source = "registry.coder.com/coder/jetbrains/coder"
|
source = "registry.coder.com/coder/jetbrains/coder"
|
||||||
version = "1.2.1"
|
version = "1.3.0"
|
||||||
agent_id = coder_agent.main.id
|
agent_id = coder_agent.main.id
|
||||||
folder = "/workspace/project"
|
folder = "/workspace/project"
|
||||||
|
|
||||||
@@ -129,11 +128,11 @@ Add helpful tooltip text that appears when users hover over the IDE app buttons:
|
|||||||
module "jetbrains" {
|
module "jetbrains" {
|
||||||
count = data.coder_workspace.me.start_count
|
count = data.coder_workspace.me.start_count
|
||||||
source = "registry.coder.com/coder/jetbrains/coder"
|
source = "registry.coder.com/coder/jetbrains/coder"
|
||||||
version = "1.2.1"
|
version = "1.3.0"
|
||||||
agent_id = coder_agent.main.id
|
agent_id = coder_agent.main.id
|
||||||
folder = "/home/coder/project"
|
folder = "/home/coder/project"
|
||||||
default = ["IU", "PY"]
|
default = ["IU", "PY"]
|
||||||
tooltip = "You need to [Install Coder Desktop](https://coder.com/docs/user-guides/desktop#install-coder-desktop) to use this button."
|
tooltip = "You need to install [JetBrains Toolbox App](https://www.jetbrains.com/toolbox-app/) to use this button."
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -170,13 +169,6 @@ resource "coder_metadata" "container_info" {
|
|||||||
- If the API is unreachable (air-gapped environments), the module automatically falls back to build numbers from `ide_config`
|
- If the API is unreachable (air-gapped environments), the module automatically falls back to build numbers from `ide_config`
|
||||||
- `major_version` and `channel` control which API endpoint is queried (when API access is available)
|
- `major_version` and `channel` control which API endpoint is queried (when API access is available)
|
||||||
|
|
||||||
### Tooltip
|
|
||||||
|
|
||||||
- **`tooltip`**: Optional markdown text displayed when hovering over IDE app buttons
|
|
||||||
- If not specified, no tooltip is shown
|
|
||||||
- Supports markdown formatting for rich text (bold, italic, links, etc.)
|
|
||||||
- All IDE apps created by this module will show the same tooltip text
|
|
||||||
|
|
||||||
## Supported IDEs
|
## Supported IDEs
|
||||||
|
|
||||||
All JetBrains IDEs with remote development capabilities:
|
All JetBrains IDEs with remote development capabilities:
|
||||||
|
|||||||
@@ -2,15 +2,15 @@ variables {
|
|||||||
# Default IDE config, mirrored from main.tf for test assertions.
|
# Default IDE config, mirrored from main.tf for test assertions.
|
||||||
# If main.tf defaults change, update this map to match.
|
# If main.tf defaults change, update this map to match.
|
||||||
expected_ide_config = {
|
expected_ide_config = {
|
||||||
"CL" = { name = "CLion", icon = "/icon/clion.svg", build = "251.26927.39" },
|
"CL" = { name = "CLion", icon = "/icon/clion.svg", build = "253.29346.141" },
|
||||||
"GO" = { name = "GoLand", icon = "/icon/goland.svg", build = "251.26927.50" },
|
"GO" = { name = "GoLand", icon = "/icon/goland.svg", build = "253.28294.337" },
|
||||||
"IU" = { name = "IntelliJ IDEA", icon = "/icon/intellij.svg", build = "251.26927.53" },
|
"IU" = { name = "IntelliJ IDEA", icon = "/icon/intellij.svg", build = "253.29346.138" },
|
||||||
"PS" = { name = "PhpStorm", icon = "/icon/phpstorm.svg", build = "251.26927.60" },
|
"PS" = { name = "PhpStorm", icon = "/icon/phpstorm.svg", build = "253.29346.151" },
|
||||||
"PY" = { name = "PyCharm", icon = "/icon/pycharm.svg", build = "251.26927.74" },
|
"PY" = { name = "PyCharm", icon = "/icon/pycharm.svg", build = "253.29346.142" },
|
||||||
"RD" = { name = "Rider", icon = "/icon/rider.svg", build = "251.26927.67" },
|
"RD" = { name = "Rider", icon = "/icon/rider.svg", build = "253.29346.144" },
|
||||||
"RM" = { name = "RubyMine", icon = "/icon/rubymine.svg", build = "251.26927.47" },
|
"RM" = { name = "RubyMine", icon = "/icon/rubymine.svg", build = "253.29346.140" },
|
||||||
"RR" = { name = "RustRover", icon = "/icon/rustrover.svg", build = "251.26927.79" },
|
"RR" = { name = "RustRover", icon = "/icon/rustrover.svg", build = "253.29346.139" },
|
||||||
"WS" = { name = "WebStorm", icon = "/icon/webstorm.svg", build = "251.26927.40" }
|
"WS" = { name = "WebStorm", icon = "/icon/webstorm.svg", build = "253.29346.143" }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -187,16 +187,16 @@ run "tooltip_when_provided" {
|
|||||||
agent_id = "foo"
|
agent_id = "foo"
|
||||||
folder = "/home/coder"
|
folder = "/home/coder"
|
||||||
default = ["GO"]
|
default = ["GO"]
|
||||||
tooltip = "You need to [Install Coder Desktop](https://coder.com/docs/user-guides/desktop#install-coder-desktop) to use this button."
|
tooltip = "You need to install [JetBrains Toolbox App](https://www.jetbrains.com/toolbox-app/) to use this button."
|
||||||
}
|
}
|
||||||
|
|
||||||
assert {
|
assert {
|
||||||
condition = anytrue([for app in values(resource.coder_app.jetbrains) : app.tooltip == "You need to [Install Coder Desktop](https://coder.com/docs/user-guides/desktop#install-coder-desktop) to use this button."])
|
condition = anytrue([for app in values(resource.coder_app.jetbrains) : app.tooltip == "You need to install [JetBrains Toolbox App](https://www.jetbrains.com/toolbox-app/) to use this button."])
|
||||||
error_message = "Expected coder_app tooltip to be set when provided"
|
error_message = "Expected coder_app tooltip to be set when provided"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
run "tooltip_null_when_not_provided" {
|
run "tooltip_default_when_not_provided" {
|
||||||
command = plan
|
command = plan
|
||||||
|
|
||||||
variables {
|
variables {
|
||||||
@@ -206,8 +206,41 @@ run "tooltip_null_when_not_provided" {
|
|||||||
}
|
}
|
||||||
|
|
||||||
assert {
|
assert {
|
||||||
condition = anytrue([for app in values(resource.coder_app.jetbrains) : app.tooltip == null])
|
condition = anytrue([for app in values(resource.coder_app.jetbrains) : app.tooltip == "You need to install [JetBrains Toolbox App](https://www.jetbrains.com/toolbox-app/) to use this button."])
|
||||||
error_message = "Expected coder_app tooltip to be null when not provided"
|
error_message = "Expected coder_app tooltip to be the default JetBrains Toolbox message when not provided"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
run "channel_eap" {
|
||||||
|
command = plan
|
||||||
|
|
||||||
|
variables {
|
||||||
|
agent_id = "foo"
|
||||||
|
folder = "/home/coder"
|
||||||
|
default = ["GO"]
|
||||||
|
channel = "eap"
|
||||||
|
major_version = "latest"
|
||||||
|
}
|
||||||
|
|
||||||
|
assert {
|
||||||
|
condition = output.ide_metadata["GO"].json_data.type == "eap"
|
||||||
|
error_message = "Expected the API to return a release of type 'eap', but got '${output.ide_metadata["GO"].json_data.type}'"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
run "specific_major_version" {
|
||||||
|
command = plan
|
||||||
|
|
||||||
|
variables {
|
||||||
|
agent_id = "foo"
|
||||||
|
folder = "/home/coder"
|
||||||
|
default = ["GO"]
|
||||||
|
major_version = "2025.3"
|
||||||
|
}
|
||||||
|
|
||||||
|
assert {
|
||||||
|
condition = output.ide_metadata["GO"].json_data.majorVersion == "2025.3"
|
||||||
|
error_message = "Expected the API to return a release for major version '2025.3', but got '${output.ide_metadata["GO"].json_data.majorVersion}'"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -294,3 +327,27 @@ run "output_multiple_ides" {
|
|||||||
error_message = "Expected ide_metadata['PY'].build to be the fallback '${var.expected_ide_config["PY"].build}'"
|
error_message = "Expected ide_metadata['PY'].build to be the fallback '${var.expected_ide_config["PY"].build}'"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
run "validate_output_schema" {
|
||||||
|
command = plan
|
||||||
|
|
||||||
|
variables {
|
||||||
|
agent_id = "foo"
|
||||||
|
folder = "/home/coder"
|
||||||
|
default = ["GO"]
|
||||||
|
}
|
||||||
|
|
||||||
|
assert {
|
||||||
|
condition = alltrue([
|
||||||
|
for key, meta in output.ide_metadata : (
|
||||||
|
can(meta.icon) &&
|
||||||
|
can(meta.name) &&
|
||||||
|
can(meta.identifier) &&
|
||||||
|
can(meta.key) &&
|
||||||
|
can(meta.build) &&
|
||||||
|
# json_data can be null, but the key must exist
|
||||||
|
can(meta.json_data)
|
||||||
|
)
|
||||||
|
])
|
||||||
|
error_message = "The ide_metadata output schema has changed. Please update the 'main.tf' and this test."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -62,7 +62,7 @@ variable "coder_parameter_order" {
|
|||||||
variable "tooltip" {
|
variable "tooltip" {
|
||||||
type = string
|
type = string
|
||||||
description = "Markdown text that is displayed when hovering over workspace apps."
|
description = "Markdown text that is displayed when hovering over workspace apps."
|
||||||
default = null
|
default = "You need to install [JetBrains Toolbox App](https://www.jetbrains.com/toolbox-app/) to use this button."
|
||||||
}
|
}
|
||||||
|
|
||||||
variable "major_version" {
|
variable "major_version" {
|
||||||
@@ -70,8 +70,8 @@ variable "major_version" {
|
|||||||
description = "The major version of the IDE. i.e. 2025.1"
|
description = "The major version of the IDE. i.e. 2025.1"
|
||||||
default = "latest"
|
default = "latest"
|
||||||
validation {
|
validation {
|
||||||
condition = can(regex("^[0-9]{4}\\.[0-2]{1}$", var.major_version)) || var.major_version == "latest"
|
condition = can(regex("^[0-9]{4}\\.[1-3]$", var.major_version)) || var.major_version == "latest"
|
||||||
error_message = "The major_version must be a valid version number. i.e. 2025.1 or latest"
|
error_message = "The major_version must be a valid version number (e.g., 2025.1) or 'latest'"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -126,7 +126,7 @@ variable "download_base_link" {
|
|||||||
|
|
||||||
data "http" "jetbrains_ide_versions" {
|
data "http" "jetbrains_ide_versions" {
|
||||||
for_each = length(var.default) == 0 ? var.options : var.default
|
for_each = length(var.default) == 0 ? var.options : var.default
|
||||||
url = "${var.releases_base_link}/products/releases?code=${each.key}&type=${var.channel}&latest=true${var.major_version == "latest" ? "" : "&major_version=${var.major_version}"}"
|
url = "${var.releases_base_link}/products/releases?code=${each.key}&type=${var.channel}${var.major_version == "latest" ? "&latest=true" : ""}"
|
||||||
}
|
}
|
||||||
|
|
||||||
variable "ide_config" {
|
variable "ide_config" {
|
||||||
@@ -138,9 +138,9 @@ variable "ide_config" {
|
|||||||
- build: The build number of the IDE.
|
- build: The build number of the IDE.
|
||||||
Example:
|
Example:
|
||||||
{
|
{
|
||||||
"CL" = { name = "CLion", icon = "/icon/clion.svg", build = "251.26927.39" },
|
"CL" = { name = "CLion", icon = "/icon/clion.svg", build = "253.29346.141" },
|
||||||
"GO" = { name = "GoLand", icon = "/icon/goland.svg", build = "251.26927.50" },
|
"GO" = { name = "GoLand", icon = "/icon/goland.svg", build = "253.28294.337" },
|
||||||
"IU" = { name = "IntelliJ IDEA", icon = "/icon/intellij.svg", build = "251.26927.53" },
|
"IU" = { name = "IntelliJ IDEA", icon = "/icon/intellij.svg", build = "253.29346.138" },
|
||||||
}
|
}
|
||||||
EOT
|
EOT
|
||||||
type = map(object({
|
type = map(object({
|
||||||
@@ -149,15 +149,15 @@ variable "ide_config" {
|
|||||||
build = string
|
build = string
|
||||||
}))
|
}))
|
||||||
default = {
|
default = {
|
||||||
"CL" = { name = "CLion", icon = "/icon/clion.svg", build = "251.26927.39" },
|
"CL" = { name = "CLion", icon = "/icon/clion.svg", build = "253.29346.141" },
|
||||||
"GO" = { name = "GoLand", icon = "/icon/goland.svg", build = "251.26927.50" },
|
"GO" = { name = "GoLand", icon = "/icon/goland.svg", build = "253.28294.337" },
|
||||||
"IU" = { name = "IntelliJ IDEA", icon = "/icon/intellij.svg", build = "251.26927.53" },
|
"IU" = { name = "IntelliJ IDEA", icon = "/icon/intellij.svg", build = "253.29346.138" },
|
||||||
"PS" = { name = "PhpStorm", icon = "/icon/phpstorm.svg", build = "251.26927.60" },
|
"PS" = { name = "PhpStorm", icon = "/icon/phpstorm.svg", build = "253.29346.151" },
|
||||||
"PY" = { name = "PyCharm", icon = "/icon/pycharm.svg", build = "251.26927.74" },
|
"PY" = { name = "PyCharm", icon = "/icon/pycharm.svg", build = "253.29346.142" },
|
||||||
"RD" = { name = "Rider", icon = "/icon/rider.svg", build = "251.26927.67" },
|
"RD" = { name = "Rider", icon = "/icon/rider.svg", build = "253.29346.144" },
|
||||||
"RM" = { name = "RubyMine", icon = "/icon/rubymine.svg", build = "251.26927.47" },
|
"RM" = { name = "RubyMine", icon = "/icon/rubymine.svg", build = "253.29346.140" },
|
||||||
"RR" = { name = "RustRover", icon = "/icon/rustrover.svg", build = "251.26927.79" },
|
"RR" = { name = "RustRover", icon = "/icon/rustrover.svg", build = "253.29346.139" },
|
||||||
"WS" = { name = "WebStorm", icon = "/icon/webstorm.svg", build = "251.26927.40" }
|
"WS" = { name = "WebStorm", icon = "/icon/webstorm.svg", build = "253.29346.143" }
|
||||||
}
|
}
|
||||||
validation {
|
validation {
|
||||||
condition = length(var.ide_config) > 0
|
condition = length(var.ide_config) > 0
|
||||||
@@ -182,6 +182,20 @@ locals {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Filter the parsed response for the requested major version if not "latest"
|
||||||
|
filtered_releases = {
|
||||||
|
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
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
# Select the latest release for the requested major version (first item in the filtered list)
|
||||||
|
selected_releases = {
|
||||||
|
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 options with fallback to ide_config
|
# Dynamically generate IDE configurations based on options with fallback to ide_config
|
||||||
options_metadata = {
|
options_metadata = {
|
||||||
for code in length(var.default) == 0 ? var.options : var.default : code => {
|
for code in length(var.default) == 0 ? var.options : var.default : code => {
|
||||||
@@ -191,13 +205,10 @@ locals {
|
|||||||
key = code
|
key = code
|
||||||
|
|
||||||
# Use API build number if available, otherwise fall back to ide_config build number
|
# Use API build number if available, otherwise fall back to ide_config build number
|
||||||
build = length(keys(local.parsed_responses[code])) > 0 ? (
|
build = local.selected_releases[code] != null ? local.selected_releases[code].build : var.ide_config[code].build
|
||||||
local.parsed_responses[code][keys(local.parsed_responses[code])[0]][0].build
|
|
||||||
) : var.ide_config[code].build
|
|
||||||
|
|
||||||
# Store API data for potential future use (only if API is available)
|
# Store API data for potential future use
|
||||||
json_data = length(keys(local.parsed_responses[code])) > 0 ? local.parsed_responses[code][keys(local.parsed_responses[code])[0]][0] : null
|
json_data = local.selected_releases[code]
|
||||||
response_key = length(keys(local.parsed_responses[code])) > 0 ? keys(local.parsed_responses[code])[0] : null
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user