Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
40deeba
FEAT: Full Stack Code Coverage
bewithgaurav Sep 17, 2025
f11fa41
Link to HTML and summary only
bewithgaurav Sep 17, 2025
a7aeb06
Potential fix for code scanning alert no. 310: Workflow does not cont…
bewithgaurav Sep 17, 2025
acaa2f3
port to linux since macOS doesnt support docker in GH runner
bewithgaurav Sep 17, 2025
9d02e9b
correct the sh filename
bewithgaurav Sep 17, 2025
c04b019
Merge branch 'main' of https://github.com/microsoft/mssql-python into…
bewithgaurav Sep 17, 2025
b369afe
codecov sh file to linux
bewithgaurav Sep 17, 2025
89266e9
fixing bugs
bewithgaurav Sep 17, 2025
b55d146
do things only once
bewithgaurav Sep 17, 2025
c4c47a4
add this in ADO
bewithgaurav Sep 17, 2025
6c977ad
fix Github comment
bewithgaurav Sep 17, 2025
541945b
fix Github comment, core logic is now in PR validation
bewithgaurav Sep 17, 2025
fa3d6cc
fix spamming in GH workflow
bewithgaurav Sep 17, 2025
3d67133
fix spamming in GH workflow
bewithgaurav Sep 17, 2025
aed05f0
line coverage only for cpp
bewithgaurav Sep 17, 2025
a65c52d
line coverage only for cpp
bewithgaurav Sep 17, 2025
2173309
refactor
bewithgaurav Sep 17, 2025
054c098
added a nice GH comment
bewithgaurav Sep 17, 2025
014099d
added a nice GH comment
bewithgaurav Sep 17, 2025
39cbd93
comment is prettier now
bewithgaurav Sep 17, 2025
67de428
added graceful handling of failures
bewithgaurav Sep 17, 2025
8e5c604
comment final
bewithgaurav Sep 18, 2025
79373c9
Merge branch 'main' of https://github.com/microsoft/mssql-python into…
bewithgaurav Sep 18, 2025
d844473
trying patch coverage
bewithgaurav Sep 18, 2025
b7b5c9c
Merge branch 'main' of https://github.com/microsoft/mssql-python into…
bewithgaurav Sep 19, 2025
6ad5087
fix xml search and dont trigger PR validation anymore
bewithgaurav Sep 19, 2025
45747b0
undo trigger PR validation and use a specified build for code coevrag…
bewithgaurav Sep 19, 2025
6e03369
specific build id
bewithgaurav Sep 19, 2025
66139e0
specific build id
bewithgaurav Sep 19, 2025
b3329a0
specific build id
bewithgaurav Sep 19, 2025
2b4927d
unzip error
bewithgaurav Sep 19, 2025
2103aaa
git main
bewithgaurav Sep 19, 2025
7f26846
pull all branches
bewithgaurav Sep 19, 2025
67fb0d2
polling for artifact instead of build status
bewithgaurav Sep 19, 2025
f05ef05
test method increased, patch coverage % debugging
bewithgaurav Sep 19, 2025
049b611
fix % extraction, make format better
bewithgaurav Sep 19, 2025
da0c0c5
add something in cpp
bewithgaurav Sep 19, 2025
c250305
change name from test to dummy in cursor
bewithgaurav Sep 19, 2025
8ad00e9
remove redundant code and add a re-label check on pr-format workflow
bewithgaurav Sep 19, 2025
328b35c
cleanup
bewithgaurav Sep 24, 2025
2176fba
rename PR validation task
bewithgaurav Sep 24, 2025
da9651c
Merge branch 'main' of https://github.com/microsoft/mssql-python into…
bewithgaurav Sep 24, 2025
dfb2537
Reformatted Comment
bewithgaurav Sep 24, 2025
867ae79
Merge branch 'main' into bewithgaurav/universal_codecov
bewithgaurav Sep 26, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
100 changes: 100 additions & 0 deletions .github/workflows/pr-code-coverage.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
name: PR Validation (macOS with Unified Coverage)

on:
pull_request:
branches:
- main

jobs:
pytest-macos:
name: macOS Unified Coverage
runs-on: macos-latest

env:
DB_PASSWORD: ${{ secrets.DB_PASSWORD }}
DB_CONNECTION_STRING: ${{ secrets.DB_CONNECTION_STRING }}

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Set up Python 3.13
uses: actions/setup-python@v5
with:
python-version: '3.13'

- name: Install CMake
run: |
brew update
brew uninstall cmake --ignore-dependencies || echo "CMake not installed"
brew install cmake

- name: Install and start Colima-based Docker
run: |
brew install docker colima
colima start --cpu 4 --memory 8 --disk 50
docker context use colima >/dev/null || true
docker version
docker ps

- name: Start SQL Server container
run: |
docker pull mcr.microsoft.com/mssql/server:2022-latest
docker run \
--name sqlserver \
-e ACCEPT_EULA=Y \
-e MSSQL_SA_PASSWORD="${DB_PASSWORD}" \
-p 1433:1433 \
-d mcr.microsoft.com/mssql/server:2022-latest

# Wait until SQL Server is ready
for i in {1..30}; do
docker exec sqlserver \
/opt/mssql-tools18/bin/sqlcmd \
-S localhost \
-U SA \
-P "$DB_PASSWORD" \
-C -Q "SELECT 1" && break
sleep 2
done

- name: Install Python dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt

