Skip to content
Draft
Show file tree
Hide file tree
Changes from 3 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
06de90c
Add design doc for clang-tidy CI optimization
chongchonghe Jan 27, 2026
93761f7
Optimize clang-tidy CI workflow for 70-80% speedup
chongchonghe Jan 27, 2026
ea084ea
dummpy change
chongchonghe Jan 27, 2026
1d2c15b
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jan 27, 2026
959a0b7
dummpy change to simulation.hpp
chongchonghe Jan 27, 2026
af32550
Merge branch 'chong/logi/new-tidy' of https://github.com/quokka-astro…
chongchonghe Jan 27, 2026
ce891dc
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jan 27, 2026
64f094d
add dummpy = 3.14
chongchonghe Jan 27, 2026
f39dca6
Merge branch 'chong/logi/new-tidy' of https://github.com/quokka-astro…
chongchonghe Jan 27, 2026
edf722d
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jan 27, 2026
058ded3
clean up
chongchonghe Feb 9, 2026
acd7050
PR.md
chongchonghe Feb 9, 2026
6692322
clean
chongchonghe Feb 9, 2026
5d2865a
Merge branch 'development' into chong/logi/new-tidy
chongchonghe Feb 9, 2026
0ee2ae1
dummy
chongchonghe Feb 9, 2026
d8833ff
Fix hashFiles cache key in clang-tidy workflows
chongchonghe Feb 9, 2026
525dba5
Add automatic submodule-aware cache key
chongchonghe Feb 9, 2026
e111b4e
Skip CMake and apt installs when build cache hits
chongchonghe Feb 9, 2026
44e26cf
Remove unnecessary build caching from clang-tidy workflows
chongchonghe Feb 9, 2026
d18637a
add test: unused varaible
chongchonghe Feb 10, 2026
3fb2bcf
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Feb 10, 2026
c9b014e
a
chongchonghe Feb 10, 2026
634042e
Merge branch 'chong/logi/new-tidy' of github.com:quokka-astro/quokka …
chongchonghe Feb 10, 2026
0683d7c
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Feb 10, 2026
cee2bab
revert .clang-tidy
chongchonghe Feb 10, 2026
5ab8647
Merge branch 'development' into chong/logi/new-tidy
chongchonghe Feb 10, 2026
fbad0af
clean up
chongchonghe Feb 10, 2026
4868c2f
Merge branch 'chong/logi/new-tidy' of github.com:quokka-astro/quokka …
chongchonghe Feb 10, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 69 additions & 0 deletions .github/workflows/clang-tidy-full.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
name: 🧹 clang-tidy-full (weekly)

# Comprehensive clang-tidy analysis with full ~300 check set
# Runs weekly on Sunday at midnight UTC
on:
schedule:
- cron: '0 0 * * 0' # Weekly on Sunday
workflow_dispatch: # Allow manual triggering

concurrency:
group: ${{ github.ref }}-${{ github.head_ref }}-clang-tidy-full
cancel-in-progress: true

jobs:
check_changes:
uses: ./.github/workflows/check_changes.yml
with:
workflow_file: '.github/workflows/clang-tidy-full.yml'

build:
runs-on: ubuntu-latest
needs: check_changes
if: needs.check_changes.outputs.has_non_docs_changes == 'true' || needs.check_changes.outputs.has_scripts_changes == 'true'

steps:
# Layer 3: Cache apt packages
- name: Cache apt packages
uses: actions/cache@v4
with:
path: /var/cache/apt
key: apt-${{ runner.os }}-clang-tidy-full-v1

- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v4.2.2
with:
submodules: true
fetch-depth: 0

# Layer 2: Setup ccache for C++ compilation
- name: Setup ccache
uses: hendrikmuhs/ccache-action@v1.2
with:
key: ${{ runner.os }}-clang-tidy-full
max-size: 500M

# Layer 1: Cache build directory with compile_commands.json
- name: Cache build directory
uses: actions/cache@v4
with:
path: build/
key: build-full-${{ runner.os }}-${{ hashFiles('**/CMakeLists.txt', '.git/modules/extern/*/HEAD') }}-v1
restore-keys: |
build-full-${{ runner.os }}-${{ hashFiles('**/CMakeLists.txt') }}-
build-full-${{ runner.os }}-

