diff --git a/.github/workflows/ci_build.yml b/.github/workflows/ci_build.yml index 660de56f..20e8e778 100644 --- a/.github/workflows/ci_build.yml +++ b/.github/workflows/ci_build.yml @@ -4,39 +4,41 @@ on: pull_request: branches: - '*' - paths: - - '.github/workflows/ci_build.yml' - - '.cmake/**' - - 'apps/**' - - 'include/**' - - 'src/**' - - 'integration_tests/**' - - 'tests/**' - - 'benchmarks/CMakeLists.txt' - - 'benchmarks/src/**' - - 'CMakeLists.txt' push: branches: - dev - main - paths: - - '.github/workflows/ci_build.yml' - - '.cmake/**' - - 'apps/**' - - 'include/**' - - 'src/**' - - 'integration_tests/**' - - 'tests/**' - - 'benchmarks/CMakeLists.txt' - - 'benchmarks/src/**' - - 'CMakeLists.txt' schedule: - cron: '0 2 * * *' workflow_dispatch: jobs: - build: + changes: if: github.event_name != 'schedule' + runs-on: ubuntu-24.04 + outputs: + relevant: ${{ steps.filter.outputs.relevant }} + steps: + - uses: actions/checkout@v4 + - uses: dorny/paths-filter@v3 + id: filter + with: + filters: | + relevant: + - '.github/workflows/ci_build.yml' + - '.cmake/**' + - 'apps/**' + - 'include/**' + - 'src/**' + - 'integration_tests/**' + - 'tests/**' + - 'benchmarks/CMakeLists.txt' + - 'benchmarks/src/**' + - 'CMakeLists.txt' + + build: + if: needs.changes.outputs.relevant == 'true' && github.event_name != 'schedule' + needs: changes strategy: matrix: os: [ubuntu-24.04, ubuntu-24.04-arm] @@ -139,7 +141,8 @@ jobs: conda run -n test-env pytest integration_tests -v benchmark: - if: github.event_name != 'schedule' + if: needs.changes.outputs.relevant == 'true' && github.event_name != 'schedule' + needs: changes runs-on: ubuntu-24.04 steps: @@ -170,7 +173,8 @@ jobs: ctest --test-dir build-benchmark -L benchmark --output-on-failure build-static-lto: - if: github.event_name != 'schedule' + if: needs.changes.outputs.relevant == 'true' && github.event_name != 'schedule' + needs: changes runs-on: ubuntu-24.04 steps: @@ -232,7 +236,8 @@ jobs: run: ctest --test-dir build --output-on-failure -j1 mpi-build: - if: github.event_name != 'schedule' + if: needs.changes.outputs.relevant == 'true' && github.event_name != 'schedule' + needs: changes runs-on: ubuntu-24.04 steps: @@ -269,3 +274,21 @@ jobs: - name: Run tests run: ctest --test-dir build --output-on-failure -j1 + + ci-build-gate: + if: always() + needs: [changes, build, benchmark, build-static-lto, mpi-build] + runs-on: ubuntu-24.04 + steps: + - name: Check CI build results + run: | + for result in \ + "${{ needs.build.result }}" \ + "${{ needs.benchmark.result }}" \ + "${{ needs.build-static-lto.result }}" \ + "${{ needs.mpi-build.result }}"; do + if [[ "$result" == "failure" ]]; then + exit 1 + fi + done + echo "OK — all CI build jobs passed or were skipped (no relevant paths changed)" diff --git a/.github/workflows/clang_format.yml b/.github/workflows/clang_format.yml index cc55f415..078a9927 100644 --- a/.github/workflows/clang_format.yml +++ b/.github/workflows/clang_format.yml @@ -5,22 +5,35 @@ on: branches: - main - dev - paths: - - '.clang-format' - - '.github/workflows/clang_format.yml' - - '**/*.c' - - '**/*.cc' - - '**/*.cpp' - - '**/*.cxx' - - '**/*.h' - - '**/*.hh' - - '**/*.hpp' - - '**/*.hxx' - - '!external/**' workflow_dispatch: jobs: + changes: + runs-on: ubuntu-24.04 + outputs: + relevant: ${{ steps.filter.outputs.relevant }} + steps: + - uses: actions/checkout@v4 + - uses: dorny/paths-filter@v3 + id: filter + with: + filters: | + relevant: + - '.clang-format' + - '.github/workflows/clang_format.yml' + - '**/*.c' + - '**/*.cc' + - '**/*.cpp' + - '**/*.cxx' + - '**/*.h' + - '**/*.hh' + - '**/*.hpp' + - '**/*.hxx' + - '!external/**' + clang-format: + needs: changes + if: needs.changes.outputs.relevant == 'true' runs-on: ubuntu-24.04 name: Check Changed C++ Formatting @@ -55,3 +68,15 @@ jobs: "$base_sha" \ "$head_sha" \ -- apps benchmarks include src tests + + clang-format-gate: + if: always() + needs: [changes, clang-format] + runs-on: ubuntu-24.04 + steps: + - name: Check clang-format result + run: | + if [[ "${{ needs.clang-format.result }}" == "failure" ]]; then + exit 1 + fi + echo "OK — clang-format passed or was skipped (no relevant paths changed)" diff --git a/.github/workflows/license_check.yml b/.github/workflows/license_check.yml index 69115df7..0d934e4c 100644 --- a/.github/workflows/license_check.yml +++ b/.github/workflows/license_check.yml @@ -4,30 +4,35 @@ on: pull_request: branches: - '*' - paths: - - '**/*.cpp' - - '**/*.hpp' - - '**/*.c' - - '**/*.h' - - '.github/workflows/license_check.yml' - - 'scripts/addLicense.sh' - - 'config/licenseHeader.txt' push: branches: - main - master - paths: - - '**/*.cpp' - - '**/*.hpp' - - '**/*.c' - - '**/*.h' - - '.github/workflows/license_check.yml' - - 'scripts/addLicense.sh' - - 'config/licenseHeader.txt' workflow_dispatch: jobs: + changes: + runs-on: ubuntu-24.04 + outputs: + relevant: ${{ steps.filter.outputs.relevant }} + steps: + - uses: actions/checkout@v4 + - uses: dorny/paths-filter@v3 + id: filter + with: + filters: | + relevant: + - '**/*.cpp' + - '**/*.hpp' + - '**/*.c' + - '**/*.h' + - '.github/workflows/license_check.yml' + - 'scripts/addLicense.sh' + - 'config/licenseHeader.txt' + license-check: + needs: changes + if: needs.changes.outputs.relevant == 'true' runs-on: ubuntu-latest name: Check License Headers @@ -38,31 +43,31 @@ jobs: - name: Check for license headers in C++ files run: | echo "Checking for exact GPL license headers in C++ files..." - + # Verify license header template exists if [ ! -f "config/licenseHeader.txt" ]; then echo "❌ License header template not found at config/licenseHeader.txt" exit 1 fi - + # Get the expected license header content license_header=$(cat config/licenseHeader.txt) header_line_count=$(wc -l < config/licenseHeader.txt) - + echo "Expected license header has $header_line_count lines" echo "" - + # Find all C++ files in the relevant directories (excluding external dependencies) missing_count=0 total_files=0 - + find src/ tests/ include/ apps/ benchmarks/ -regex ".*\.\(hpp\|cpp\|c\|h\)$" -print0 2>/dev/null | while IFS= read -r -d '' file; do total_files=$((total_files + 1)) echo "Checking: $file" - + # Extract the first N lines from the file (where N = number of lines in license header) file_header=$(head -n "$header_line_count" "$file" 2>/dev/null) - + # Compare the extracted header with the expected license header if [ "$file_header" = "$license_header" ]; then echo "✅ Exact license header match: $file" @@ -71,22 +76,22 @@ jobs: echo "$file" >> /tmp/missing_files.txt fi done - + # Count missing files if [ -f /tmp/missing_files.txt ]; then missing_count=$(wc -l < /tmp/missing_files.txt) else missing_count=0 fi - + # Get total file count total_files=$(find src/ tests/ include/ apps/ benchmarks/ -regex ".*\.\(hpp\|cpp\|c\|h\)$" 2>/dev/null | wc -l) - + echo "" echo "=== License Check Summary ===" echo "Total files checked: $total_files" echo "Files with missing/invalid license headers: $missing_count" - + if [ $missing_count -gt 0 ]; then echo "" echo "Files with incorrect license headers:" @@ -113,3 +118,15 @@ jobs: cat config/licenseHeader.txt echo "=== End of Template ===" shell: bash + + license-check-gate: + if: always() + needs: [changes, license-check] + runs-on: ubuntu-24.04 + steps: + - name: Check license-check result + run: | + if [[ "${{ needs.license-check.result }}" == "failure" ]]; then + exit 1 + fi + echo "OK — license check passed or was skipped (no relevant paths changed)" diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index ea03c8be..d87f2726 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -4,41 +4,41 @@ on: pull_request: branches: - '*' - paths: - - '.github/workflows/ci_build.yml' - - '.cmake/**' - - 'apps/**' - - 'include/**' - - 'src/**' - - 'integration_tests/**' - - 'tests/**' - - 'benchmarks/CMakeLists.txt' - - 'benchmarks/src/**' - - 'CMakeLists.txt' - - '.clang-tidy' - - 'scripts/clang_tidy.sh' - - '.github/workflows/lint.yml' push: branches: - dev - main - paths: - - '.github/workflows/ci_build.yml' - - '.cmake/**' - - 'apps/**' - - 'include/**' - - 'src/**' - - 'integration_tests/**' - - 'CMakeLists.txt' - - '.clang-tidy' - - 'scripts/clang_tidy.sh' - - '.github/workflows/lint.yml' - - 'benchmarks/src/**' - - 'CMakeLists.txt' workflow_dispatch: jobs: + changes: + runs-on: ubuntu-24.04 + outputs: + relevant: ${{ steps.filter.outputs.relevant }} + steps: + - uses: actions/checkout@v4 + - uses: dorny/paths-filter@v3 + id: filter + with: + filters: | + relevant: + - '.github/workflows/ci_build.yml' + - '.cmake/**' + - 'apps/**' + - 'include/**' + - 'src/**' + - 'integration_tests/**' + - 'tests/**' + - 'benchmarks/CMakeLists.txt' + - 'benchmarks/src/**' + - 'CMakeLists.txt' + - '.clang-tidy' + - 'scripts/clang_tidy.sh' + - '.github/workflows/lint.yml' + lint: + needs: changes + if: needs.changes.outputs.relevant == 'true' runs-on: ubuntu-24.04 steps: @@ -78,3 +78,15 @@ jobs: - name: Run clangd-tidy run: | clangd-tidy $(find src/ apps/ include/ -name "*.cpp" -o -name "*.hpp" -o -name "*.tpp" 2>/dev/null) -p=build + + lint-gate: + if: always() + needs: [changes, lint] + runs-on: ubuntu-24.04 + steps: + - name: Check lint result + run: | + if [[ "${{ needs.lint.result }}" == "failure" ]]; then + exit 1 + fi + echo "OK — lint passed or was skipped (no relevant paths changed)" diff --git a/changes/developer/internal.workflow.md b/changes/developer/internal.workflow.md new file mode 100644 index 00000000..9d1c159e --- /dev/null +++ b/changes/developer/internal.workflow.md @@ -0,0 +1 @@ +- add explicit path filtering via filters in CI to make them checkable in rulesets