From 5be19cf96e64684f85997bed617281ebba8151c7 Mon Sep 17 00:00:00 2001 From: Jack Luo Date: Wed, 15 Jul 2026 22:06:16 -0700 Subject: [PATCH 1/2] fix(ci): Cap clang-tidy concurrency in lint:check-cpp-full. `lint:check-cpp-full` runs `clang-tidy` over every C++ source file by fanning out one process per file through a Taskfile `deps: for:` loop, which has no built-in concurrency limit. Each `clang-tidy` process holds a full preprocessed translation unit, so spawning ~hundreds at once peaks high in memory. The runners don't have a huge amount of memory, and as the source tree and project complexity grow, that peak grows until it exceeds what the runner has and the OS swaps/thrashes instead of making progress, so the full pass can no longer finish within the runner's timeout. Cap concurrency to the logical-processor count via `task --concurrency` (default `$(getconf _NPROCESSORS_ONLN)`), overridable with `CLP_CPP_LINT_CONCURRENCY` (e.g. "1" for maximum memory safety). Keeping the pass within memory lets it complete, which also lets the `Update lint:check-cpp-static-full cache` step (main only) save a cache so future unchanged-source PRs can skip the step. --- .github/workflows/clp-core-build-macos.yaml | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/.github/workflows/clp-core-build-macos.yaml b/.github/workflows/clp-core-build-macos.yaml index 005f1c23c9..21ebe053f2 100644 --- a/.github/workflows/clp-core-build-macos.yaml +++ b/.github/workflows/clp-core-build-macos.yaml @@ -106,9 +106,18 @@ jobs: # TODO: When enough files are passing clang-tidy, switch to a full pass on schedule only. # - run: >- # task lint:check-cpp-${{(github.event_name == 'schedule') && 'full' || 'diff'}} + # Cap clang-tidy concurrency. `lint:check-cpp-full` fans out one `clang-tidy` process per C++ + # source file through a Taskfile `deps: for:` loop, which has no built-in concurrency limit, + # so ~hundreds of `clang-tidy` processes (each holding a full preprocessed translation unit) + # spawn at once. The runners don't have a huge amount of memory, and as the number of source + # files and the project's complexity grow, peak memory grows until it exceeds what the runner + # has and the OS swaps/thrashes instead of making progress. Cap concurrency to the + # logical-processor count to keep it within memory; override via `CLP_CPP_LINT_CONCURRENCY` + # (e.g. "1" for maximum memory safety). - run: >- - CLP_CPP_MAX_PARALLELISM_PER_BUILD_TASK=$(getconf _NPROCESSORS_ONLN) - task lint:check-cpp-full + task --concurrency + "${CLP_CPP_LINT_CONCURRENCY:-$(getconf _NPROCESSORS_ONLN)}" + lint:check-cpp-full shell: "bash" # Cache the source file checksums and the generated files (logs) for the From 4e0db20fb1c461a7724e8d1fea4467514dd0a346 Mon Sep 17 00:00:00 2001 From: Jack Luo Date: Thu, 16 Jul 2026 14:17:46 -0700 Subject: [PATCH 2/2] style(ci): Simplify lint concurrency cap. Drop the CLP_CPP_LINT_CONCURRENCY override and the explanatory comment; cap clang-tidy concurrency directly to the logical-processor count. --- .github/workflows/clp-core-build-macos.yaml | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/.github/workflows/clp-core-build-macos.yaml b/.github/workflows/clp-core-build-macos.yaml index 21ebe053f2..f098c20b4f 100644 --- a/.github/workflows/clp-core-build-macos.yaml +++ b/.github/workflows/clp-core-build-macos.yaml @@ -106,17 +106,9 @@ jobs: # TODO: When enough files are passing clang-tidy, switch to a full pass on schedule only. # - run: >- # task lint:check-cpp-${{(github.event_name == 'schedule') && 'full' || 'diff'}} - # Cap clang-tidy concurrency. `lint:check-cpp-full` fans out one `clang-tidy` process per C++ - # source file through a Taskfile `deps: for:` loop, which has no built-in concurrency limit, - # so ~hundreds of `clang-tidy` processes (each holding a full preprocessed translation unit) - # spawn at once. The runners don't have a huge amount of memory, and as the number of source - # files and the project's complexity grow, peak memory grows until it exceeds what the runner - # has and the OS swaps/thrashes instead of making progress. Cap concurrency to the - # logical-processor count to keep it within memory; override via `CLP_CPP_LINT_CONCURRENCY` - # (e.g. "1" for maximum memory safety). - run: >- - task --concurrency - "${CLP_CPP_LINT_CONCURRENCY:-$(getconf _NPROCESSORS_ONLN)}" + task + --concurrency "$(getconf _NPROCESSORS_ONLN)" lint:check-cpp-full shell: "bash"