Skip to content

ci: seed the validation .env from one script, not two copies - #20

Merged
Gerrrt merged 1 commit into
mainfrom
fix/rendered-secrets-container-uid
Aug 18, 2026
Merged

ci: seed the validation .env from one script, not two copies#20
Gerrrt merged 1 commit into
mainfrom
fix/rendered-secrets-container-uid

Conversation

@Gerrrt

@Gerrrt Gerrrt commented Aug 18, 2026

Copy link
Copy Markdown
Owner

The throwaway .env that gets compose.yaml's ${VAR:?} guards past
validation was built in two places: a run: block in ci.yml and a heredoc in
validate.sh. Both copied .env.example and appended the same variables, and
nothing tied them together.

They drifted the first time the list changed. 2431173 added the
RENDER_UID/RENDER_GID guards and updated only validate.sh, so it passed
locally and failed in CI:

error while interpolating services.alertmanager.user:
required variable RENDER_UID is missing a value: run make render

and needed a follow-up commit (165394c) to fix the copy that was missed.

scripts/seed-validation-env.sh is extracted and both callers invoke it, so the
list exists once. The script takes an output path; lifetime stays with the
caller, which is the only thing the two genuinely disagree about — CI wants the
gitignored stacks/observability/.env, validate.sh wants an mktemp file it
removes on a trap.

Sharing the script stops the two callers drifting from each other. It does not
stop both drifting from compose.yaml, so the script also asserts it covers
every ${VAR:?} it finds there — a newly guarded variable fails at seeding time
and names itself, rather than surfacing as an opaque interpolation error in
whichever caller runs first.

History

This commit was pushed to fix/rendered-secrets-container-uid after #15 was
merged, so it never had a PR of its own and was never merged. It surfaced during
a branch cleanup: its tip no longer matched the tip #15 recorded as merged, and
scripts/seed-validation-env.sh did not exist on main.

Rebased from 165394c onto 475126b. No conflicts, though main has since
touched both compose.yaml (b4da221) and validate.sh (c971366).

Verification

Run against the rebased tree:

  • shellcheck scripts/*.sh — clean
  • seeder writes all three guarded variables (GRAFANA_ADMIN_PASSWORD,
    RENDER_UID, RENDER_GID) plus the .env.example defaults
  • docker compose --env-file <seeded> config -q — passes
  • negative test: adding ${NEWLY_GUARDED_VAR:?} to compose.yaml makes the
    seeder exit 1 with
    compose.yaml guards NEWLY_GUARDED_VAR, which the validation .env does not set.
    (compose.yaml restored afterwards)
  • ./scripts/validate.sh — all checks pass except gitleaks (full history),
    which fails only because the local gitleaks is 8.30.1 against CI's pinned
    8.24.0 and the .gitleaksignore fingerprints do not match across that gap.
    Pre-existing on main, unrelated to this branch.

🤖 Generated with Claude Code

The throwaway .env that gets compose.yaml's `${VAR:?}` guards past validation
was built in two places: a `run:` block in ci.yml and a heredoc in validate.sh.
Both copied .env.example and appended the same variables, and nothing tied them
together.

They drifted the first time the list changed. 2431173 added the
RENDER_UID/RENDER_GID guards and updated only validate.sh, so the change passed
locally and failed in CI:

  error while interpolating services.alertmanager.user:
  required variable RENDER_UID is missing a value: run make render

and needed a follow-up commit (165394c) to fix the copy that was missed.

Extract scripts/seed-validation-env.sh and have both callers invoke it, so the
list of variables exists once. The script takes an output path and writes;
lifetime stays with the caller, which is the only thing the two genuinely
disagree about — CI wants the gitignored stacks/observability/.env, validate.sh
wants an mktemp file it removes on a trap. Hardcoding either inside the script
would have left it able to serve only one of them.

Sharing the script stops the two copies drifting from each other, but both
could still drift from compose.yaml, so the script also asserts it covers every
`${VAR:?}` it finds there. A newly guarded variable now fails at seeding time
and names itself:

  compose.yaml guards NEW_VAR, which the validation .env does not set.

rather than surfacing as an interpolation error in whichever caller runs first.

validate.sh runs without `set -e`, so a failed seed had to be caught explicitly
or the compose check would have run against a half-written file and reported
its confusing error instead; the existing if/else grew a leading `if ! seed`
branch that reports through the usual fail().

Co-Authored-By: Claude Opus 5 <[email protected]>
@Gerrrt
Gerrrt merged commit 3287815 into main Aug 18, 2026
3 checks passed
@Gerrrt
Gerrrt deleted the fix/rendered-secrets-container-uid branch August 18, 2026 22:39
Gerrrt added a commit that referenced this pull request Aug 19, 2026
ci: seed the validation .env from one script, not two copies
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.

1 participant