Skip to content

feat: support repeatable, required -config flag across config loaders#2877

Open
renuka-fernando wants to merge 7 commits into
wso2:mainfrom
renuka-fernando:multi-conf-file
Open

feat: support repeatable, required -config flag across config loaders#2877
renuka-fernando wants to merge 7 commits into
wso2:mainfrom
renuka-fernando:multi-conf-file

Conversation

@renuka-fernando

Copy link
Copy Markdown
Contributor

Purpose

Unify configuration loading across the platform's Go components behind a repeatable, required -config flag, so config can be layered as a complete base file plus thin environment/deployment overlays instead of a single monolithic file.

Resolves #2865. Related #2873, #2874 (follow-ups for the AI Workspace BFF and Platform API, both included here) and #2876 (Developer Portal, tracked separately).

Goals

  • Accept multiple -config files, merged in order with last-wins precedence (maps deep-merge, arrays replace) via koanf StrictMerge, so a type-mismatched override across files fails loudly.
  • {{ env }} / {{ file }} interpolation runs once, after all files are merged, so a token in the base can be resolved by a later overlay.
  • Standardize on required, no default path, no silent-defaults fallback: a missing -config (or a passed file that does not exist/parse) fails fast rather than silently booting on built-in defaults — consistent with the repo's fail-closed startup posture (GO-AUTH-011). There is no env-var provider; env reaches config only through explicit {{ env }} tokens, which is exactly why a missing config file must fail fast.

Approach

  • gateway-controller (c6b343a8): repeatable flag.Var; LoadConfig variadic with StrictMerge last-wins loop.
  • policy-engine (073cb77b): same flag change; Load variadic; dropped the loader's optional-file branch so it fails closed instead of silently running on defaults.
  • platform-api (28d3466f): repeatable + required flag; LoadConfig variadic; configFilePath singleton became a slice with SetConfigPaths; added a WithConfigPaths façade option. The embeddable library API/platform façade still permits zero files (env + defaults via WithConfig); only the binary requires -config. Corrected the misleading "env vars take priority" flag help. Breaking (flag was optional).
  • ai-workspace-bff (443c1595): repeatable + required flag; Load/loadConfigKoanf variadic with StrictMerge; dropped the DefaultConfigFile fallback and the missing-file no-op; updated the image ENTRYPOINT to pass -config explicitly (the Helm chart inherits it). Breaking (had a default path).
  • docs (0a76a8da): updated the platform-api bootstrap spec.
  • Added multi-file test suites per component (deep-merge/last-wins, array-replace, StrictMerge type-mismatch, interpolation-after-merge, order precedence, fail-closed no-files/missing-file).

Both real deployment paths for each affected binary already pass -config (all-in-one compose, the platform-api and BFF Helm charts / image ENTRYPOINTs), so there is no runtime breakage.

User stories

As an operator, I want to keep a shared base config and apply thin per-environment overlays, so I don't duplicate a full monolithic config per deployment.

Documentation

