Skip to content

STYLE: Code linting

STYLE: Code linting #2

name: Code Quality
permissions:
contents: read
issues: write
on:
pull_request:
types: [opened, edited, reopened, synchronize]
paths:
- '**.py'
- '**.cpp'
- '**.h'
jobs:
lint:
name: Code Linting
runs-on: ubuntu-latest
steps:
- name: Checkout Code
uses: actions/checkout@v3
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.9'
- name: Cache pip dependencies
uses: actions/cache@v3
with:
path: ~/.cache/pip
key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements*.txt') }}
restore-keys: |
${{ runner.os }}-pip-
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -e .
pip install pylint cpplint
- name: Run Python Linter
id: pylint
continue-on-error: true
run: |
echo "Running pylint with threshold 8.5..."
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
echo "pylint_status=$?" >> $GITHUB_ENV
- name: Run C++ Linter
id: cpplint
continue-on-error: true
run: |
echo "Running cpplint with maximum 10 errors per file..."
# Find C++ files excluding build directories
FILES=$(find mssql_python -name "*.cpp" -o -name "*.h" | grep -v "/build/")
MAX_ERRORS=10
FAILED_FILES=""
# Run cpplint on all files and capture output
CPPLINT_OUTPUT=$(python -m cpplint --filter=-readability/todo --linelength=100 $FILES 2>&1)
echo "$CPPLINT_OUTPUT"
# Extract error counts per file
while IFS= read -r line; do
if [[ $line =~ Total\ errors\ found:\ ([0-9]+) ]]; then
ERROR_COUNT=${BASH_REMATCH[1]}
# Get the filename from the previous line
PREV_LINE=$(echo "$CPPLINT_OUTPUT" | grep -B 1 "$line" | head -n 1)
if [[ $PREV_LINE =~ Done\ processing\ (.+) ]]; then
FILE_PATH=${BASH_REMATCH[1]}
FILE_NAME=$(basename "$FILE_PATH")
echo "File $FILE_NAME has $ERROR_COUNT errors"
# Check if file exceeds threshold
if [ $ERROR_COUNT -gt $MAX_ERRORS ]; then
FAILED_FILES="$FAILED_FILES\n- $FILE_NAME ($ERROR_COUNT errors)"
fi
fi
fi
done <<< "$CPPLINT_OUTPUT"
if [ ! -z "$FAILED_FILES" ]; then
echo -e "\n⛔ The following files have more than $MAX_ERRORS errors:$FAILED_FILES"
echo "cpplint_status=1" >> $GITHUB_ENV
else
echo -e "\n✅ All files have $MAX_ERRORS or fewer errors."
echo "cpplint_status=0" >> $GITHUB_ENV
fi
- name: Determine overall status
run: |
if [[ "${{ env.pylint_status }}" != "0" || "${{ env.cpplint_status }}" != "0" ]]; then
echo "Linting checks failed!"
exit 1
else
echo "All linting checks passed!"
fi
- name: Comment on PR
if: github.event_name == 'pull_request' && (env.pylint_status != '0' || env.cpplint_status != '0')
uses: actions/github-script@v7
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
let comment = '## Code Quality Check Results\n\n';
if ('${{ env.pylint_status }}' !== '0') {
comment += '⚠️ **Python linting failed** - Please check the [workflow logs](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}) for details.\n\n';
} else {
comment += '✅ **Python linting passed**\n\n';
}
if ('${{ env.cpplint_status }}' !== '0') {
comment += '⚠️ **C++ linting failed** - Some files exceed the maximum error threshold of 10.\n\n';
} else {
comment += '✅ **C++ linting passed**\n\n';
}
comment += 'See [code quality guidelines](https://github.com/microsoft/mssql-python/blob/main/CONTRIBUTING.md) for more information.';
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: comment
});