Add PMT function #31
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: clang-tidy | |
| on: [push, pull_request] | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} | |
| cancel-in-progress: true | |
| permissions: | |
| contents: read | |
| jobs: | |
| clang-tidy: | |
| runs-on: ubuntu-latest | |
| env: | |
| BUILD_DIR: build | |
| FIXES_DIR: clang_tidy_fixes | |
| REPORT_HTML: clang-tidy-report.html | |
| # Scan these roots for *.cpp | |
| INCLUDE_DIRS: | | |
| src | |
| # Exclude these folders (repo-root relative). | |
| # Tip: list the folder roots; the step adds '/*' for you. | |
| EXCLUDE_DIRS: | | |
| src/tests | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| with: | |
| submodules: recursive | |
| - name: Install LLVM/Clang + deps | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y clang-tidy clang cmake ninja-build python3-yaml lcov | |
| - name: Reorganize sources for clang-tidy | |
| run: | | |
| mkdir src | |
| # Move ONLY your two real source files into src | |
| mv tinyexpr.cpp src/ | |
| mv tinyexpr.h src/ 2>/dev/null || true # if it exists | |
| # Move the whole tests folder under src/ | |
| mv tests src/ | |
| # Recreate symlinks so CMake can still find files at their old locations | |
| ln -s src/tinyexpr.cpp tinyexpr.cpp | |
| ln -s src/tests tests | |
| # Create compile_commands.json for clang-tidy | |
| - name: Configure CMake compile_commands.json | |
| run: | | |
| cmake -S src/tests -B "$BUILD_DIR" -DTE_BUILD_TEST_RUNNER=OFF -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -G Ninja | |
| # If your project generates headers, you can add a light build: | |
| # cmake --build "$BUILD_DIR" -j | |
| - name: Collect target files (include + prune excludes) | |
| id: files | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| # Build: find <INCLUDE_DIRS> \( -path EX1/* -o -path EX2/* ... \) -prune -o -type f -name '*.cpp' -print | |
| readarray -t roots <<<"$(printf "%s\n" "$INCLUDE_DIRS" | sed '/^\s*$/d')" | |
| readarray -t exdirs <<<"$(printf "%s\n" "$EXCLUDE_DIRS" | sed '/^\s*$/d')" | |
| if [[ ${#roots[@]} -eq 0 ]]; then | |
| echo "No INCLUDE_DIRS configured"; exit 0 | |
| fi | |
| # Assemble prune expression | |
| prune=() | |
| if [[ ${#exdirs[@]} -gt 0 ]]; then | |
| prune+=( "(" ) | |
| for i in "${!exdirs[@]}"; do | |
| d="${exdirs[$i]}"; [[ -z "$d" ]] && continue | |
| [[ $i -gt 0 ]] && prune+=( -o ) | |
| prune+=( -path "$d/*" ) | |
| done | |
| prune+=( ")" -prune -o ) | |
| fi | |
| files=$( | |
| find "${roots[@]}" "${prune[@]}" -type f -name '*.cpp' -print | sort | |
| ) | |
| echo "files<<EOF" >> "$GITHUB_OUTPUT" | |
| echo "$files" >> "$GITHUB_OUTPUT" | |
| echo "EOF" >> "$GITHUB_OUTPUT" | |
| echo "Selected files:" | |
| printf '%s\n' $files || true | |
| - name: Short-circuit if none | |
| if: ${{ steps.files.outputs.files == '' }} | |
| run: | | |
| echo "No matching *.cpp after excludes." | |
| echo "No matching *.cpp after excludes." >> $GITHUB_STEP_SUMMARY | |
| - name: Run clang-tidy | |
| if: ${{ steps.files.outputs.files != '' }} | |
| shell: bash | |
| env: | |
| FIXES_DIR: clang_tidy_fixes | |
| run: | | |
| set -euo pipefail | |
| mkdir -p "$FIXES_DIR" logs | |
| # Read the newline-separated list | |
| while IFS= read -r file; do | |
| [[ -z "$file" ]] && continue | |
| echo "=== clang-tidy -> $file ===" | |
| # POSIX-safe path mangling (avoid ${var//.../...} which is a bashism) | |
| base="$(printf '%s' "$file" | sed 's#/#__#g')" | |
| clang-tidy -p "$BUILD_DIR" -fix=false "$file" \ | |
| --extra-arg=-fno-color-diagnostics \ | |
| --extra-arg=-fdiagnostics-color=never \ | |
| > "logs/${base}.txt" 2>&1 || true | |
| done <<< "${{ steps.files.outputs.files }}" | |
| - name: Generate HTML report | |
| if: ${{ steps.files.outputs.files != '' }} | |
| run: | | |
| python3 .github/scripts/clang_tidy_html_report.py \ | |
| --logs logs/*.txt \ | |
| --out "$REPORT_HTML" \ | |
| --counts ct_counts.json \ | |
| --fail-on warnings | |
| { | |
| echo "### Clang-Tidy Report (read-only)"; | |
| echo; | |
| echo "Generated **$REPORT_HTML** (fail-on=warnings after suppressions)."; | |
| } >> "$GITHUB_STEP_SUMMARY" | |
| - name: Workspace file check | |
| if: always() | |
| run: | | |
| echo "=== WORKSPACE TREE (max 4 levels) ===" | |
| find . -maxdepth 4 -type f | sort || true | |
| echo "" | |
| echo "=== Checking report HTML ===" | |
| echo "REPORT_HTML = $REPORT_HTML" | |
| if [ -f "$REPORT_HTML" ]; then | |
| echo "FOUND: $REPORT_HTML" | |
| else | |
| echo "MISSING: $REPORT_HTML" | |
| fi | |
| echo "" | |
| echo "=== Checking ct_counts.json ===" | |
| if [ -f ct_counts.json ]; then | |
| echo "FOUND: ct_counts.json" | |
| else | |
| echo "MISSING: ct_counts.json" | |
| fi | |
| echo "" | |
| echo "=== Checking logs directory ===" | |
| if [ -d logs ]; then | |
| echo "logs/ exists" | |
| ls -al logs | |
| else | |
| echo "logs directory MISSING" | |
| fi | |
| echo "" | |
| echo "=== Checking log files ===" | |
| ls logs/*.txt 2>/dev/null || echo "No log files found" | |
| - name: Upload artifacts | |
| if: always() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: clang-tidy-report | |
| path: | | |
| ${{ env.REPORT_HTML }} | |
| logs/ | |
| ct_counts.json | |
| if-no-files-found: warn | |
| retention-days: 14 |