Skip to content

Feat/docker ci - #36

Merged
sametd merged 7 commits into
mainfrom
feat/docker-ci
Apr 15, 2026
Merged

Feat/docker ci#36
sametd merged 7 commits into
mainfrom
feat/docker-ci

Conversation

@sametd

@sametd sametd commented Apr 15, 2026

Copy link
Copy Markdown
Member

Description

Replaces per-job tool installation (LLVM, cmake, apt-get, rust-toolchain, setup-uv, setup-node, wasm-pack) with a single pre-baked Docker image. macOS jobs are unchanged.

Image (eccr.ecmwf.int/tensogram/ci)

  • Base: Ubuntu 24.04 (cmake 3.28 + LLVM 18 from default repos — zero PPAs)
  • Multi-stage build: wasm-pack compiled in builder stage, only the binary copied to final image
  • 1.55 GB compressed (Rust 1.94.0, clippy, rustfmt, wasm32 target, wasm-pack 0.14.0, uv 0.11.6, cmake, libclang, eccodes/netcdf/hdf5)
  • Python and Node.js installed at CI runtime (~10s and ~3s respectively) to keep the image small
  • All tool versions pinned as ARGs at the top of the Dockerfile
  • Semver versioning via .github/ci/VERSION → tags :1.0.0, :1.0, :1, :latest

CI restructuring

Before After
main (matrix: Linux + macOS) main-linux (container) + main-macos (bare metal)
cpp (matrix: Linux + macOS) cpp-linux (container) + cpp-macos (bare metal)
python-free-threaded (Linux, installs LLVM/cmake/uv) python-free-threaded (container, zero setup)
python-packages (Linux, installs LLVM/cmake/uv) python-packages (container, zero setup)
wasm (Linux, installs rust-toolchain/node/wasm-pack) wasm (container, only downloads node binary)

Eliminated from every Linux job: KyleMayes/install-llvm-action, dtolnay/rust-toolchain, astral-sh/setup-uv, actions/setup-node, apt-get install, cmake pip fallback, cargo install wasm-pack, has_grib_deps conditional.
Other changes:

  • Swatinem/rust-cache removed from all jobs (doesn't work reliably on self-hosted runners)
  • python-free-threaded and python-packages now gate on main-linux only (not macOS) — they start sooner
  • permissions: contents: read added for least privilege
  • workflow_dispatch added to CI for manual re-runs (needed for bootstrap)
  • Cleanup steps kept on container jobs (if: always()) for root-owned files on self-hosted runners
  • GRIB/NetCDF tests run unconditionally on Linux (deps are always present in the image)

New files

File Purpose
.github/ci/Dockerfile Multi-stage CI image
.github/ci/VERSION Semver version for image tags
.github/workflows/ci-image.yml Build + push image on Dockerfile changes (build-only on PRs)

Locally verified inside the container

Job Result
cargo fmt + clippy + test --workspace
GRIB + NetCDF
Python bindings (412 tests)
C++ FFI (135 tests)
WASM (134 tests)

Contributor Declaration

By opening this pull request, I affirm the following:

  • All authors agree to the Contributor License Agreement.
  • The code follows the project's coding standards.
  • I have performed self-review and added comments where needed.
  • I have added or updated tests to verify that my changes are effective and functional.
  • I have run all existing tests and confirmed they pass.

Docs Preview
https://sites.ecmwf.int/docs/dev-section/tensogram/pull-requests/PR-36

@sametd
sametd requested review from tlmquintino April 15, 2026 18:38
sametd added 7 commits April 15, 2026 22:03
Pre-bakes Rust 1.94.0 + clippy/rustfmt + wasm-pack 0.14.0 + uv on
Ubuntu 24.04. Python and Node.js are installed at CI runtime to keep
the image at 1.55 GB.

- Multi-stage build: wasm-pack compiled in builder, only binary copied
- libclang1-18 instead of libclang-18-dev (saves ~250 MB)
- Static .a libs stripped, shared libs stripped of debug symbols
- All tool versions pinned as ARGs at the top for easy bumps
- VERSION file for semver tagging (1.0.0)
Triggers on pushes to main touching .github/ci/** and on PRs
(build-only, no push). Publishes four tags per build: :1.0.0,
:1.0, :1, :latest. Uses docker/build-push-action with GHA cache.
Split matrix jobs into Linux (container) + macOS (bare metal).
5 Linux jobs now run inside eccr.ecmwf.int/tensogram/ci:1.0.0,
eliminating LLVM, cmake, apt-get, rust-toolchain, setup-uv,
setup-node, and wasm-pack installation steps.

- Python installed at runtime via uv python install (~10s)
- Node.js downloaded at runtime for WASM job (~3s)
- Swatinem/rust-cache removed (incompatible with self-hosted runners)
- Cleanup steps kept on all jobs (root-owned files on self-hosted)
- permissions: contents: read for least privilege
- python-free-threaded/python-packages now gate on main-linux only
…lity

Split main-linux into 3 parallel container jobs:
- lint: fmt + focused clippy (no wasted test-mode compilation)
- test: all cargo test runs in optimal artifact-reuse order
- python: bindings build + pytest (separate build world)

Also fixes:
- 'source' -> '.' for POSIX sh compatibility in containers
- Over-broad '--all-features' clippy replaced with targeted feature
  checks per crate (avoids needless feature unification)
Remove libnetcdf-dev, libhdf5-dev, libeccodes-dev from the Docker
image since GRIB/NetCDF are already tested on macOS. Merges
python-free-threaded and python-packages into the test job to
reuse compiled artifacts. Bumps image to 1.1.0.
@sametd
sametd merged commit 7602888 into main Apr 15, 2026
13 checks passed
@sametd
sametd deleted the feat/docker-ci branch April 15, 2026 20:34
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