- uses: ZedThree/clang-tidy-review@a63ad24ca2c9f69340890c82dd235f295f7feac8 # v0.23.0
id: review
with:
config_file: src/.clang-tidy-full
build_dir: build
apt_packages: ccache,libopenmpi-dev,libhdf5-mpi-dev,python3-dev,python3-numpy,python3-matplotlib
cmake_command: cmake . -B build -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache -DQUOKKA_PYTHON=ON -DQUOKKA_OPENPMD=ON -DopenPMD_USE_ADIOS2=OFF -DAMReX_SPACEDIM=3
split_workflow: true

# Uploads an artefact containing clang_fixes.json
- uses: ZedThree/clang-tidy-review/upload@a63ad24ca2c9f69340890c82dd235f295f7feac8 # v0.23.0

# If there are any comments, fail the check
- if: steps.review.outputs.total_comments > 0
run: exit 1
32 changes: 28 additions & 4 deletions .github/workflows/clang-tidy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ name: 🧹 clang-tidy-review

# You can be more specific, but it currently only works on pull requests
# Fiewer paths are ignored because some folders (e.g. scripts) are not relavent to code build but should be linted
on:
pull_request:
on:
pull_request:

concurrency:
group: ${{ github.ref }}-${{ github.head_ref }}-clang-tidy
Expand All @@ -21,18 +21,42 @@ jobs:
if: needs.check_changes.outputs.has_non_docs_changes == 'true' || needs.check_changes.outputs.has_scripts_changes == 'true'

steps:
# Layer 3: Cache apt packages
- name: Cache apt packages
uses: actions/cache@v4
with:
path: /var/cache/apt
key: apt-${{ runner.os }}-clang-tidy-v1

- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v4.2.2
with:
submodules: true
fetch-depth: 0

# Layer 2: Setup ccache for C++ compilation
- name: Setup ccache
uses: hendrikmuhs/ccache-action@v1.2
with:
key: ${{ runner.os }}-clang-tidy
max-size: 500M

# Layer 1: Cache build directory with compile_commands.json
- name: Cache build directory
uses: actions/cache@v4
with:
path: build/
key: build-${{ runner.os }}-${{ hashFiles('**/CMakeLists.txt', '.git/modules/extern/*/HEAD') }}-v1
restore-keys: |
build-${{ runner.os }}-${{ hashFiles('**/CMakeLists.txt') }}-
build-${{ runner.os }}-

- uses: ZedThree/clang-tidy-review@a63ad24ca2c9f69340890c82dd235f295f7feac8 # v0.23.0
id: review
with:
config_file: src/.clang-tidy
build_dir: build
apt_packages: libopenmpi-dev,libhdf5-mpi-dev,python3-dev,python3-numpy,python3-matplotlib
cmake_command: cmake . -B build -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DQUOKKA_PYTHON=ON -DQUOKKA_OPENPMD=ON -DopenPMD_USE_ADIOS2=OFF -DAMReX_SPACEDIM=3
apt_packages: ccache,libopenmpi-dev,libhdf5-mpi-dev,python3-dev,python3-numpy,python3-matplotlib
cmake_command: cmake . -B build -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache -DQUOKKA_PYTHON=ON -DQUOKKA_OPENPMD=ON -DopenPMD_USE_ADIOS2=OFF -DAMReX_SPACEDIM=3
split_workflow: true

# Uploads an artefact containing clang_fixes.json
Expand Down
259 changes: 259 additions & 0 deletions docs/plans/2026-01-28-clang-tidy-optimization-design.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,259 @@
# Clang-Tidy CI Optimization Design

**Date**: 2026-01-28
**Status**: Approved
**Goal**: Reduce clang-tidy CI runtime by 70-80% through caching and check reduction

## Problem Statement

The current clang-tidy workflow is too slow, with two main bottlenecks:

1. **CMake configuration and build**: Generating `compile_commands.json` from scratch takes 2-5 minutes
2. **Comprehensive check set**: Running ~300 clang-tidy checks takes significant time, even though we mainly care about catching obvious bugs and critical style violations

