mirror of
https://github.com/coder/coder.git
synced 2026-09-24 15:04:27 +08:00
feat: add merge_strategy support for coder_env resources (#23107)
## Description Implements the server-side merge logic for the `merge_strategy` attribute added to `coder_env` in [terraform-provider-coder v2.15.0](https://github.com/coder/terraform-provider-coder/pull/489). This allows template authors to control how duplicate environment variable names are combined across multiple `coder_env` resources. Relates to https://github.com/coder/coder/issues/21885 ## Supported strategies | Strategy | Behavior | |----------|----------| | `replace` (default) | Last value wins — backward compatible | | `append` | Joins values with `:` separator (e.g. PATH additions) | | `prepend` | Prepends value with `:` separator | | `error` | Fails the build if the variable is already defined | ## Example ```hcl resource "coder_env" "path_tools" { agent_id = coder_agent.dev.id name = "PATH" value = "/home/coder/tools/bin" merge_strategy = "append" } ``` ## Changes - **Proto**: Added `merge_strategy` field to `Env` message in `provisioner.proto` - **State reader**: Updated `agentEnvAttributes` struct and proto construction in `resources.go` - **Merge logic**: Added `mergeExtraEnvs()` function in `provisionerdserver.go` with strategy-aware merging for both agent envs and devcontainer subagent envs - **Tests**: 15 unit tests covering all strategies, edge cases (empty values, mixed strategies, multiple appends) - **Dependency**: Bumped `terraform-provider-coder` v2.14.0 → v2.15.0 - **Fixtures**: Updated `duplicate-env-keys` test fixtures and golden files ## Ordering When multiple resources `append` or `prepend` to the same key, they are processed in alphabetical order by Terraform resource address (per the determinism fix in #22706).
This commit is contained in:
@@ -118,9 +118,10 @@ type agentAppAttributes struct {
|
||||
}
|
||||
|
||||
type agentEnvAttributes struct {
|
||||
AgentID string `mapstructure:"agent_id"`
|
||||
Name string `mapstructure:"name"`
|
||||
Value string `mapstructure:"value"`
|
||||
AgentID string `mapstructure:"agent_id"`
|
||||
Name string `mapstructure:"name"`
|
||||
Value string `mapstructure:"value"`
|
||||
MergeStrategy string `mapstructure:"merge_strategy"`
|
||||
}
|
||||
|
||||
type agentScriptAttributes struct {
|
||||
@@ -648,8 +649,9 @@ func ConvertState(ctx context.Context, modules []*tfjson.StateModule, rawGraph s
|
||||
}
|
||||
|
||||
env := &proto.Env{
|
||||
Name: attrs.Name,
|
||||
Value: attrs.Value,
|
||||
Name: attrs.Name,
|
||||
Value: attrs.Value,
|
||||
MergeStrategy: attrs.MergeStrategy,
|
||||
}
|
||||
|
||||
envAgentLoop:
|
||||
|
||||
@@ -382,12 +382,14 @@ func TestConvertResources(t *testing.T) {
|
||||
Architecture: "amd64",
|
||||
ExtraEnvs: []*proto.Env{
|
||||
{
|
||||
Name: "PATH",
|
||||
Value: "/a/bin",
|
||||
Name: "PATH",
|
||||
Value: "/a/bin",
|
||||
MergeStrategy: "append",
|
||||
},
|
||||
{
|
||||
Name: "PATH",
|
||||
Value: "/b/bin",
|
||||
Name: "PATH",
|
||||
Value: "/b/bin",
|
||||
MergeStrategy: "append",
|
||||
},
|
||||
{
|
||||
Name: "UNIQUE",
|
||||
|
||||
+4
-2
@@ -21,11 +21,13 @@
|
||||
"extra_envs": [
|
||||
{
|
||||
"name": "PATH",
|
||||
"value": "/a/bin"
|
||||
"value": "/a/bin",
|
||||
"merge_strategy": "append"
|
||||
},
|
||||
{
|
||||
"name": "PATH",
|
||||
"value": "/b/bin"
|
||||
"value": "/b/bin",
|
||||
"merge_strategy": "append"
|
||||
},
|
||||
{
|
||||
"name": "UNIQUE",
|
||||
|
||||
+4
-2
@@ -22,11 +22,13 @@
|
||||
"extra_envs": [
|
||||
{
|
||||
"name": "PATH",
|
||||
"value": "/a/bin"
|
||||
"value": "/a/bin",
|
||||
"merge_strategy": "append"
|
||||
},
|
||||
{
|
||||
"name": "PATH",
|
||||
"value": "/b/bin"
|
||||
"value": "/b/bin",
|
||||
"merge_strategy": "append"
|
||||
},
|
||||
{
|
||||
"name": "UNIQUE",
|
||||
|
||||
Generated
Vendored
+4
-2
@@ -44,7 +44,8 @@
|
||||
"schema_version": 1,
|
||||
"values": {
|
||||
"name": "PATH",
|
||||
"value": "/a/bin"
|
||||
"value": "/a/bin",
|
||||
"merge_strategy": "append"
|
||||
},
|
||||
"sensitive_values": {}
|
||||
},
|
||||
@@ -57,7 +58,8 @@
|
||||
"schema_version": 1,
|
||||
"values": {
|
||||
"name": "PATH",
|
||||
"value": "/b/bin"
|
||||
"value": "/b/bin",
|
||||
"merge_strategy": "append"
|
||||
},
|
||||
"sensitive_values": {}
|
||||
},
|
||||
|
||||
Generated
Vendored
+4
-2
@@ -60,7 +60,8 @@
|
||||
"agent_id": "aaaaaaaa-1111-2222-3333-444444444444",
|
||||
"id": "bbbbbbbb-1111-2222-3333-444444444444",
|
||||
"name": "PATH",
|
||||
"value": "/a/bin"
|
||||
"value": "/a/bin",
|
||||
"merge_strategy": "append"
|
||||
},
|
||||
"sensitive_values": {},
|
||||
"depends_on": [
|
||||
@@ -78,7 +79,8 @@
|
||||
"agent_id": "aaaaaaaa-1111-2222-3333-444444444444",
|
||||
"id": "cccccccc-1111-2222-3333-444444444444",
|
||||
"name": "PATH",
|
||||
"value": "/b/bin"
|
||||
"value": "/b/bin",
|
||||
"merge_strategy": "append"
|
||||
},
|
||||
"sensitive_values": {},
|
||||
"depends_on": [
|
||||
|
||||
Reference in New Issue
Block a user