- name: Build pybind bindings
run: |
cd mssql_python/pybind
./build.sh

- name: Run pytest (with raw coverage)
run: |
echo "Running pytest..."
python -m pytest -v --junitxml=test-results.xml --cov=. --cov-report=xml --capture=tee-sys --cache-clear

- name: Generate unified coverage (Python + C++)
run: |
chmod +x ./generate_codecov.sh
./generate_codecov.sh
# Create summary text file from LCOV report
genhtml total.info \
--output-directory unified-coverage \
--quiet \
--title "Unified Coverage Report" \
--summary-only > unified-coverage/summary.txt

- name: Upload full HTML coverage artifact
uses: actions/upload-artifact@v4
with:
name: UnifiedCoverageHTML
path: unified-coverage

- name: Comment unified coverage summary on PR
uses: marocchino/sticky-pull-request-comment@v2
with:
header: Unified Coverage Report
message: |
$(cat unified-coverage/summary.txt)

👉 [Download full HTML report](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}#artifacts)
93 changes: 93 additions & 0 deletions generate_codecov.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
#!/bin/bash
set -euo pipefail

echo "==================================="
echo "[STEP 1] Installing dependencies"
echo "==================================="

# Ensure Homebrew exists
if ! command -v brew &>/dev/null; then
echo "[ERROR] Homebrew is required. Install from https://brew.sh/"
exit 1
fi

# Install LLVM (for llvm-profdata, llvm-cov)
if ! command -v llvm-profdata &>/dev/null; then
echo "[ACTION] Installing LLVM via Homebrew"
brew install llvm
fi
export PATH="/opt/homebrew/opt/llvm/bin:$PATH"

# Install lcov (provides lcov + genhtml)
if ! command -v genhtml &>/dev/null; then
echo "[ACTION] Installing lcov via Homebrew"
brew install lcov
fi

# Install Python plugin for LCOV export
if ! python -m pip show coverage-lcov &>/dev/null; then
echo "[ACTION] Installing coverage-lcov via pip"
python -m pip install coverage-lcov
fi

echo "==================================="
echo "[STEP 2] Running pytest with Python coverage"
echo "==================================="

# Cleanup old coverage
rm -f .coverage coverage.xml python-coverage.info cpp-coverage.info total.info
rm -rf htmlcov unified-coverage

# Run pytest with Python coverage (XML + HTML output)
python -m pytest -v \
--junitxml=test-results.xml \
--cov=mssql_python \
--cov-report=xml \
--cov-report=html \
--capture=tee-sys \
--cache-clear

# Convert Python coverage to LCOV format (restrict to your repo only)
echo "[ACTION] Converting Python coverage to LCOV"
coverage lcov -o python-coverage.info --include="mssql_python/*"

echo "==================================="
echo "[STEP 3] Processing C++ coverage (Clang/LLVM)"
echo "==================================="

# Merge raw profile data from pybind runs
if [ ! -f default.profraw ]; then
echo "[ERROR] default.profraw not found. Did you build with -fprofile-instr-generate?"
exit 1
fi

llvm-profdata merge -sparse default.profraw -o default.profdata

# Find the pybind .so (assuming universal2 build)
PYBIND_SO=$(find mssql_python -name "*.so" | grep "universal2" | head -n 1)
if [ -z "$PYBIND_SO" ]; then
echo "[ERROR] Could not find pybind .so (universal2 build)."
exit 1
fi

echo "[INFO] Using pybind module: $PYBIND_SO"

# Export C++ coverage, excluding Python headers, pybind11, and Homebrew includes
llvm-cov export "$PYBIND_SO" \
-instr-profile=default.profdata \
-arch arm64 \
-ignore-filename-regex='(python3\.13|cpython|pybind11|homebrew)' \
-format=lcov > cpp-coverage.info

echo "==================================="
echo "[STEP 4] Merging Python + C++ coverage"
echo "==================================="

# Merge LCOV reports (ignore minor inconsistencies in Python LCOV export)
lcov -a python-coverage.info -a cpp-coverage.info -o total.info \
--ignore-errors inconsistent,corrupt

# Generate unified HTML report
genhtml total.info --output-directory unified-coverage

echo "[SUCCESS] Unified coverage report generated at unified-coverage/index.html"
7 changes: 5 additions & 2 deletions mssql_python/pybind/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,11 @@ echo "[DIAGNOSTIC] Changed to build directory: ${BUILD_DIR}"
# Configure CMake (architecture settings handled in CMakeLists.txt)
echo "[DIAGNOSTIC] Running CMake configure"
if [[ "$OS" == "macOS" ]]; then
echo "[DIAGNOSTIC] Configuring for macOS (universal2 is set automatically)"
cmake -DMACOS_STRING_FIX=ON "${SOURCE_DIR}"
echo "[ACTION] Configuring for macOS with Clang coverage instrumentation"
cmake -DMACOS_STRING_FIX=ON \
-DCMAKE_CXX_FLAGS="-fprofile-instr-generate -fcoverage-mapping" \
-DCMAKE_C_FLAGS="-fprofile-instr-generate -fcoverage-mapping" \
"${SOURCE_DIR}"
else
echo "[DIAGNOSTIC] Configuring for Linux with architecture: $DETECTED_ARCH"
cmake -DARCHITECTURE="$DETECTED_ARCH" "${SOURCE_DIR}"
Expand Down
Loading