chore: clone config.env in genEnv to prevent shared-object mutation#2981
chore: clone config.env in genEnv to prevent shared-object mutation#2981joonas wants to merge 3 commits intodefenseunicorns:mainfrom
config.env in genEnv to prevent shared-object mutation#2981Conversation
config.env in genEnv to prevent shared-object mutationconfig.env in genEnv to prevent shared-object mutation
`genEnv` deleted `config.env["PEPR_WATCH_MODE"]` directly from the caller's `ModuleConfig` reference. Since the same config object is passed twice (once for the admission deployment and once for the watcher deployment) the first call permanently removed the key. Any code reading `config.env` after the first `genEnv` call would no longer see `PEPR_WATCH_MODE`. Shallow-clone `config.env` into a local `cfg` object and delete the key from the clone instead. This preserves the original config while still preventing a user-supplied `PEPR_WATCH_MODE` from overriding the programmatic value controlled by the `watchMode` parameter. Both regression tests assert `config.env` identity via snapshot comparison rather than checking `genEnv` return values. The `def` object always supplies `PEPR_WATCH_MODE` from the `watchMode` parameter, so output-based assertions pass even with the mutation bug present. Existing tests already cover output correctness for each mode. Signed-off-by: Joonas Bergius <joonas@defenseunicorns.com>
d9479f9 to
bcdf37e
Compare
Greptile SummaryThis PR fixes a shared-object mutation bug in Confidence Score: 5/5Safe to merge — targeted one-liner fix with good regression coverage and no behaviour change for callers. The change is tiny, well-understood, and correctly addresses the mutation bug. No P0/P1 findings; all remaining observations are P2 or lower. No files require special attention. Important Files Changed
Sequence DiagramsequenceDiagram
participant Caller
participant genEnv
Note over Caller: Build admission + watcher deployments<br/>using the same ModuleConfig
Caller->>genEnv: genEnv(config, watchMode=false)
Note over genEnv: cfg = { ...config.env }<br/>delete cfg.PEPR_WATCH_MODE<br/>(clone only, original untouched)
genEnv-->>Caller: V1EnvVar[] (PEPR_WATCH_MODE="false")
Note over Caller: config.env still intact ✅
Caller->>genEnv: genEnv(config, watchMode=true)
Note over genEnv: cfg = { ...config.env }<br/>delete cfg.PEPR_WATCH_MODE<br/>(clone only, original untouched)
genEnv-->>Caller: V1EnvVar[] (PEPR_WATCH_MODE="true")
Note over Caller: config.env still intact ✅
Reviews (1): Last reviewed commit: "Merge branch 'main' into fix/environment..." | Re-trigger Greptile |
Description
genEnvdeletedconfig.env["PEPR_WATCH_MODE"]directly from the caller'sModuleConfigreference. Since the same config object is passed twice (once for the admission deployment and once for the watcher deployment) the first call permanently removed the key. Any code readingconfig.envafter the firstgenEnvcall would no longer seePEPR_WATCH_MODE.Shallow-clone
config.envinto a localcfgobject and delete the key from the clone instead. This preserves the original config while still preventing a user-suppliedPEPR_WATCH_MODEfrom overriding the programmatic value controlled by thewatchModeparameter.Both regression tests assert
config.envidentity via snapshot comparison rather than checkinggenEnvreturn values. Thedefobject always suppliesPEPR_WATCH_MODEfrom thewatchModeparameter, so output-based assertions pass even with the mutation bug present. Existing tests already cover output correctness for each mode.End to End Test:
(See Pepr Excellent Examples)
Type of change
Checklist before merging