Skip to content

Build the full-stack image once at RC time, so GA can promote it - #159

Merged
jsokol merged 3 commits into
testingfrom
FEATURE-full-image-buildonce-testing
Aug 21, 2026
Merged

Build the full-stack image once at RC time, so GA can promote it#159
jsokol merged 3 commits into
testingfrom
FEATURE-full-image-buildonce-testing

Conversation

@jsokol

@jsokol jsokol commented Aug 21, 2026

Copy link
Copy Markdown
Member

Description

Prerequisite for the GA promote cutover (FEATURE-ga-promote-cutovermaster). That PR makes GA a promote of an existing RC digest rather than a rebuild. For simplerisk/simplerisk-minimal the RC already exists; for the full-stack simplerisk/simplerisk image it does not — that image has only ever been built on master from the prod bundle. This PR gives it an RC build so there is something to promote.

Three changes:

1. simplerisk/generate_dockerfile.sh — decouple version from source-mode.
The generator branched its recipe on the literal string testing, so a context-sourced build could only ever stamp ENV version=testing. That single coupling is what kept the full-stack image out of the build-once model — an RC has to carry a real version to be promotable. Adds the same (version, source_mode) split simplerisk-minimal already has: context COPYs the app from the build context, download emits the hash-verifying downloader stage. Defaults preserve back-compat exactly — a bare testing still selects context, a bare version still selects download.

Also restores --fail on the schema fetch. It is present on master (commit 6351391) but absent on testing; without it curl writes the 404 body into /simplerisk.sql and the image ships an HTML error page as its database schema.

2. publish-testing.yml — build the full-stack RC alongside the minimal one.
New publish-full job tagging <VERSION>-jammy, <VERSION>-noble, bare <VERSION> (= noble, the default) and :testing. amd64-only, matching what the release build published before. No SSM tier — the full-stack image is not part of the managed fleet.

Version resolution is hoisted into a shared resolve job so both publish jobs stamp the same release even if the testing channel rotates mid-run, and each now fetches that exact bundle by name instead of re-listing the channel.

3. container-validation.yml — pin both generators.
The generators are now load-bearing for the release path, but neither harness ran in CI. Adds a generator_checks job running both, plus a guard that fails if a harness leaves a committed Dockerfile modified.

Release Notes

No customer-facing change. Container build/release plumbing only.

Manual Validation Steps

  1. ./simplerisk/test_generate_dockerfile.sh → 14 checks, all ok, exit 0.
  2. ./simplerisk-minimal/test_generate_dockerfile.sh → still green (unchanged).
  3. ./simplerisk/generate_dockerfile.sh 20260519-001 → regenerates the committed Dockerfile with only the intended -fsSL change; no structural drift.
  4. ./simplerisk/generate_dockerfile.sh <V> context → no FROM alpine/curl stage, ENV version=<V>, COPY ./simplerisk/ /var/www/simplerisk.
  5. ./simplerisk/generate_dockerfile.sh <V> bogus → exits 1 with Invalid source mode.
  6. After merge, the next push to testing should publish simplerisk/simplerisk:<VERSION>-jammy, -noble, bare <VERSION> and move :testing.

Type of Change

  • Build / CI configuration
  • Bug fix (the missing --fail on the schema fetch)

Testing Results

  • Both generator harnesses pass locally (14 + existing checks, exit 0).
  • shellcheck clean at all severities on both changed/added scripts (CI gates at error). One deliberate SC2016 suppression where $DB_LANG must stay literal — it is a Dockerfile ARG.
  • actionlint clean on publish-testing.yml and container-validation.yml.
  • YAML parses; job graph is resolve → (publish, publish-full).
  • Not exercised end-to-end: the actual RC image build only runs on a push to testing. The first post-merge testing push is the real test.

CIA Impact Check

WILL NOT negatively impact Confidentiality, Integrity or Availability.

The bundle hash verification, the fail-closed download path, and the published tag set for simplerisk-minimal are all unchanged. The full-stack image gains RC tags it did not previously have; no existing tag changes meaning. The --fail restoration is a net integrity improvement — it prevents an image shipping an HTML error page as its schema.

jsokol and others added 3 commits August 21, 2026 10:55
simplerisk/generate_dockerfile.sh branched its recipe on the literal string
"testing", so a context-sourced build could only ever stamp
`ENV version=testing`. That is the one thing standing between the full-stack
image and the build-once-promote model: the RC has to carry a real version to
be promotable at GA.

Add the same (version, source_mode) split simplerisk-minimal already has:
`context` COPYs the app from the build context, `download` emits the
hash-verifying downloader stage. The default preserves back-compat exactly --
a bare "testing" still selects context, a bare version still selects download.

Also restore --fail on the schema fetch (present on master, lost on testing).
Without it curl writes the 404 body into /simplerisk.sql and the image ships
an HTML error page as its schema.

Adds test_generate_dockerfile.sh mirroring the minimal harness: 14 checks over
both modes, both back-compat paths, invalid-mode rejection and idempotence.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…nimal

GA promotes digests rather than rebuilding, so every image it promotes has to
exist as an RC. simplerisk/simplerisk had no RC build at all -- it was only
ever built on master from the prod bundle, which is exactly the rebuild the
promote model removes.

Add a publish-full job tagging <VERSION>-jammy/-noble, bare <VERSION> (= noble,
the default) and :testing, amd64-only to match what the release build published
before. No SSM tier: the full-stack image is not part of the managed fleet.

Hoist version resolution into a shared resolve job so both publish jobs stamp
the same release even if the testing channel rotates mid-run, and have each
fetch that exact bundle by name rather than re-listing the channel.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The generators are now load-bearing for the release path -- context mode has to
stamp a real ENV version, download mode has to keep the hash-verifying
downloader stage -- but neither harness was wired into CI. Run both on PRs, and
fail if either leaves a committed Dockerfile modified.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@jsokol
jsokol marked this pull request as ready for review August 21, 2026 16:03
@jsokol
jsokol merged commit af02e01 into testing Aug 21, 2026
7 checks passed
@jsokol
jsokol deleted the FEATURE-full-image-buildonce-testing branch August 21, 2026 16:10
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