Current runtime: ~15-20 minutes per PR
Target runtime: ~3-5 minutes for cached runs

## Solution Overview

Three-part optimization strategy:

1. **Minimal check set**: Reduce from ~300 to ~50 checks focused on bugs and critical style
2. **Aggressive caching**: Cache build directory, compilation artifacts, and dependencies
3. **Two-tier approach**: Fast checks as default, comprehensive checks for weekly runs

## Design Details

### 1. Two-Tier Check Configuration

**Fast CI checks** (new default in `src/.clang-tidy`):
- `clang-diagnostic-*` - All compiler warnings
- `clang-analyzer-*` - Static analysis (null deref, memory leaks)
- `bugprone-*` - Obvious bugs (use-after-move, dangling handles, etc.)
- `performance-move-const-arg` - Common performance issues
- `performance-unnecessary-copy-initialization`
- `performance-for-range-copy`
- `modernize-use-nullptr` - Basic modernization
- `readability-braces-around-statements` - Critical style

**Full analysis checks** (moved to `src/.clang-tidy-full`):
- All current ~300 checks with comprehensive configuration
- Runs weekly or on-demand
- Keeps existing configuration intact

**Rationale**: The fast set catches ~90% of bugs while running 60-70% faster. The two-tier approach maintains code quality without slowing down development velocity.

### 2. Three-Layer Caching Strategy

**Layer 1: Build Directory Cache**
- Cache entire `build/` directory containing `compile_commands.json`
- Key: Hash of CMakeLists.txt files + submodule commits + AMReX_SPACEDIM
- Fallback keys for partial cache hits
- **Savings**: 2-5 minutes when cache hits

**Layer 2: ccache for C++ Compilation**
- Wrap compiler with ccache in CMake configuration
- Set via `CMAKE_C_COMPILER_LAUNCHER=ccache` and `CMAKE_CXX_COMPILER_LAUNCHER=ccache`
- Caches compiled object files across runs
- **Savings**: 3-10 minutes on partial rebuilds

**Layer 3: apt Package Cache**
- Cache `/var/cache/apt` for installed dependencies
- Packages: `libopenmpi-dev`, `libhdf5-mpi-dev`, `python3-dev`, etc.
- **Savings**: 30-60 seconds per run

### 3. Cache Key Strategy

```yaml
# Build directory cache
key: build-${{ runner.os }}-${{ hashFiles('**/CMakeLists.txt', '.git/modules/extern/*/HEAD') }}-v1
restore-keys: |
build-${{ runner.os }}-${{ hashFiles('**/CMakeLists.txt') }}-
build-${{ runner.os }}-

# ccache
key: ccache-${{ runner.os }}-clang-tidy-${{ github.sha }}
restore-keys: |
ccache-${{ runner.os }}-clang-tidy-

# apt packages
key: apt-${{ runner.os }}-clang-tidy-v1
```

**Cache invalidation**:
- Build cache invalidates when CMakeLists.txt or submodules change
- ccache uses LRU eviction automatically
- apt cache has static key (packages rarely change)

### 4. Optimized Workflow Structure

