1+ name : Code Quality
2+
3+ permissions :
4+ contents : read
5+ issues : write
6+
7+ on :
8+ pull_request :
9+ types : [opened, edited, reopened, synchronize]
10+ paths :
11+ - ' **.py'
12+ - ' **.cpp'
13+ - ' **.h'
14+
15+ jobs :
16+ lint :
17+ name : Code Linting
18+ runs-on : ubuntu-latest
19+ steps :
20+ - name : Checkout Code
21+ uses : actions/checkout@v3
22+
23+ - name : Set up Python
24+ uses : actions/setup-python@v4
25+ with :
26+ python-version : ' 3.11'
27+
28+ - name : Cache pip dependencies
29+ uses : actions/cache@v3
30+ with :
31+ path : ~/.cache/pip
32+ key : ${{ runner.os }}-pip-${{ hashFiles('**/requirements*.txt') }}
33+ restore-keys : |
34+ ${{ runner.os }}-pip-
35+
36+ - name : Install dependencies
37+ run : |
38+ python -m pip install --upgrade pip
39+ pip install -e .
40+ pip install pylint cpplint
41+
42+ - name : Run Python Linter
43+ id : pylint
44+ continue-on-error : true
45+ run : |
46+ echo "Running pylint with threshold 8.5..."
47+ python -m pylint --fail-under=8.5 --disable=fixme,no-member,too-many-arguments,too-many-positional-arguments,invalid-name,useless-parent-delegation --output-format=colorized mssql_python
48+ echo "pylint_status=$?" >> $GITHUB_ENV
49+
50+ - name : Run C++ Linter
51+ id : cpplint
52+ continue-on-error : true
53+ run : |
54+ echo "Running cpplint with maximum 10 errors per file..."
55+
56+ # Find C++ files excluding build directories
57+ FILES=$(find mssql_python -name "*.cpp" -o -name "*.h" | grep -v "/build/")
58+ if [ -z "$FILES" ]; then
59+ echo "No C++ files found to check!"
60+ echo "cpplint_status=0" >> $GITHUB_ENV
61+ exit 0
62+ fi
63+
64+ echo "Found files to check:"
65+ echo "$FILES"
66+
67+ # Process each file individually with better error handling
68+ MAX_ERRORS=10
69+ FAILED_FILES=""
70+
71+ for FILE in $FILES; do
72+ echo "Checking $FILE..."
73+
74+ # Run cpplint on a single file and capture output
75+ OUTPUT=$(python -m cpplint --filter=-readability/todo --linelength=100 "$FILE" 2>&1 || true)
76+
77+ # Display the output for this file
78+ echo "$OUTPUT"
79+
80+ # Extract error count more reliably
81+ ERROR_COUNT=$(echo "$OUTPUT" | grep -o 'Total errors found: [0-9]*' | grep -o '[0-9]*' || echo "0")
82+
83+ # If we couldn't extract a count, default to 0
84+ if [ -z "$ERROR_COUNT" ]; then
85+ ERROR_COUNT=0
86+ fi
87+
88+ echo "File $FILE has $ERROR_COUNT errors"
89+
90+ # Check if over threshold
91+ if [ "$ERROR_COUNT" -gt "$MAX_ERRORS" ]; then
92+ FAILED_FILES="$FAILED_FILES\n- $FILE ($ERROR_COUNT errors)"
93+ fi
94+ done
95+
96+ # Output results
97+ if [ ! -z "$FAILED_FILES" ]; then
98+ echo -e "\n⛔ The following files have more than $MAX_ERRORS errors:$FAILED_FILES"
99+ echo "cpplint_status=1" >> $GITHUB_ENV
100+ else
101+ echo -e "\n✅ All files have $MAX_ERRORS or fewer errors."
102+ echo "cpplint_status=0" >> $GITHUB_ENV
103+ fi
104+
105+ - name : Determine overall status
106+ run : |
107+ if [[ "${{ env.pylint_status }}" != "0" || "${{ env.cpplint_status }}" != "0" ]]; then
108+ echo "Linting checks failed!"
109+ exit 1
110+ else
111+ echo "All linting checks passed!"
112+ fi
113+
114+ - name : Comment on PR
115+ if : github.event_name == 'pull_request'
116+ uses : actions/github-script@v7
117+ with :
118+ github-token : ${{ secrets.GITHUB_TOKEN }}
119+ script : |
120+ let comment = '## Code Quality Check Results\n\n';
121+
122+ if ('${{ env.pylint_status }}' !== '0') {
123+ comment += '⚠️ **Python linting failed** - Please check the [workflow logs](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}) for details.\n\n';
124+ } else {
125+ comment += '✅ **Python linting passed**\n\n';
126+ }
127+
128+ if ('${{ env.cpplint_status }}' !== '0') {
129+ comment += '⚠️ **C++ linting failed** - Some files exceed the maximum error threshold of 10.\n\n';
130+ } else {
131+ comment += '✅ **C++ linting passed**\n\n';
132+ }
133+
134+ comment += 'See [code quality guidelines](https://github.com/microsoft/mssql-python/blob/main/CONTRIBUTING.md) for more information.';
135+
136+ github.rest.issues.createComment({
137+ issue_number: context.issue.number,
138+ owner: context.repo.owner,
139+ repo: context.repo.repo,
140+ body: comment
141+ });
0 commit comments