Skip to content

Commit ecd27ea

Browse files
committed
ci: add code style and quality checks to CI workflow
Introduce new jobs for code style checking with clang-format and code quality checking with clang-tidy in the CI workflow. The style check identifies formatting issues in C++ source files and comments on them, while the quality check runs clang-tidy to detect errors and warnings, providing feedback on code quality. This enhancement aims to maintain code standards and improve overall code quality in the project.
1 parent 84534ec commit ecd27ea

File tree

1 file changed

+151
-0
lines changed

1 file changed

+151
-0
lines changed

.github/workflows/ci_tests.yml

Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,3 +123,154 @@ jobs:
123123
working-directory: ./cmake-build/tests
124124
run: |
125125
valgrind --leak-check=full --track-origins=yes --error-exitcode=1 ./ovum_tests
126+
127+
style-check:
128+
name: Code style check with clang-format
129+
runs-on: ubuntu-latest
130+
steps:
131+
- uses: actions/checkout@v4
132+
133+
- name: Install clang-format
134+
run: |
135+
sudo apt-get update && sudo apt-get -y install clang-format
136+
137+
- name: Check code style
138+
run: |
139+
# Find all C++ source files
140+
find . -name "*.cpp" -o -name "*.hpp" -o -name "*.c" -o -name "*.h" | \
141+
grep -v "./build/" | grep -v "./cmake-build" | grep -v "./_deps/" | \
142+
xargs clang-format --dry-run --Werror
143+
144+
- name: Comment on style issues
145+
if: failure()
146+
uses: actions/github-script@v7
147+
with:
148+
script: |
149+
const fs = require('fs');
150+
const { execSync } = require('child_process');
151+
152+
try {
153+
// Get list of files that need formatting
154+
const files = execSync('find . -name "*.cpp" -o -name "*.hpp" -o -name "*.c" -o -name "*.h" | grep -v "./build/" | grep -v "./cmake-build" | grep -v "./_deps/"', { encoding: 'utf8' }).trim().split('\n');
155+
156+
let comment = '## 🎨 Code Style Issues Found\n\n';
157+
comment += 'The following files have formatting issues:\n\n';
158+
159+
for (const file of files) {
160+
try {
161+
const result = execSync(`clang-format --dry-run --Werror "${file}" 2>&1`, { encoding: 'utf8' });
162+
} catch (error) {
163+
comment += `- \`${file}\`: Formatting issues detected\n`;
164+
}
165+
}
166+
167+
comment += '\nPlease run `clang-format -i <file>` to fix formatting issues.';
168+
169+
github.rest.issues.createComment({
170+
issue_number: context.issue.number,
171+
owner: context.repo.owner,
172+
repo: context.repo.repo,
173+
body: comment
174+
});
175+
} catch (error) {
176+
console.log('Could not create comment:', error.message);
177+
}
178+
179+
code-quality-check:
180+
name: Code quality check with clang-tidy
181+
runs-on: ubuntu-latest
182+
steps:
183+
- uses: actions/checkout@v4
184+
185+
- name: Install clang-tidy
186+
run: |
187+
sudo apt-get update && sudo apt-get -y install clang-tidy
188+
189+
- name: Create CMake cache
190+
run: |
191+
cmake -S . -B cmake-build-tidy -DCMAKE_BUILD_TYPE=Debug -DCMAKE_EXPORT_COMPILE_COMMANDS=ON
192+
193+
- name: Run clang-tidy
194+
run: |
195+
# Find all C++ source files
196+
find . -name "*.cpp" -o -name "*.hpp" | \
197+
grep -v "./build/" | grep -v "./cmake-build" | grep -v "./_deps/" | \
198+
xargs clang-tidy -p cmake-build-tidy --warnings-as-errors=* --format-style=file || true
199+
200+
- name: Count warnings and errors
201+
id: count_issues
202+
run: |
203+
# Run clang-tidy and capture output
204+
find . -name "*.cpp" -o -name "*.hpp" | \
205+
grep -v "./build/" | grep -v "./cmake-build" | grep -v "./_deps/" | \
206+
xargs clang-tidy -p cmake-build-tidy --format-style=file > tidy_output.txt 2>&1 || true
207+
208+
# Count errors and warnings
209+
errors=$(grep -c "error:" tidy_output.txt || echo "0")
210+
warnings=$(grep -c "warning:" tidy_output.txt || echo "0")
211+
212+
echo "errors=$errors" >> $GITHUB_OUTPUT
213+
echo "warnings=$warnings" >> $GITHUB_OUTPUT
214+
215+
# Fail if more than 3 warnings or any errors
216+
if [ "$errors" -gt 0 ] || [ "$warnings" -gt 3 ]; then
217+
echo "clang-tidy found $errors errors and $warnings warnings"
218+
exit 1
219+
fi
220+
221+
- name: Comment on quality issues
222+
if: failure()
223+
uses: actions/github-script@v7
224+
with:
225+
script: |
226+
const fs = require('fs');
227+
228+
try {
229+
let comment = '## 🔍 Code Quality Issues Found\n\n';
230+
231+
if (fs.existsSync('tidy_output.txt')) {
232+
const output = fs.readFileSync('tidy_output.txt', 'utf8');
233+
const lines = output.split('\n');
234+
235+
let currentFile = '';
236+
let hasIssues = false;
237+
238+
for (const line of lines) {
239+
if (line.includes('error:') || line.includes('warning:')) {
240+
const parts = line.split(':');
241+
if (parts.length >= 4) {
242+
const file = parts[0];
243+
const lineNum = parts[1];
244+
const message = parts.slice(3).join(':').trim();
245+
246+
if (file !== currentFile) {
247+
if (hasIssues) comment += '\n';
248+
comment += `### \`${file}\`\n\n`;
249+
currentFile = file;
250+
hasIssues = true;
251+
}
252+
253+
const issueType = line.includes('error:') ? '❌ Error' : '⚠️ Warning';
254+
comment += `- **Line ${lineNum}**: ${issueType} - ${message}\n`;
255+
}
256+
}
257+
}
258+
259+
if (!hasIssues) {
260+
comment += 'No specific issues found in the output.';
261+
}
262+
} else {
263+
comment += 'Could not read clang-tidy output.';
264+
}
265+
266+
comment += '\n\nPlease review and fix the issues above.';
267+
268+
github.rest.issues.createComment({
269+
issue_number: context.issue.number,
270+
owner: context.repo.owner,
271+
repo: context.repo.repo,
272+
body: comment
273+
});
274+
} catch (error) {
275+
console.log('Could not create comment:', error.message);
276+
}

0 commit comments

Comments
 (0)