## Summary Add two new customization variables to the Mux module so users can control how Mux is installed: ### `package_manager` (default: `"auto"`) Choose which Node package manager installs Mux: - **`auto`** (default) — auto-detects `npm` → `pnpm` → `bun` in order, falling back to a direct tarball download when none is available - **`npm`**, **`pnpm`**, **`bun`** — force a specific package manager (fails if not found on PATH) ### `registry_url` (default: `"https://registry.npmjs.org"`) Override the npm registry URL for private registries or mirrors. All previously hardcoded `registry.npmjs.org` references have been replaced with this variable. The `--registry` flag is passed to whichever package manager is used, and the tarball fallback path also uses it. ## Changes | File | What changed | |---|---| | `main.tf` | Added `package_manager` and `registry_url` variables with validation; pass both to template | | `run.sh` | Rewrote install logic: PM auto-detection loop, `case`/`esac` dispatch with PM-specific flags, replaced all hardcoded registry URLs with `${REGISTRY_URL}` | | `mux.tftest.hcl` | Added 6 new test cases: PM selection (npm/pnpm/bun), invalid PM validation, custom registry URL, trailing-slash stripping | | `main.test.ts` | Updated expected log messages to match new generic wording | | `README.md` | Updated description, added Custom Package Manager and Custom Registry examples, updated Notes section | ## Version Bumped **1.2.0 → 1.3.0** (minor: new backward-compatible features). ## Validation - ✅ `terraform validate` — clean - ✅ `terraform test` — **15 passed, 0 failed** - ✅ `terraform fmt` — clean --- Generated with [Mux](https://mux.coder.com) using Claude
217 lines
5.0 KiB
HCL
217 lines
5.0 KiB
HCL
run "required_vars" {
|
|
command = plan
|
|
|
|
variables {
|
|
agent_id = "foo"
|
|
}
|
|
}
|
|
|
|
run "install_false_and_use_cached_conflict" {
|
|
command = plan
|
|
|
|
variables {
|
|
agent_id = "foo"
|
|
use_cached = true
|
|
install = false
|
|
}
|
|
|
|
expect_failures = [
|
|
resource.coder_script.mux
|
|
]
|
|
}
|
|
|
|
# Needs command = apply because the URL contains random_password.result,
|
|
# which is unknown during plan.
|
|
run "custom_port" {
|
|
command = apply
|
|
|
|
variables {
|
|
agent_id = "foo"
|
|
port = 8080
|
|
}
|
|
|
|
assert {
|
|
condition = startswith(resource.coder_app.mux.url, "http://localhost:8080?token=")
|
|
error_message = "coder_app URL must use the configured port and include auth token"
|
|
}
|
|
|
|
assert {
|
|
condition = trimprefix(resource.coder_app.mux.url, "http://localhost:8080?token=") == random_password.mux_auth_token.result
|
|
error_message = "URL token must match the generated auth token"
|
|
}
|
|
}
|
|
|
|
# Needs command = apply because random_password.result is unknown during plan.
|
|
run "auth_token_in_server_script" {
|
|
command = apply
|
|
|
|
variables {
|
|
agent_id = "foo"
|
|
}
|
|
|
|
assert {
|
|
condition = strcontains(resource.coder_script.mux.script, "MUX_SERVER_AUTH_TOKEN=")
|
|
error_message = "mux launch script must set MUX_SERVER_AUTH_TOKEN"
|
|
}
|
|
|
|
assert {
|
|
condition = strcontains(resource.coder_script.mux.script, random_password.mux_auth_token.result)
|
|
error_message = "mux launch script must use the generated auth token"
|
|
}
|
|
}
|
|
|
|
# Needs command = apply because random_password.result is unknown during plan.
|
|
run "auth_token_in_url" {
|
|
command = apply
|
|
|
|
variables {
|
|
agent_id = "foo"
|
|
}
|
|
|
|
assert {
|
|
condition = startswith(resource.coder_app.mux.url, "http://localhost:4000?token=")
|
|
error_message = "coder_app URL must include auth token query parameter"
|
|
}
|
|
|
|
assert {
|
|
condition = trimprefix(resource.coder_app.mux.url, "http://localhost:4000?token=") == random_password.mux_auth_token.result
|
|
error_message = "URL token must match the generated auth token"
|
|
}
|
|
}
|
|
|
|
run "custom_additional_arguments" {
|
|
command = plan
|
|
|
|
variables {
|
|
agent_id = "foo"
|
|
additional_arguments = "--open-mode pinned --add-project '/workspaces/my repo'"
|
|
}
|
|
|
|
assert {
|
|
condition = strcontains(resource.coder_script.mux.script, "--open-mode pinned --add-project '/workspaces/my repo'")
|
|
error_message = "mux launch script must include the configured additional arguments"
|
|
}
|
|
}
|
|
|
|
run "custom_version" {
|
|
command = plan
|
|
|
|
variables {
|
|
agent_id = "foo"
|
|
install_version = "0.3.0"
|
|
}
|
|
}
|
|
|
|
# install=false should succeed
|
|
run "install_false_only_success" {
|
|
command = plan
|
|
|
|
variables {
|
|
agent_id = "foo"
|
|
install = false
|
|
}
|
|
}
|
|
|
|
# use_cached-only should succeed
|
|
run "use_cached_only_success" {
|
|
command = plan
|
|
|
|
variables {
|
|
agent_id = "foo"
|
|
use_cached = true
|
|
}
|
|
}
|
|
|
|
# Custom package_manager should appear in generated script
|
|
run "custom_package_manager_npm" {
|
|
command = plan
|
|
|
|
variables {
|
|
agent_id = "foo"
|
|
package_manager = "npm"
|
|
}
|
|
|
|
assert {
|
|
condition = strcontains(resource.coder_script.mux.script, "PM_CMD=\"npm\"")
|
|
error_message = "mux script must set PM_CMD to the configured package manager"
|
|
}
|
|
}
|
|
|
|
run "custom_package_manager_pnpm" {
|
|
command = plan
|
|
|
|
variables {
|
|
agent_id = "foo"
|
|
package_manager = "pnpm"
|
|
}
|
|
|
|
assert {
|
|
condition = strcontains(resource.coder_script.mux.script, "PM_CMD=\"pnpm\"")
|
|
error_message = "mux script must set PM_CMD to the configured package manager"
|
|
}
|
|
}
|
|
|
|
run "custom_package_manager_bun" {
|
|
command = plan
|
|
|
|
variables {
|
|
agent_id = "foo"
|
|
package_manager = "bun"
|
|
}
|
|
|
|
assert {
|
|
condition = strcontains(resource.coder_script.mux.script, "PM_CMD=\"bun\"")
|
|
error_message = "mux script must set PM_CMD to the configured package manager"
|
|
}
|
|
}
|
|
|
|
# Invalid package_manager should fail validation
|
|
run "invalid_package_manager" {
|
|
command = plan
|
|
|
|
variables {
|
|
agent_id = "foo"
|
|
package_manager = "yarn"
|
|
}
|
|
|
|
expect_failures = [
|
|
var.package_manager
|
|
]
|
|
}
|
|
|
|
# Custom registry_url should appear in generated script
|
|
run "custom_registry_url" {
|
|
command = plan
|
|
|
|
variables {
|
|
agent_id = "foo"
|
|
registry_url = "https://npm.example.com"
|
|
}
|
|
|
|
assert {
|
|
condition = strcontains(resource.coder_script.mux.script, "https://npm.example.com")
|
|
error_message = "mux script must use the configured registry URL"
|
|
}
|
|
|
|
assert {
|
|
condition = !strcontains(resource.coder_script.mux.script, "registry.npmjs.org")
|
|
error_message = "mux script must not contain hardcoded registry.npmjs.org when custom registry is set"
|
|
}
|
|
}
|
|
|
|
# registry_url trailing slash should be stripped
|
|
run "registry_url_trailing_slash" {
|
|
command = plan
|
|
|
|
variables {
|
|
agent_id = "foo"
|
|
registry_url = "https://npm.example.com/"
|
|
}
|
|
|
|
assert {
|
|
condition = strcontains(resource.coder_script.mux.script, "https://npm.example.com/mux/")
|
|
error_message = "registry URL trailing slash must be stripped to avoid double slashes"
|
|
}
|
|
}
|
|
|