Skip to content

feat(containers): wro.cpp toolset containers v1 (6 images on GHCR) - #1

Merged
filipsajdak merged 6 commits into
mainfrom
feat/containers-v1
May 3, 2026
Merged

filipsajdak merged 6 commits into
mainfrom
feat/containers-v1

Conversation

@filipsajdak

Copy link
Copy Markdown
Contributor

Summary

MR2 of the Modern-C++-for-production expansion. Six Docker images published to ghcr.io/wrocpp/cpp-* via a multi-arch GitHub Actions matrix build. Powers the "Reproduce locally" affordance on every wro.cpp toolset page (https://wrocpp.github.io/toolset/).

Image map

Image Purpose Base Multi-arch
ghcr.io/wrocpp/cpp-base Shared substrate: Ubuntu 24.04 + clang-19 + GCC 13 + CMake + Ninja + Python3 + clang-tidy/format. ubuntu:24.04 amd64 + arm64
ghcr.io/wrocpp/cpp-safety Safety cluster: AFL++, libstdc++-debug, valgrind, sanitizers via clang-19. cpp-base amd64 + arm64
ghcr.io/wrocpp/cpp-performance Performance cluster: perf, google-benchmark, hyperfine. cpp-base amd64 + arm64
ghcr.io/wrocpp/cpp-security Security cluster: vcpkg, Conan, syft, grype, libsodium-dev, OpenSSL. cpp-base amd64 + arm64
ghcr.io/wrocpp/cpp-compliance Compliance cluster: cppcheck-MISRA, clang-tidy MISRA / CERT-C++ presets. cpp-base amd64 + arm64
ghcr.io/wrocpp/cpp-reflection Powers every "Reflection today" triptych sub-section. clang-p2996 ready to use. vsavkov/clang-p2996:${TARGETARCH} amd64 + arm64

Why this layout

Per the planning round on 2026-05-03: cluster containers do NOT need clang-p2996 (their tools are sanitizers, profilers, supply-chain, MISRA -- none of which need C++26 reflection). Apt-only Ubuntu keeps each cluster image small (~500MB-1.5GB) and CI builds in <5 minutes. cpp-reflection is FROM the community-maintained vsavkov/clang-p2996 image (per-arch tags), avoiding the 45-90 min cost of building clang-p2996 from source.

Workflow

  • .github/workflows/build-containers.yml -- matrix-build with three jobs:
    • base -- builds cpp-base, multi-arch (linux/amd64 + linux/arm64).
    • cluster -- 4-entry matrix (safety, performance, security, compliance) FROM cpp-base; multi-arch.
    • reflection -- builds cpp-reflection FROM vsavkov/clang-p2996:${TARGETARCH}; multi-arch via TARGETARCH switch.
  • Triggers on push to any branch touching containers/** or the workflow file.
  • permissions: packages: write + GHCR login via secrets.GITHUB_TOKEN. No PAT needed.
  • Tag scheme: 2026-05 (rolling, on main), branch-<sanitised-name> (per branch), sha-<commit> (per build).

Verification (already done on this branch)

  • All 6 jobs green on the latest workflow run.
  • Local pull + smoke test from arm64 macOS for each image:
    • cpp-safety: `afl-fuzz, clang-tidy, valgrind` all present.
    • cpp-performance: `perf, hyperfine, /usr/include/benchmark/` all present.
    • cpp-security: `vcpkg 2026-04-08, conan, syft, grype` all present.
    • cpp-compliance: `cppcheck 2.13.0, clang-tidy 19.1.1, clang-format 19.1.1` all present, presets at /opt/wrocpp/.
    • cpp-reflection: `uname -m == aarch64`, clang-p2996 (clang 21.0.0git from Bloomberg fork) at `/opt/p2996/clang/bin`.

Commit shape

feat(containers): scaffold cpp-base + GH Actions workflow + README
feat(ci): GH Actions workflow to build + push cpp-base to GHCR
fix(ci): build cpp-base for both linux/amd64 and linux/arm64
feat(containers): add 5 specialised images (safety/perf/security/compliance/reflection)
fix(containers): cpp-safety drops afl++-clang; cpp-reflection uses TARGETARCH
fix(containers): install clang-tidy-19 + clang-format-19 explicitly

Test plan

  • All 6 GH Actions jobs green
  • All 6 images pull cleanly on arm64
  • Smoke tests pass for each image (tools present, versions correct)
  • Manual: after merge to main, confirm 2026-05 tag appears at https://github.com/orgs/wrocpp/packages

Follow-ups

  • Per-cluster entry scripts (containers/scripts/run-asan.sh, run-perf.sh, run-misra.sh, etc.) -- ship just-in-time with each toolset section MR (MR3-MR11 in the broader plan).
  • Site-repo PR (DockerRun.astro component + AGENTS.md update) -- separate PR, lands together with this one.

🤖 Generated with Claude Code

filipsajdak and others added 6 commits May 3, 2026 20:26
First slice of MR2. Lays the foundation:
- containers/base/Dockerfile: Ubuntu 24.04 + apt clang-19 + GCC 14 +
  CMake + Ninja + Python3. Apt-only, builds in <5 min on CI.
- .github/workflows/build-containers.yml: matrix-ready workflow with
  packages:write, GHCR login, buildx + GHA cache. Currently builds just
  cpp-base; cluster images get added in follow-up commits to this
  branch and the workflow gains them as additional jobs.
- containers/README.md: image map, tag scheme, pull/run/build-local
  recipes.

Tag scheme: rolling 2026-05 on main, branch-<name> on feature branches,
sha-<commit> per build. CI publishes to ghcr.io/wrocpp/cpp-base:* on
every push that touches containers/** or this workflow file.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds .github/workflows/build-containers.yml with packages:write
permission, GHCR login via GITHUB_TOKEN, buildx + GHA cache. Currently
publishes only cpp-base; cluster jobs added in follow-up commits.

All workflow-input values use controlled system context (github.actor,
github.ref_name, github.sha, secrets.GITHUB_TOKEN). No user-controlled
text (issue body, commit message body) flows into shell. REF_NAME
routes through env: var per the workflow-injection guidance the
security hook flagged.

Tag scheme:
  - main push touching containers/** -> 2026-05 (rolling)
  - any branch push -> branch-<name>
  - every build -> sha-<commit>

Push branch + workflow runs immediately; first run validates the GHCR
publish pipeline before adding the other 5 images.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Default GH Actions runner is x86_64; the previous build pushed only
linux/amd64, which fails to pull on Apple Silicon developer machines
("no matching manifest for linux/arm64/v8"). Adds QEMU + multi-arch
builds. apt clang-19 + GCC + CMake + Ninja are all available on both
architectures, so no Dockerfile changes needed.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…liance/reflection)

Builds out the rest of the wro.cpp container fleet:

- containers/safety/Dockerfile -- FROM cpp-base + AFL++, libstdc++-debug,
  valgrind. Sanitizers + clang-tidy already in cpp-base via clang-19.
- containers/performance/Dockerfile -- FROM cpp-base + linux-tools
  (perf), google-benchmark headers, hyperfine. Tracy server + Perfetto
  SDK intentionally NOT bundled (heavy GUI/build deps); toolset page
  links upstream + ships scripts/run-perf.sh for the apt perf.
- containers/security/Dockerfile -- FROM cpp-base + libssl-dev,
  libsodium-dev, Conan (pip), syft + grype (Anchore install scripts),
  vcpkg (clone + bootstrap, VCPKG_ROOT pre-set).
- containers/compliance/Dockerfile -- FROM cpp-base + cppcheck (with
  bundled MISRA addon), plus three configuration files: clang-tidy
  MISRA preset, clang-tidy CERT preset, cppcheck-MISRA addon config.
  Run scripts use these presets by default.
- containers/reflection/Dockerfile -- FROM vsavkov/clang-p2996 + cmake
  + ninja + python3 + git. amd64-only initially (vsavkov hasn't shipped
  arm64 yet); arm64 macOS readers pull via Rosetta. Tag with note in
  the workflow so we can re-enable multi-arch when upstream lands it.

Workflow gains two new jobs:
- `cluster` matrix job (4 entries: safety, performance, security,
  compliance), depends on the base job, multi-arch (linux/amd64 +
  linux/arm64), passes BASE_TAG via build-args so cluster images FROM
  the freshly-built cpp-base.
- `reflection` job, no dependency on base (different lineage),
  amd64-only.

After this commit lands, all 6 wro.cpp images publish on every push
touching containers/. CI runtime expected ~10-15 min for the matrix.

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

Two CI failures from previous push:

1. cpp-safety: apt install failed because `afl++-clang` does not exist
   as a separate package in Ubuntu 24.04 (afl++ bundles clang support).
   Drop the bogus package name; afl++ alone is correct.

2. cpp-reflection: `vsavkov/clang-p2996:latest` does not exist; vsavkov
   ships per-architecture tags (amd64, arm64). Use ARG TARGETARCH (auto-
   set by buildx during multi-arch builds) to pick the right tag per
   platform. Bonus: cpp-reflection now builds genuinely multi-arch
   (both linux/amd64 + linux/arm64), where the previous attempt
   would have been amd64-only.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
clang-tools-19 does NOT bundle clang-tidy or clang-format on Ubuntu
24.04 -- they are separate apt packages (clang-tidy-19, clang-format-19).
The /usr/local/bin symlinks I added in cpp-base were dangling because
their targets did not exist. Adds the explicit packages so cpp-safety
+ cpp-compliance get a working clang-tidy.

Also drops the redundant `clang++-19` and second `ca-certificates`
entries (clang-19 ships clang++ as part of the same package; ca-certs
appeared twice).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@filipsajdak
filipsajdak merged commit 720816a into main May 3, 2026
6 checks passed
@filipsajdak
filipsajdak deleted the feat/containers-v1 branch May 3, 2026 19:06
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