Skip to content

feat(deploy): add CONFIG_LOCAL_DIR overlay for local-only config overrides#388

Open
ivangrynenko wants to merge 1 commit into
govCMS:10.x-developfrom
ivangrynenko:feature/config-local-overlay
Open

feat(deploy): add CONFIG_LOCAL_DIR overlay for local-only config overrides#388
ivangrynenko wants to merge 1 commit into
govCMS:10.x-developfrom
ivangrynenko:feature/config-local-overlay

Conversation

@ivangrynenko
Copy link
Copy Markdown

Closes #387.

Summary

Adds an optional CONFIG_LOCAL_DIR (default /app/config/local) overlay to scripts/deploy/govcms-config-import, applied via drush config:import --partial only when LAGOON_ENVIRONMENT_TYPE=local AND the directory contains importable YAML.

Overlay order: defaultdev (any non-prod) → local (local only).

Lets site projects place shield.settings.yml (and any other local-only overrides) under config/local/ to disable shield on developers' machines without weakening it on public Lagoon dev/staging/branch URLs.

Why this matters

Today every non-production environment shares the same config/dev/ overlay, so disabling shield for local also disables it on public dev URLs. This PR splits those concerns without changing existing behaviour for any environment that doesn't opt in.

What changed

  • scripts/deploy/govcms-config-import: read CONFIG_LOCAL_DIR, append a gated --partial import after the existing dev overlay. Header comment now documents the three-tier import order.
  • tests/bats/deploy/govcms-config-import.bats: 4 new test cases (local+present, local+absent, development+present regression guard, production+present).
  • tests/bats/deploy/fixtures/config/local/shield.settings.yml: new fixture matching the existing dev fixture pattern.

What didn't change

  • No changes to scripts/govcms-deploy or drupal/settings/*.
  • No new runtime dependencies.
  • Default behaviour for sites that don't add config/local/ is identical to today.

Backward compatibility

Fully backward compatible. The new code path is only reached when both LAGOON_ENVIRONMENT_TYPE=local and CONFIG_LOCAL_DIR contains YAML — neither is true for any existing GovCMS production or remote non-production environment.

Security notes

  • Gated on LAGOON_ENVIRONMENT_TYPE=local, set by the Lagoon local stack and not user-supplied at request time.
  • Strengthens the current posture by removing the incentive to weaken shield in config/dev/ for developer convenience.
  • No changes to secret handling, no new code execution paths beyond drush config:import.

Testing

$ bats tests/bats/deploy/govcms-config-import.bats
1..13
ok 1 Config import: defaults
ok 2 Config import: retain
ok 3 Config import: import
ok 4 Config import: default config
ok 5 Config import: dev config (production)
ok 6 Config import: dev config (nonprod)
ok 7 Config import: both dirs available (production)
ok 8 Config import: both dirs available (nonprod)
ok 9 Config import: local config (local env, all dirs)
ok 10 Config import: local config (local env, no local dir)
ok 11 Config import: local config not applied on development env
ok 12 Config import: local config not applied on production env
ok 13 Config import: upgrade branch

All 13 tests pass (9 pre-existing + 4 new).

Manual verification on a Compose-based GovCMS local stack:

  1. Add config/local/shield.settings.yml with shield_enable: false.
  2. Run govcms-deploy with LAGOON_ENVIRONMENT_TYPE=local.
  3. Confirm shield is disabled locally and still enabled on a remote Lagoon dev environment for the same project.

Adoption note for site projects

Once merged, a consuming GovCMS site project can:

  1. Create config/local/ in their project repo.
  2. drush config:export --destination=/app/config/local shield.settings on a local instance with shield disabled, or hand-write the YAML.
  3. Commit config/local/shield.settings.yml.

When their local stack sets LAGOON_ENVIRONMENT_TYPE=local (default for pygmy/lando/Compose-based GovCMS local dev), the next govcms-deploy will disable shield. Public Lagoon dev/staging URLs remain shielded.

Follow-ups

  • Consider a runtime local.settings.php companion in a future PR for settings overrides that shouldn't round-trip through drush cex.

…rides

Mirror the existing CONFIG_DEV_DIR pattern with a new optional
CONFIG_LOCAL_DIR (default /app/config/local). Apply it as an additional
`drush config:import --partial` step only when LAGOON_ENVIRONMENT_TYPE=local
AND the directory contains importable YAML.

Final overlay order:
  1. config/default/  (always, full import)
  2. config/dev/      (any non-production env, partial)
  3. config/local/    (local env only, partial) - new

This lets site projects place shield.settings.yml (and any other
local-only overrides) under config/local/ to keep shield disabled on
developers' machines without weakening it on public Lagoon dev/staging
URLs. The new code path is fully opt-in: no-op when config/local/ is
absent, never reached on remote Lagoon environments.

Adds four bats test cases covering:
- local env with all three dirs (asserts ordering and partial flag)
- local env with no local dir (asserts no third import call)
- development env with local dir present (regression guard for the
  local-only gate)
- production env with local dir present (only default import runs)
@jackwrfuller
Copy link
Copy Markdown

jackwrfuller commented May 12, 2026

Thanks for the contribution @ivangrynenko, I'll get this added to our internal backlog for review!

Internal ticket: GOVCMS-14851

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.

Add CONFIG_LOCAL_DIR overlay so local environments can override config without affecting public Lagoon dev URLs

2 participants