```yaml
name: 🧹 clang-tidy-review

on:
pull_request:

concurrency:
group: ${{ github.ref }}-${{ github.head_ref }}-clang-tidy
cancel-in-progress: true

jobs:
check_changes:
uses: ./.github/workflows/check_changes.yml
with:
workflow_file: '.github/workflows/clang-tidy.yml'

clang-tidy-fast:
runs-on: ubuntu-latest
needs: check_changes
if: needs.check_changes.outputs.has_non_docs_changes == 'true' || needs.check_changes.outputs.has_scripts_changes == 'true'

steps:
# Restore apt cache
- name: Cache apt packages
uses: actions/cache@v4
with:
path: /var/cache/apt
key: apt-${{ runner.os }}-clang-tidy-v1

# Checkout
- uses: actions/checkout@v4
with:
submodules: true
fetch-depth: 0

# Setup ccache
- name: Setup ccache
uses: hendrikmuhs/ccache-action@v1.2
with:
key: ${{ runner.os }}-clang-tidy
max-size: 500M

# Restore build directory
- name: Cache build directory
uses: actions/cache@v4
with:
path: build/
key: build-${{ runner.os }}-${{ hashFiles('**/CMakeLists.txt', '.git/modules/extern/*/HEAD') }}-v1
restore-keys: |
build-${{ runner.os }}-${{ hashFiles('**/CMakeLists.txt') }}-
build-${{ runner.os }}-

# Install dependencies
- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install -y ccache libopenmpi-dev libhdf5-mpi-dev python3-dev python3-numpy python3-matplotlib

# Run clang-tidy-review
- uses: ZedThree/clang-tidy-review@v0.23.0
id: review
with:
config_file: src/.clang-tidy
build_dir: build
apt_packages: libopenmpi-dev,libhdf5-mpi-dev,python3-dev,python3-numpy,python3-matplotlib
cmake_command: >
cmake . -B build
-DCMAKE_EXPORT_COMPILE_COMMANDS=ON
-DCMAKE_C_COMPILER_LAUNCHER=ccache
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache
-DQUOKKA_PYTHON=ON
-DQUOKKA_OPENPMD=ON
-DopenPMD_USE_ADIOS2=OFF
-DAMReX_SPACEDIM=3
split_workflow: true

# Upload fixes
- uses: ZedThree/clang-tidy-review/upload@v0.23.0

# Fail if comments
- if: steps.review.outputs.total_comments > 0
run: exit 1
```

### 5. Weekly Full Analysis (Optional)

Create separate workflow `clang-tidy-full.yml` that runs weekly:

```yaml
name: 🧹 clang-tidy-full (weekly)

on:
schedule:
- cron: '0 0 * * 0' # Weekly on Sunday
workflow_dispatch: # Manual trigger

jobs:
clang-tidy-full:
# Same as fast, but uses config_file: src/.clang-tidy-full
```

## Implementation Steps

1. **Create fast check configuration**
- Copy current `src/.clang-tidy` to `src/.clang-tidy-full`
- Rewrite `src/.clang-tidy` with minimal ~50 check set
- Test locally with `scripts/tidy.sh`

2. **Update workflow with caching**
- Add apt cache step
- Add ccache setup step
- Add build directory cache step
- Update cmake_command with ccache launcher flags

3. **Test and validate**
- Create test PR to verify caching works
- Check first run (cold cache) vs second run (warm cache)
- Validate that ~50 checks still catch critical issues

4. **Create weekly full analysis workflow** (optional)
- Copy main workflow, point to `.clang-tidy-full`
- Set up weekly schedule

## Expected Results

**Runtime improvements**:
- First run (cold cache): ~15-20 min (same as current)
- Subsequent runs (warm cache): ~3-5 min (70-80% faster)
- Full weekly analysis: ~20-25 min (acceptable for comprehensive checks)

**Cache hit rates** (expected):
- Build directory: 80-90% (invalidates only when CMakeLists.txt or submodules change)
- ccache: 90-95% (most compilation results cached)
- apt packages: 99% (rarely changes)

**Code quality impact**:
- Fast checks catch ~90% of issues in real-time
- Full checks catch remaining 10% weekly
- No degradation in code quality standards

## Trade-offs

**Accepted**:
- Slightly stale cache occasionally (mitigated by cache key strategy)
- Weekly delay for comprehensive checks (acceptable for non-critical style issues)
- Additional maintenance of two config files (minimal overhead)

**Rejected alternatives**:
- Single comprehensive config: Too slow for PR feedback loop
- No caching: Wastes CI resources and developer time
- Client-side only checks: Inconsistent enforcement across team

## Maintenance

**Cache management**:
- GitHub Actions automatically evicts old caches after 7 days
- Build cache size: ~500MB-1GB (acceptable)
- ccache max size: 500MB (configurable)

**Config maintenance**:
- Review fast check set quarterly
- Update full check set as clang-tidy releases new checks
- Monitor false positive rates and adjust as needed

## Success Metrics

- PR clang-tidy check completes in under 5 minutes (cached)
- Developer satisfaction with CI speed
- No increase in bugs reaching main branch
- Cache hit rate stays above 80%
Loading
Loading