Updated platform-api/spec/impls/platform-bootstrap.md. The -config flag help text documents the repeatable + last-wins behavior in each binary. Developer Portal docs are out of scope (tracked in #2876).

Automation tests

  • Unit tests: new config_multifile_test.go in gateway-controller, policy-engine, platform-api, and ai-workspace/bff — covering deep-merge/last-wins, array-replace, StrictMerge type-mismatch, interpolation-after-merge, order precedence, and the fail-closed no-files/missing-file paths. Existing single-path callers keep working via the variadic signatures. Full config suites, go vet, and builds pass for each module.
  • Integration tests: N/A — no new runtime endpoints; behavior covered by unit tests and existing deployment paths.

Security checks

Samples

N/A

Related PRs

N/A

Test environment

Go 1.26 (module toolchains), macOS (darwin). go build, go vet, and go test ./.../config/... for each affected module.

Checklist

  • Tests added or updated (unit, integration, etc.)
  • Samples updated (if applicable)

…g flag

Make the gateway-controller -config flag repeatable so config can be
layered as a base file plus thin overlays instead of one monolithic file.

- main.go: back -config with a repeatable flag.Var; require at least one
- config.go: LoadConfig now variadic, merging files in order with
  last-wins precedence via koanf StrictMerge (maps deep-merge, arrays
  replace); interpolation still runs once after all files are merged
- add tests for deep-merge, array-replace, strict type-mismatch,
  interpolation-after-merge, order precedence, and single-file regression

Closes wso2#2865

Signed-off-by: Renuka Fernando <renukapiyumal@gmail.com>
…nfig flag

Extend the multi-config-file support from the gateway-controller (wso2#2865)
to the gateway-runtime policy-engine, so config can be layered as a base
file plus thin overlays instead of one monolithic file.

- main.go: back -config with a repeatable flag.Var; require at least one
- config.go: Load now variadic, merging files in order with last-wins
  precedence via koanf StrictMerge (maps deep-merge, arrays replace);
  drop the optional-file branch so the loader fails closed instead of
  silently running on defaults; interpolation still runs once after merge
- add tests for deep-merge, array-replace, strict type-mismatch,
  interpolation-after-merge, and order precedence; update the empty-path
  test to assert the new fail-closed contract

Closes wso2#2865

Signed-off-by: Renuka Fernando <renukapiyumal@gmail.com>
Adopt the layered multi-config-file pattern (wso2#2874) so config can be a
base file plus thin overlays, and unify the flag behavior with the
gateway components (wso2#2865): required, repeatable, no default path.

- cmd/main.go: back -config with a repeatable flag.Var; require at least
  one file (fail fast instead of silently booting on defaults); correct
  the misleading "env vars take priority" help text
- config.go: LoadConfig now variadic, merging files in order with
  last-wins precedence via koanf StrictMerge (maps deep-merge, arrays
  replace) before the platform_api Cut + interpolation; configFilePath
  singleton becomes a slice; add SetConfigPaths
- platform/options.go: add WithConfigPaths alongside WithConfigPath
- add tests for deep-merge, array-replace, strict type-mismatch,
  interpolation-after-merge, and order precedence

The embeddable LoadConfig/platform façade still permits zero files
(env + defaults via WithConfig); only the platform-api binary requires
-config. Both deployment paths (all-in-one compose, platform-api Helm
chart) already pass -config, so no runtime breakage.

BREAKING CHANGE: the platform-api binary now requires at least one
-config flag. Running it with no -config (previously booted on env +
built-in defaults) exits non-zero. Deployments already pass -config;
local `go run ./cmd/main.go` invocations must now add -config <file>.

Closes wso2#2874

Signed-off-by: Renuka Fernando <renukapiyumal@gmail.com>
…uired

Adopt the layered multi-config-file pattern (wso2#2873) so config can be a
base file plus thin overlays, and unify the flag behavior with the
gateway components (wso2#2865): required, repeatable, no default path.

- main.go: back -config with a repeatable flag.Var; require at least one
- config.go: Load now variadic with last-wins merge; drop the
  DefaultConfigFile fallback so a missing/absent file fails fast instead
  of silently applying built-in defaults
- settings.go: loadConfigKoanf loops the files with a koanf StrictMerge
  instance (maps deep-merge, arrays replace); a missing explicitly-passed
  file is now a hard error, not a no-op
- Dockerfile: ENTRYPOINT passes -config /etc/ai-workspace/config.toml
  explicitly (the container previously relied on the default path; the
  Helm chart inherits this via the image ENTRYPOINT)
- add tests for deep-merge, strict type-mismatch, interpolation-after-
  merge, order precedence, and the no-files/missing-file fail-closed paths

BREAKING CHANGE: the ai-workspace BFF now requires at least one -config
flag and no longer falls back to /etc/ai-workspace/config.toml. The image
ENTRYPOINT and `make bff-run` already pass -config, so running the
published image or the standard dev target is unaffected; only a bare
`bff` invocation that relied on the default path must now pass -config.

Closes wso2#2873

Signed-off-by: Renuka Fernando <renukapiyumal@gmail.com>
Update the platform-bootstrap implementation spec for the repeatable,
required -config flag (wso2#2874):

- fix the stale "parses environment variables" description — config comes
  from the layered -config file(s) plus {{ env }}/{{ file }} tokens, not
  an env-var provider
- the verification step now runs go run ./cmd/main.go with -config and
  notes the binary exits non-zero when no -config is given

Signed-off-by: Renuka Fernando <renukapiyumal@gmail.com>
@coderabbitai

coderabbitai Bot commented Jul 26, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

The change adds repeatable, required -config inputs across gateway, platform API, and AI Workspace components. Configuration files merge in order with last-wins precedence, post-merge interpolation, updated startup logging, tests, documentation, and container wiring.

Changes

Layered configuration support

Layer / File(s) Summary
Gateway controller configuration
gateway/gateway-controller/cmd/controller/main.go, gateway/gateway-controller/pkg/config/*
The controller accepts repeated config flags, and LoadConfig performs ordered multi-file merging with post-merge interpolation and validation.
Policy engine configuration
gateway/gateway-runtime/policy-engine/cmd/policy-engine/main.go, gateway/gateway-runtime/policy-engine/internal/config/*
The policy engine requires config files and loads them in order, replacing previous default-loading behavior.
Platform API configuration
platform-api/cmd/main.go, platform-api/config/*, platform-api/platform/options.go, platform-api/spec/impls/platform-bootstrap.md
Platform API adds repeatable config paths, layered loading, WithConfigPaths, updated tests, and bootstrap documentation.
AI Workspace BFF configuration
portals/ai-workspace/Dockerfile, portals/ai-workspace/bff/*, portals/ai-workspace/docker-compose.yaml
The BFF requires explicit config paths, rejects missing files, loads multiple files in order, and passes its config path from the container entrypoint.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant CLI
  participant Application
  participant ConfigLoader
  participant Koanf
  CLI->>Application: Parse repeated -config paths
  Application->>ConfigLoader: Load(paths...)
  ConfigLoader->>Koanf: Load files in argument order
  Koanf-->>ConfigLoader: Merged configuration
  ConfigLoader-->>Application: Interpolate and unmarshal config
  Application-->>CLI: Start or report configuration error
Loading

Possibly related issues

Possibly related PRs

  • wso2/api-platform#2761 — Related gateway configuration interpolation changes in the same loading flow.
  • wso2/api-platform#2799 — Related Platform API and AI Workspace configuration-loader changes affecting interpolation and scoping.

Suggested reviewers: pubudu538, malinthaprasan, chamilaadhi

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Linked Issues check ⚠️ Warning For #2865, the gateway loaders don't implement StrictMerge; type mismatches are only caught later by unmarshal and validation. Update both gateway loaders to use koanf StrictMerge/WithMergeFunc so cross-file type mismatches fail at merge time, then rerun the multi-file tests.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title is concise and accurately summarizes the main change: repeatable required -config support across config loaders.
Description check ✅ Passed All required sections are present and filled with relevant details, including purpose, goals, approach, tests, docs, and environment.
Out of Scope Changes check ✅ Passed The extra Platform API, BFF, docs, and deployment updates are consistent with the stated follow-up scope and deployment-path changes.
Docstring Coverage ✅ Passed Docstring coverage is 94.87% which is sufficient. The required threshold is 80.00%.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 golangci-lint (2.12.2)

level=error msg="[linters_context] typechecking error: pattern ./...: directory prefix . does not contain modules listed in go.work or their selected dependencies"


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (1)
gateway/gateway-controller/pkg/config/config_multifile_test.go (1)

106-127: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Test interpolation timing with an overridden token. These tests pass whether interpolation occurs before or after merging because the overlay changes an unrelated field. Make the base define a token that would fail if evaluated, then override that exact key with a literal in the overlay and assert loading succeeds with the literal.

  • gateway/gateway-controller/pkg/config/config_multifile_test.go#L106-L127: add the timing-distinguishing override case.
  • gateway/gateway-runtime/policy-engine/internal/config/config_multifile_test.go#L105-L126: add the equivalent policy-engine case.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@gateway/gateway-controller/pkg/config/config_multifile_test.go` around lines
106 - 127, Update TestLoadConfig_MultiFile_InterpolationAfterMerge in
gateway/gateway-controller/pkg/config/config_multifile_test.go:106-127 so the
base defines an invalid or failing interpolation token, the overlay overrides
that exact key with a literal, and the test asserts loading succeeds with the
literal value. Apply the equivalent timing-distinguishing change to the
corresponding policy-engine test in
gateway/gateway-runtime/policy-engine/internal/config/config_multifile_test.go:105-126.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@gateway/gateway-controller/pkg/config/config.go`:
- Around line 715-718: Validate each config path in the loaders at
gateway/gateway-controller/pkg/config/config.go:715-718 and
gateway/gateway-runtime/policy-engine/internal/config/config.go:369-371 before
calling file.Provider: reject null bytes and URL-encoded traversal, resolve and
clean the absolute path, then require strict containment under the
server-controlled config root using a separator-suffixed prefix check. Pass only
the validated path to file.Provider and preserve the existing load error
behavior.

In `@platform-api/config/config.go`:
- Around line 443-446: Update the config-path handling in LoadConfig to return
an error when any configPath is empty instead of continuing and loading
defaults; preserve normal processing for non-empty paths. Add a regression test
covering LoadConfig("") that asserts the expected error.

---

Nitpick comments:
In `@gateway/gateway-controller/pkg/config/config_multifile_test.go`:
- Around line 106-127: Update TestLoadConfig_MultiFile_InterpolationAfterMerge
in gateway/gateway-controller/pkg/config/config_multifile_test.go:106-127 so the
base defines an invalid or failing interpolation token, the overlay overrides
that exact key with a literal, and the test asserts loading succeeds with the
literal value. Apply the equivalent timing-distinguishing change to the
corresponding policy-engine test in
gateway/gateway-runtime/policy-engine/internal/config/config_multifile_test.go:105-126.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: cfe529e2-5292-4207-9d40-309f6e7c458d

📥 Commits

Reviewing files that changed from the base of the PR and between 71fd31a and 0a76a8d.

📒 Files selected for processing (17)
  • gateway/gateway-controller/cmd/controller/main.go
  • gateway/gateway-controller/pkg/config/config.go
  • gateway/gateway-controller/pkg/config/config_multifile_test.go
  • gateway/gateway-runtime/policy-engine/cmd/policy-engine/main.go
  • gateway/gateway-runtime/policy-engine/internal/config/config.go
  • gateway/gateway-runtime/policy-engine/internal/config/config_multifile_test.go
  • gateway/gateway-runtime/policy-engine/internal/config/config_test.go
  • platform-api/cmd/main.go
  • platform-api/config/config.go
  • platform-api/config/config_multifile_test.go
  • platform-api/platform/options.go
  • platform-api/spec/impls/platform-bootstrap.md
  • portals/ai-workspace/Dockerfile
  • portals/ai-workspace/bff/internal/config/config.go
  • portals/ai-workspace/bff/internal/config/config_multifile_test.go
  • portals/ai-workspace/bff/internal/config/settings.go
  • portals/ai-workspace/bff/main.go

Comment thread gateway/gateway-controller/pkg/config/config.go
Comment thread platform-api/config/config.go
renuka-fernando added a commit to renuka-fernando/api-platform that referenced this pull request Jul 26, 2026
An explicit empty-string config path (e.g. the binary invoked with
`-config=`) was skipped by the load loop, so it fell through to zero
effective files. Return a clear "config path must not be empty" error
at the path check instead — matching the other loaders, which already
reject "" via file.Provider — rather than surfacing a confusing
downstream validation error (or silently booting on defaults if those
were ever valid). A zero-arg call remains the embeddable defaults path.

Adds a regression test asserting LoadConfig("") fails with the explicit
empty-path error. Addresses a CodeRabbit review finding on wso2#2877.

Signed-off-by: Renuka Fernando <renukapiyumal@gmail.com>
coderabbitai[bot]
coderabbitai Bot previously approved these changes Jul 26, 2026
- platform-api: reject an explicit empty-string -config path with a clear
  error instead of skipping it (matches the other loaders); add a
  regression test. Addresses a CodeRabbit review finding on wso2#2877.
- ai-workspace: pin the docker-compose image to :1.0.0-rc-SNAPSHOT to
  match the built VERSION and the sibling platform-api SNAPSHOT tag, so
  the pr-check stack uses the freshly built image instead of pulling the
  unpublished :1.0.0-rc tag (manifest unknown).

Signed-off-by: Renuka Fernando <renukapiyumal@gmail.com>
…s files

StrictMerge compared raw parsed types at merge time, before interpolation.
Since an {{ env }}/{{ file }} token is a string until resolved, a numeric or
bool field set natively in one file and overridden by a token in an overlay
was wrongly rejected as a type mismatch — a legitimate, common overlay
pattern. Drop StrictMerge in all four loaders (gateway-controller,
policy-engine, platform-api, ai-workspace-bff) and rely on the weakly-typed
unmarshal plus Validate, which still fail loudly on genuinely invalid values.

- config loaders: use koanf.New instead of NewWithConf(StrictMerge); update
  the doc/inline comments explaining why
- tests: rename ...StrictMergeTypeMismatchFails to ...TypeMismatchFails
  (now caught at unmarshal), and add per-component regressions —
  NumericOverriddenByEnvToken and EnvTokenResolvingToNonNumberFails

Deep-merge (maps), array-replace, last-wins, and fail-closed interpolation
are unchanged; only the pre-interpolation type-strictness is removed.

Signed-off-by: Renuka Fernando <renukapiyumal@gmail.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (3)
gateway/gateway-controller/pkg/config/config_multifile_test.go (1)

71-87: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Add coverage for a scalar overriding an array-typed field across files.

ArrayReplaceNotAppend only proves array-vs-array replacement. Removing koanf StrictMerge means a cross-file override where a later file sets a scalar for a field typed as a slice (e.g. admin_server.allowed_ips) is no longer rejected at merge time — mapstructure's WeaklyTypedInput silently converts a single value into a one-element slice at unmarshal instead. Worth a regression test asserting this is the intended behavior (rather than an oversight), especially since several array-typed fields (e.g. AllowedIPs) are security-relevant.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@gateway/gateway-controller/pkg/config/config_multifile_test.go` around lines
71 - 87, The multi-file configuration tests lack coverage for a scalar
overriding an array-typed field. Add a regression test alongside
TestLoadConfig_MultiFile_ArrayReplaceNotAppend that loads an initial array value
and a later scalar value for a slice field such as admin_server.allowed_ips,
then assert LoadConfig succeeds and mapstructure conversion produces the
expected one-element slice.
portals/ai-workspace/bff/internal/config/config_multifile_test.go (1)

1-30: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Missing array-replace-not-append regression test for this component.

Gateway-controller, policy-engine, and platform-api each have a ..._ArrayReplaceNotAppend test proving a later file's array replaces (rather than appends to) an earlier file's array. This suite has no equivalent, even though the same "arrays replace" merge contract applies here. Worth adding for parity and to guard the documented merge semantics.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@portals/ai-workspace/bff/internal/config/config_multifile_test.go` around
lines 1 - 30, Add an AI Workspace regression test named with the existing
ArrayReplaceNotAppend convention in config_multifile_test.go. Configure two
input files containing the same array-valued key with different elements, merge
them through the component’s normal config-loading path, and assert the result
contains only the later file’s array values rather than an appended combination.
gateway/gateway-controller/pkg/config/config.go (1)

704-753: 📐 Maintainability & Code Quality | 🔵 Trivial | 🏗️ Heavy lift

Near-identical multi-file load logic duplicated across four packages. The "deliberately not StrictMerge" rationale comment, the sequential file-load loop, and the pre/post-interpolation wiring are copy-pasted almost verbatim across gateway-controller, policy-engine, platform-api, and the AI Workspace BFF — despite all four already sharing the configinterpolate package for token expansion. A shared loader helper (e.g. LoadFiles(paths []string, parser koanf.Parser) (*koanf.Koanf, error)) would reduce the risk of the four copies drifting apart on a future fix or hardening change.

  • gateway/gateway-controller/pkg/config/config.go#L704-L753: extract the load-loop/koanf-setup portion into a shared helper and delegate here.
  • gateway/gateway-runtime/policy-engine/internal/config/config.go#L358-L415: delegate to the same shared helper instead of duplicating the loop and comment.
  • platform-api/config/config.go#L436-L535: delegate to the same shared helper (keeping the platform-api-specific Cut step local to this file).
  • portals/ai-workspace/bff/internal/config/settings.go#L72-L125: delegate to the same shared helper (keeping the ai-workspace-specific Cut step local to this file).
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@gateway/gateway-controller/pkg/config/config.go` around lines 704 - 753,
Extract the shared koanf setup, sequential file-loading loop, and interpolation
wiring from gateway/gateway-controller/pkg/config/config.go#L704-L753,
gateway/gateway-runtime/policy-engine/internal/config/config.go#L358-L415,
platform-api/config/config.go#L436-L535, and
portals/ai-workspace/bff/internal/config/settings.go#L72-L125 into a common
helper such as LoadFiles(paths []string, parser koanf.Parser). Update all four
config loaders to delegate to it, retaining platform-api’s and ai-workspace’s
local Cut steps while removing duplicated merge rationale and load-loop logic.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@gateway/gateway-controller/pkg/config/config_multifile_test.go`:
- Around line 71-87: The multi-file configuration tests lack coverage for a
scalar overriding an array-typed field. Add a regression test alongside
TestLoadConfig_MultiFile_ArrayReplaceNotAppend that loads an initial array value
and a later scalar value for a slice field such as admin_server.allowed_ips,
then assert LoadConfig succeeds and mapstructure conversion produces the
expected one-element slice.

In `@gateway/gateway-controller/pkg/config/config.go`:
- Around line 704-753: Extract the shared koanf setup, sequential file-loading
loop, and interpolation wiring from
gateway/gateway-controller/pkg/config/config.go#L704-L753,
gateway/gateway-runtime/policy-engine/internal/config/config.go#L358-L415,
platform-api/config/config.go#L436-L535, and
portals/ai-workspace/bff/internal/config/settings.go#L72-L125 into a common
helper such as LoadFiles(paths []string, parser koanf.Parser). Update all four
config loaders to delegate to it, retaining platform-api’s and ai-workspace’s
local Cut steps while removing duplicated merge rationale and load-loop logic.

In `@portals/ai-workspace/bff/internal/config/config_multifile_test.go`:
- Around line 1-30: Add an AI Workspace regression test named with the existing
ArrayReplaceNotAppend convention in config_multifile_test.go. Configure two
input files containing the same array-valued key with different elements, merge
them through the component’s normal config-loading path, and assert the result
contains only the later file’s array values rather than an appended combination.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: b427725a-d96c-4fae-9d78-f765ab494bf7

📥 Commits

Reviewing files that changed from the base of the PR and between cec8311 and 4a9a263.

📒 Files selected for processing (10)
  • gateway/gateway-controller/pkg/config/config.go
  • gateway/gateway-controller/pkg/config/config_multifile_test.go
  • gateway/gateway-runtime/policy-engine/internal/config/config.go
  • gateway/gateway-runtime/policy-engine/internal/config/config_multifile_test.go
  • platform-api/config/config.go
  • platform-api/config/config_multifile_test.go
  • portals/ai-workspace/bff/internal/config/config.go
  • portals/ai-workspace/bff/internal/config/config_multifile_test.go
  • portals/ai-workspace/bff/internal/config/settings.go
  • portals/ai-workspace/docker-compose.yaml

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Support multiple config files via repeatable -config flag

1 participant