From ef13d9ea6180a055a54e8c93b7d67af630e46e1a Mon Sep 17 00:00:00 2001 From: Arav Garg Date: Fri, 24 Jul 2026 08:29:34 -0500 Subject: [PATCH] R1-02: CI pipeline v1 Adds .github/workflows/pr.yml running on every pull request and push to main (docs/build/CI_PLAN.md scope for R1-02): - format: pinned clang-format 20.1.7 via pip so formatting is reproducible across machines rather than dependent on a contributor's local LLVM version. Verified locally that 20.1.7 and the 22.x used to format the tree agree byte-for-byte. - build matrix: linux {debug, asan-ubsan, release} + macos debug, each configure/build/test through its preset with -Werror enabled (CI-only, per BUILD_SYSTEM.md). - ccache (also caches the gtest/benchmark compile) + FetchContent source caching keyed on cmake/deps.cmake; per-ref concurrency with cancel-in-progress. tidy/deps/spec-coverage/python/bench-smoke jobs are intentionally absent until their subjects exist (R1-24, R2, R1-23), so CI never references tooling that is not yet in the tree. README gains a developer section (build commands, canonical clang-format version, contributing workflow, recommended branch protection); BUILD_SYSTEM.md records the pinned clang-format version. Co-Authored-By: Claude Fable 5 --- .github/workflows/pr.yml | 109 +++++++++++++++++++++++++++++++++++++ README.md | 60 +++++++++++++++++++- docs/build/BUILD_SYSTEM.md | 4 +- 3 files changed, 171 insertions(+), 2 deletions(-) create mode 100644 .github/workflows/pr.yml diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml new file mode 100644 index 0000000..cbf3328 --- /dev/null +++ b/.github/workflows/pr.yml @@ -0,0 +1,109 @@ +# Per-PR and push-to-main continuous integration (docs/build/CI_PLAN.md). +# +# Scope for task R1-02: format, linux-debug, linux-asan, linux-release, macos. +# The tidy, deps/spec-coverage, python, and bench-smoke jobs arrive with their +# subjects (R1-24, R2, R1-23) so CI never references tooling that does not exist. +# +# Performance note: no benchmark *numbers* are produced here. Authoritative +# measurement happens only on the dev Mac (docs/performance/METHODOLOGY.md); +# cross-runner comparison is never valid. + +name: CI + +on: + pull_request: + push: + branches: [main] + +# One in-flight run per ref; a new push cancels the previous (free-tier minutes). +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +permissions: + contents: read + +jobs: + # --------------------------------------------------------------------------- + # Formatting. clang-format is pinned via pip so CI and every contributor use + # the identical version — formatting is reproducible, never version-dependent. + # The canonical version also appears in docs/build/BUILD_SYSTEM.md. + # --------------------------------------------------------------------------- + format: + runs-on: ubuntu-24.04 + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + with: + python-version: "3.12" + - name: Install pinned clang-format + run: pip install "clang-format==20.1.7" + - name: Check formatting + run: ./scripts/format.sh --check + + # --------------------------------------------------------------------------- + # Build + test matrix. -Werror is enabled here (and only here): the strict + # warning set gates CI while local iteration stays unblocked (decision in + # docs/build/BUILD_SYSTEM.md). + # --------------------------------------------------------------------------- + build: + name: ${{ matrix.name }} + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + include: + - name: linux-debug + os: ubuntu-24.04 + preset: debug + - name: linux-asan + os: ubuntu-24.04 + preset: asan-ubsan + - name: linux-release + os: ubuntu-24.04 + preset: release + - name: macos-debug + os: macos-14 + preset: debug + steps: + - uses: actions/checkout@v4 + + - name: Install build tools (Linux) + if: runner.os == 'Linux' + run: sudo apt-get update && sudo apt-get install -y ninja-build clang + + - name: Install build tools (macOS) + if: runner.os == 'macOS' + run: brew install ninja + + # ccache also caches the compilation of the FetchContent dependencies + # (gtest, benchmark), which dominate a cold build. + - name: Set up ccache + uses: hendrikmuhs/ccache-action@v1.2 + with: + key: ${{ matrix.name }} + max-size: 400M + + # Cache the fetched dependency *sources* so git clones are skipped when + # cmake/deps.cmake is unchanged. + - name: Cache FetchContent sources + uses: actions/cache@v4 + with: + path: .deps-cache + key: deps-${{ runner.os }}-${{ hashFiles('cmake/deps.cmake') }} + + - name: Configure + env: + CC: ${{ runner.os == 'Linux' && 'clang' || '' }} + CXX: ${{ runner.os == 'Linux' && 'clang++' || '' }} + run: > + cmake --preset ${{ matrix.preset }} + -DMICROSIM_WERROR=ON + -DCMAKE_CXX_COMPILER_LAUNCHER=ccache + -DFETCHCONTENT_BASE_DIR=${{ github.workspace }}/.deps-cache + + - name: Build + run: cmake --build --preset ${{ matrix.preset }} + + - name: Test + run: ctest --preset ${{ matrix.preset }} diff --git a/README.md b/README.md index 46f4034..3f2dc11 100644 --- a/README.md +++ b/README.md @@ -1 +1,59 @@ -# MicroSim-Quant \ No newline at end of file +# MicroSim-Quant + +> Deterministic simulated electronic exchange and market-microstructure research platform. +> A C++20 price-time-priority matching engine with a latency laboratory, agent-based order +> flow, and a Python research interface for reproducible market-making experiments. + +**Status:** early construction (Release 1). The full specification suite lives under +[`docs/`](docs/); the vision is in [`docs/product/PROJECT_VISION.md`](docs/product/PROJECT_VISION.md) +and every design decision is logged in [`docs/DECISIONS.md`](docs/DECISIONS.md). A +recruiter-facing README (architecture diagram, benchmarks, findings) is assembled at the +Release 1 milestone; until then this file is developer-facing. + +## Development + +Requirements: CMake ≥ 3.27, Ninja, a C++20 compiler (AppleClang 15+ / Clang 16+ / GCC 13+). +Build tooling and rationale are documented in +[`docs/build/BUILD_SYSTEM.md`](docs/build/BUILD_SYSTEM.md). + +```bash +# Configure, build, and test (development default) +cmake --preset debug +cmake --build --preset debug +ctest --preset debug + +# Sanitizers (AddressSanitizer + UndefinedBehaviorSanitizer, findings are hard failures) +cmake --preset asan-ubsan && cmake --build --preset asan-ubsan && ctest --preset asan-ubsan + +# Optimized build (benchmarks and experiments) +cmake --preset release && cmake --build --preset release && ctest --preset release +``` + +Format all C++ sources (or `--check` to verify, as CI does): + +```bash +./scripts/format.sh # rewrite in place +./scripts/format.sh --check # verify only +``` + +**Canonical `clang-format` version: 20.1.7.** CI pins it via `pip install clang-format==20.1.7` +so formatting is reproducible across machines; use the same version locally to avoid spurious +diffs (`pipx install clang-format==20.1.7`, or Homebrew's is close enough for the current code). + +### Contributing workflow + +- Work happens on `task/-` branches, one implementation task per pull request + (see [`docs/execution/OPUS_HANDOFF.md`](docs/execution/OPUS_HANDOFF.md) and + [`docs/execution/IMPLEMENTATION_TASKS.md`](docs/execution/IMPLEMENTATION_TASKS.md)). +- CI ([`.github/workflows/pr.yml`](.github/workflows/pr.yml)) must be green before merge: + formatting, plus build + test on Linux (`debug`, `asan-ubsan`, `release`) and macOS + (`debug`). Warnings are errors on CI (`-Werror`); locally they are warnings so iteration + stays unblocked. +- **Recommended branch protection for `main`** (set once by the repo owner in GitHub + Settings → Branches): require the `CI` status checks to pass, require a pull request before + merging, and disallow force-pushes. This keeps `main` always-green, which the roadmap + depends on. + +## License + +MIT — see [`LICENSE`](LICENSE). diff --git a/docs/build/BUILD_SYSTEM.md b/docs/build/BUILD_SYSTEM.md index 786c759..f8fb36f 100644 --- a/docs/build/BUILD_SYSTEM.md +++ b/docs/build/BUILD_SYSTEM.md @@ -47,7 +47,9 @@ only — no PyPI publishing planned; install-from-source is the documented path) ## Tooling - `clang-format` (file committed; LLVM-based style, 100 cols) — CI checks, `scripts/format.sh` - fixes. + fixes. **Pinned to version 20.1.7**, installed in CI via `pip install clang-format==20.1.7` + so formatting is reproducible across machines and does not drift with a contributor's local + LLVM version. - `clang-tidy` (curated check list: bugprone-*, performance-*, modernize-* minus noisy ones, cppcoreguidelines subset) — CI on changed files; full run nightly. - `.editorconfig`, `.gitattributes` (LF everywhere) — cross-platform hygiene.