Skip to content

ci: build the dev and distribution images, push to GHCR by hand only - #192

Merged
h0ffmann merged 4 commits into
mainfrom
goal/fe2173f3-4827-ghcr-images
Oct 18, 2026
Merged

h0ffmann merged 4 commits into
mainfrom
goal/fe2173f3-4827-ghcr-images

Conversation

@h0ffmann

@h0ffmann h0ffmann commented Oct 18, 2026 •

Copy link
Copy Markdown
Owner

Summary — Goal fe2173f3 (session cf0ba05d-2aa3-4303-b426-4730fe2173f3). Two images, two workflows.

Tested not recorded — add a Tested: trailer to the commit

What changed

  • ci: build the dev and distribution images, push to GHCR by hand only (f2ccff5)
  • ci: every Docker build on GitHub Actions starts by hand only (f23936e)
  • docker: the CUDA image builds with WW_KOKKOS_LIBM=OFF (3d00e2c)
  • docker: the runtime images carry switches/switch_lab_ompg (7aa8722)

h0ffmann and others added 3 commits October 18, 2026 13:08
Goal fe2173f3 (session cf0ba05d-2aa3-4303-b426-4730fe2173f3). Two images, two workflows.
docker-dev.yml builds the dev stage of docker/Dockerfile (the image the devcontainer uses; no
sources, the checkout is mounted), so working on ww3-gpu needs only Docker. docker-dist.yml
builds the runtime images, CPU (docker/Dockerfile) and CUDA (docker/Dockerfile.cuda), each with
NOAA's WW3 at the WW3-noaa pin and ww3-gpu compiled side by side and no source file, so an
outside user can run both on one case and compare the outputs. A pull request builds and checks;
only a manual workflow_dispatch with push ticked pushes to ghcr.io, from a job that alone holds
packages: write, in the environment ghcr; a typed `latest` is refused, `latest` moves only from
main. scripts/docker.sh gains build-dev, run-dev, submodules, check and push, and OCI labels that
name the two WW3 commits; devcontainer.json takes the published dev image as cacheFrom.

Tested: bash scripts/docker.sh --self-test (ok); shellcheck scripts/docker.sh (clean); actionlint
on both workflows (clean); scripts/docker.sh build-dev ci and the workflow's tool check (gfortran
15.2.0, CMake 4.2.3, just 1.45.0, ShellCheck 0.11.0, Nix 2.34.3, /opt/kokkos); scripts/docker.sh
submodules && build ci && check ww3-gpu:ci (binaries only: ok); scripts/vale.sh README.md (0
errors); security-reviewer (no finding; its two hardening notes applied). CUDA image not built
locally; nothing pushed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Goal fe2173f3. The owner's rule: no Docker image is built or pushed by a push, a pull request or
a schedule; the only way is a manual workflow_dispatch. docker-dev.yml and docker-dist.yml lose
their pull_request trigger and their read-only build job, leaving one dispatch-only job each (push
still behind the `push` input and the ghcr environment), and docker-scan.yml, which built the CPU
image on every change, on main and weekly, becomes dispatch-only too. The READMEs say so.

Tested: actionlint .github/workflows/docker-*.yml (clean); grep of .github/workflows for docker
build, docker push, docker.sh and the devcontainer CLI finds only these three workflows;
scripts/vale.sh README.md (0 errors). The PR's running docker-dist and docker-scan runs were
cancelled.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Goal fe2173f3. docker/Dockerfile.cuda had not built since the device libm (WFIP-0006, #178):
gen_tables looks up the hidden __svml_spow_data in libmvec.so.1's symbol table, and Ubuntu's
libmvec is stripped (readelf finds no .symtab in the nvidia/cuda:13.4.2-devel-ubuntu26.04
image), so it exits 3. The owner chose libdevice for the image: the port is configured with
WW_KOKKOS_LIBM=OFF, BUILD_INFO says so, and the READMEs say a GPU run in the image is judged by
tolerance (ADR-0014).

Tested: the steps of docker-dev.yml and docker-dist.yml run locally at this branch:
scripts/docker.sh build-dev ci and its tool check (ok); submodules, build ci, check ww3-gpu:ci
(binaries only: ok); build-cuda ci, check ww3-gpu-cuda:ci (binaries only: ok; compiled, never
run on a GPU); the push step as a dry run (sha-<short> and latest refs); scripts/vale.sh
README.md (0 errors).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Goal fe2173f3. Since 3023bb6, scripts/ww3-gpu.sh reads switches/<WW3GPU_SWITCH> (default
switch_lab_ompg) before any run, prebuilt or not, and neither runtime stage copied it, so the
distribution image exited 64 on its first run ("WW3GPU_SWITCH is a switches/switch_lab_* file").
Both Dockerfiles copy it next to the entry point. scripts/docker.sh check now also starts the
entry point with --ww3 and --ww3-gpu (--gpu in the CUDA image) and --build-only, which stops
before any run, so the workflow catches this class of failure.

Tested: docker run ww3-gpu:ci --ww3-gpu smoke --build-only exited 64 before the fix;
scripts/docker.sh --self-test (ok); shellcheck (clean); build ci + check ww3-gpu:ci (ok, both
modes start); the CUDA image built before the fix fails the new check (64); build-cuda ci + check
ww3-gpu-cuda:ci (ok). No case run, no GPU used.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
h0ffmann added a commit that referenced this pull request Oct 18, 2026
Goal eb10363f, from the owner's session. A decision record for the CMake
option WW_KOKKOS_LIBM: ON (device copies of glibc 2.44, WFIP-0006, the
library default) against OFF (libdevice, judged by tolerance per ADR-0014),
which the CUDA image of PR #192 uses because Ubuntu's libmvec has no
.symtab. It compares bits, verification, portability across CPUs, build
requirements and speed, lists what is incomplete with ON, and evaluates
three ways to make ON work in the image. The position: ON on the lab
machine with the Nix toolchain, OFF in the distributed image, timings both
ways. A check on this host shows Ubuntu's libc6-dbg file has the symbol
and Ubuntu 2.43's libmvec tables equal Nix 2.44's byte for byte.
GLOSSARY gains one row (stripped library / .symtab / debug file).

Tested: vale --config=.vale.ini on docs/KOKKOS_LIBM_ON_VS_OFF.md and docs/GLOSSARY.md (the steps of scripts/vale.sh): 0 errors, 0 warnings; every relative link of the new page resolves (ls of each target); no em dash; readelf and a byte comparison of the two libmvec.so.1 files run as section 7 of the page says; nothing ran on a GPU
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@h0ffmann
h0ffmann merged commit b7e5476 into main Oct 18, 2026
8 checks passed
h0ffmann added a commit that referenced this pull request Oct 18, 2026
Plan 003: #193 is merged; the CUDA Docker image of #192 builds with
WW_KOKKOS_LIBM=OFF, so it calls CUDA's libm and stays out of the first
GPU run; #194's KOKKOS_LIBM_ON_VS_OFF.md holds the owner's decision on
that option, and A3 records the value the run's build has. Plan 004: the
UFS NUOPC cap on production/GFS.v17 reads VA after W3WAVE, so its host
uses are listed and synced, and one coupled case runs with the VA
poison, as section 29 did for the ESMF cap.

Tested: nix shell nixpkgs#vale -c scripts/vale.sh on both plans, rc 0

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@h0ffmann
h0ffmann deleted the goal/fe2173f3-4827-ghcr-images branch October 18, 2026 20:03
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