@@ -12,20 +12,141 @@ jobs:
1212 runs-on : ubuntu-24.04
1313 steps :
1414 - uses : actions/checkout@v4
15-
16- - name : Run clang-format style check for C/C++ source code.
17- uses : jidicula/clang-format-action@v4.15.0
18- if : always()
1915 with :
20- clang-format-version : ' 10'
21- check-path : ' src/EnergyPlus'
16+ fetch-depth : 2
2217
23- - name : Run clang-format style check for C/C++ unit test code.
24- uses : jidicula/clang-format-action@v4.15.0
25- if : always()
18+ - name : Install clang-format-19
19+ shell : bash
20+ run : |
21+ # 14s to install from apt, getting 19.1.1
22+ # Getting it from LLVM takes 1min13s
23+ # sudo apt-get update && apt-get install -y wget gnupg lsb-release software-properties-common
24+ # wget -qO - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo gpg --dearmor -o /usr/share/keyrings/llvm-archive-keyring.gpg
25+ # echo "deb [signed-by=/usr/share/keyrings/llvm-archive-keyring.gpg] http://apt.llvm.org/$(lsb_release -cs)/ llvm-toolchain-$(lsb_release -cs)-19 main" | sudo tee /etc/apt/sources.list.d/llvm.list
26+ sudo apt-get update -qq
27+ sudo apt-get install -y -q clang-format-19
28+ clang-format-19 --version
29+
30+ - name : Run clang-format against C++ files touched by the PR
31+ if : ${{ github.event_name == 'pull_request' }}
32+ shell : bash
33+ run : |
34+ clang-format-19 --version
35+ begin_group() { echo -e "::group::\033[93m$1\033[0m"; }
36+
37+ begin_group "Find changed files"
38+ echo "GITHUB_REF=$GITHUB_REF GITHUB_BASE_REF=$GITHUB_BASE_REF GITHUB_HEAD_REF=$GITHUB_HEAD_REF"
39+ # too slow on E+: git fetch --all --quiet
40+ # first find if any files changed
41+ # HEAD^ works in PRs because actions/checkout checks out a merge commit by default in PR contexts
42+ # and I specified a fetch-depth of 2
43+ changed_files=$(git diff --name-only HEAD^ HEAD src/ tst/ | /bin/grep -E '\.(cpp|cc|c|hpp|hh|h)$')
44+ file_count=$(echo "$changed_files" | wc -l)
45+ if [ $file_count -eq 0 ]; then
46+ echo "No files of type (cpp, c, hpp, h) changed. Skipping clang-formatting"
47+ exit 0
48+ else
49+ begin_group "Found $file_count C/C++ changed files"
50+ echo "$changed_files"
51+ echo "::endgroup::"
52+ fi
53+ echo "::endgroup::"
54+
55+ begin_group "Run clang-format for changes files"
56+ # Using \0 as a terminator in case we'd ever have files with spaces
57+ git diff -z --name-only HEAD^ HEAD src/ tst/ \
58+ | /bin/grep -z -E '\.(cpp|cc|c|hpp|hh|h)$' \
59+ | xargs -0 -P "$(nproc)" -n 1 clang-format-19 -style=file -i -fallback-style=none --verbose
60+
61+ # clang-format will auto correct files so prepare the diff and use this as artifact
62+ git diff > clang_format.patch
63+ echo "::endgroup::"
64+
65+ # Delete if nothhing otherwise exit 1 to indicate a failed job
66+ if [ ! -s clang_format.patch ]; then
67+ rm clang_format.patch
68+ exit 0
69+ else
70+ incorrect_count=$(git diff --name-only | wc -l)
71+ incorrect_percent=$(awk "BEGIN { printf \"%.2f\", ($incorrect_count/$file_count)*100 }")
72+ begin_group "clang-format auto corrected $incorrect_count files:"
73+ git diff --name-only
74+ echo "::endgroup::"
75+ echo "::error title=Clang Format Check Failed::Formatting issues detected in $incorrect_count files"
76+ echo -e "\nPlease correct these files by running clang-format-19 locally, or download the artifact "
77+ echo 'and run `patch -p1 < /path/to/clang_format.patch`'
78+ {
79+ echo "| Item | Value |"
80+ echo "|---------------------------------------|-----------|"
81+ echo "| Number of Files Analyzed | $file_count |"
82+ echo "| Number of Files Incorrectly Formatted | $incorrect_count |"
83+ echo "| % Files Incorrectly Formatted | ${incorrect_percent}% |"
84+ } >> "$GITHUB_STEP_SUMMARY"
85+ exit 1
86+ fi
87+
88+ - name : Run clang-format for entire codebase
89+ if : ${{ github.event_name == 'push' }}
90+ shell : bash
91+ run : |
92+ clang-format-19 --version
93+ begin_group() { echo -e "::group::\033[93m$1\033[0m"; }
94+
95+ begin_group "Run clang-format"
96+ find src tst \( -name "*.hpp" -o -name "*.h" -o -name "*.hh" -o -name "*.cc" -o -name "*.cpp" -o -name "*.c" \) \
97+ -print0 | xargs -0 -P "$(nproc)" -n 1 clang-format-19 -style=file -i -fallback-style=none --verbose
98+
99+ # clang-format will auto correct files so prepare the diff and use this as artifact
100+ git diff > clang_format.patch
101+ echo "::endgroup::"
102+
103+ # Delete if nothing otherwise exit 1 to indicate a failed job
104+ if [ ! -s clang_format.patch ]; then
105+ rm clang_format.patch
106+ exit 0
107+ else
108+ file_count=$(find src tst \( -name "*.hpp" -o -name "*.h" -o -name "*.hh" -o -name "*.cc" -o -name "*.cpp" -o -name "*.c" \) | wc -l)
109+ incorrect_count=$(git diff --name-only | wc -l)
110+ incorrect_percent=$(awk "BEGIN { printf \"%.2f\", ($incorrect_count/$file_count)*100 }")
111+ begin_group "clang-format auto corrected $incorrect_count files:"
112+ git diff --name-only
113+ echo "::endgroup::"
114+ echo "::error title=Clang Format Check Failed::Formatting issues detected in $incorrect_count files"
115+ {
116+ echo "| Item | Value |"
117+ echo "|---------------------------------------|-----------|"
118+ echo "| Number of Files Analyzed | $file_count |"
119+ echo "| Number of Files Incorrectly Formatted | $incorrect_count |"
120+ echo "| % Files Incorrectly Formatted | ${incorrect_percent}% |"
121+ } >> "$GITHUB_STEP_SUMMARY"
122+ exit 1
123+ fi
124+
125+ - name : Upload clang-format patch as artifact
126+ if : ${{ failure() }}
127+ uses : actions/upload-artifact@v4
26128 with :
27- clang-format-version : ' 10'
28- check-path : ' tst/EnergyPlus/unit'
129+ name : EnergyPlus-${{ github.sha }}-clang_format.patch
130+ path : clang_format.patch
131+
132+ - name : Commit Auto-corrections
133+ shell : bash
134+ if : ${{ always() && github.event_name == 'push' }}
135+ run : |
136+ git add -u
137+ if [[ $(git diff --cached --exit-code) ]]; then
138+ echo "Commiting Lint Autocorrects"
139+ git config --global user.email 'github-actions[bot]@users.noreply.github.com'
140+ git config --global user.name 'github-actions[bot]'
141+ git commit -m "[chore] Commit clang-format autocorrects"
142+ echo '' >> .git-blame-ignore-revs
143+ git log -n1 --pretty='format:# %C(auto)%s [%an, %as]%n%H%n' >> .git-blame-ignore-revs
144+ git add .git-blame-ignore-revs
145+ git commit -m "Add clang-format autocorrects to git-blame-ignore-revs"
146+ git push
147+ else
148+ echo "No Autocorrect needed"
149+ fi
29150
30151 - name : Custom Check
31152 if : always()
0 commit comments