From 661314e13487784c94b3c9fd69b469764eb6ef7b Mon Sep 17 00:00:00 2001 From: Mihai Fufezan Date: Mon, 16 Feb 2026 14:30:35 +0200 Subject: [PATCH] CI/c-f check: adapt jidicula script --- .github/workflows/ci.yaml | 34 +++++++-- .github/workflows/clang-format-check.sh | 92 +++++++++++++++++++++++++ 2 files changed, 122 insertions(+), 4 deletions(-) create mode 100755 .github/workflows/clang-format-check.sh diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 5648bcbf..2ec558ed 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -46,12 +46,38 @@ jobs: if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.fork name: "Code Style" runs-on: ubuntu-latest + container: + image: archlinux steps: - name: Checkout repository uses: actions/checkout@v4 + # - name: clang-format check + # uses: jidicula/clang-format-action@v4.16.0 + # with: + # exclude-regex: ^subprojects$ + + - name: Install clang-format + run: | + pacman --noconfirm --noprogressbar -Syyu + pacman --noconfirm --noprogressbar -Sy clang + - name: clang-format check - uses: jidicula/clang-format-action@v4.16.0 - with: - clang-format-version: 20 - exclude-regex: ^subprojects$ + run: .github/workflows/clang-format-check.sh "." "llvm" "^subprojects$" "" + + - name: Save PR head commit SHA + if: failure() && github.event_name == 'pull_request' + shell: bash + run: | + SHA="${{ github.event.pull_request.head.sha }}" + echo "SHA=$SHA" >> $GITHUB_ENV + - name: Save latest commit SHA if not PR + if: failure() && github.event_name != 'pull_request' + shell: bash + run: echo "SHA=${{ github.sha }}" >> $GITHUB_ENV + + - name: Report failure in job summary + if: failure() + run: | + DEEPLINK="${{ github.server_url }}/${{ github.repository }}/commit/${{ env.SHA }}" + echo -e "Format check failed on commit [${GITHUB_SHA:0:8}]($DEEPLINK) with files:\n$(<$GITHUB_WORKSPACE/failing-files.txt)" >> $GITHUB_STEP_SUMMARY diff --git a/.github/workflows/clang-format-check.sh b/.github/workflows/clang-format-check.sh new file mode 100755 index 00000000..41237aa7 --- /dev/null +++ b/.github/workflows/clang-format-check.sh @@ -0,0 +1,92 @@ +#!/usr/bin/env bash +# +# Adapted from https://github.com/jidicula/clang-format-action + +############################################################################### +# check.sh # +############################################################################### +# USAGE: ./entrypoint.sh [] [] +# +# Checks all C/C++/Protobuf/CUDA files (.h, .H, .hpp, .hh, .h++, .hxx and .c, +# .C, .cpp, .cc, .c++, .cxx, .proto, .cu) in the provided GitHub repository path +# (arg1) for conforming to clang-format. If no path is provided or provided path +# is not a directory, all C/C++/Protobuf/CUDA files are checked. If any files +# are incorrectly formatted, the script lists them and exits with 1. +# +# Define your own formatting rules in a .clang-format file at your repository +# root. Otherwise, the provided style guide (arg2) is used as a fallback. + +# format_diff function +# Accepts a filepath argument. The filepath passed to this function must point +# to a C/C++/Protobuf/CUDA file. +format_diff() { + local filepath="$1" + + # Invoke clang-format with dry run and formatting error output + local_format="$(clang-format \ + --dry-run \ + --Werror \ + --style=file \ + --fallback-style="$FALLBACK_STYLE" \ + "${filepath}")" + + local format_status="$?" + if [[ ${format_status} -ne 0 ]]; then + # Append Markdown-bulleted monospaced filepath of failing file to + # summary file. + echo "* \`$filepath\`" >>failing-files.txt + + echo "Failed on file: $filepath" >&2 + echo "$local_format" >&2 + exit_code=1 # flip the global exit code + return "${format_status}" + fi + return 0 +} + +CHECK_PATH="$1" +FALLBACK_STYLE="$2" +EXCLUDE_REGEX="$3" +INCLUDE_REGEX="$4" + +# Set the regex to an empty string regex if nothing was provided +if [[ -z $EXCLUDE_REGEX ]]; then + EXCLUDE_REGEX="^$" +fi + +# Set the filetype regex if nothing was provided. +# Find all C/C++/Protobuf/CUDA files: +# h, H, hpp, hh, h++, hxx +# c, C, cpp, cc, c++, cxx +# ino, pde +# proto +# cu +if [[ -z $INCLUDE_REGEX ]]; then + INCLUDE_REGEX='^.*\.((((c|C)(c|pp|xx|\+\+)?$)|((h|H)h?(pp|xx|\+\+)?$))|(ino|pde|proto|cu))$' +fi + +cd "$GITHUB_WORKSPACE" || exit 2 + +if [[ ! -d $CHECK_PATH ]]; then + echo "Not a directory in the workspace, fallback to all files." >&2 + CHECK_PATH="." +fi + +# initialize exit code +exit_code=0 + +# All files improperly formatted will be printed to the output. +src_files=$(find "$CHECK_PATH" -name .git -prune -o -regextype posix-egrep -regex "$INCLUDE_REGEX" -print) + +# check formatting in each source file +IFS=$'\n' # Loop below should separate on new lines, not spaces. +for file in $src_files; do + # Only check formatting if the path doesn't match the regex + if ! [[ ${file} =~ $EXCLUDE_REGEX ]]; then + format_diff "${file}" + fi +done + +# global exit code is flipped to nonzero if any invocation of `format_diff` has +# a formatting difference. +exit "$exit_code"