-
Notifications
You must be signed in to change notification settings - Fork 145
Move code coverage from GitHub Actions to Azure Pipeline, Fixes AB#3421522 #2433
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
+228
−75
Merged
Changes from 3 commits
Commits
Show all changes
42 commits
Select commit
Hold shift + click to select a range
65b18be
Initial plan
Copilot 492cd3b
Add code-coverage GitHub Actions workflow
Copilot f7fb76f
Fix YAML syntax in code-coverage workflow
Copilot 214235d
Apply suggestion from @Copilot
cacosta33 c52a606
Apply suggestion from @Copilot
cacosta33 dd6cb21
Apply suggestions from code review
cacosta33 773e749
Fix 0.0% coverage issue with better error handling and debugging
Copilot 98c096d
Fix gradle.properties parsing error causing build failure
Copilot 7af1ddd
Pivot to Azure Pipeline for code coverage instead of GitHub Actions
Copilot 20be74e
fix
fadidurah 9cc64db
common
fadidurah 08cf666
Merge branch 'dev' of https://github.com/AzureAD/microsoft-authentica…
fadidurah 2c82323
revert
fadidurah bae3a06
try code cov pipeline
fadidurah dc0a7e9
jacoco
fadidurah faee566
jacoco
fadidurah 05e2731
jacoco
fadidurah d72bc1a
actually use jacoco
fadidurah a4f783b
actually use jacoco
fadidurah 45e908f
actually use jacoco
fadidurah a33e982
limit to one test task
fadidurah 769bc50
limit to one test task
fadidurah 0a2a704
limit to one test task
fadidurah 133b5f8
limit to one test task
fadidurah 826bf61
limit to one test task
fadidurah e7c3acf
limit to one test task
fadidurah 39adcee
limit to one test task
fadidurah fef82c2
limit to one test task
fadidurah 48b349b
Fix Yaml
fadidurah 89511d8
Fix Yaml
fadidurah 22f2bea
comment out jobs for now
fadidurah 19daab4
comment out jobs for now
fadidurah 1aa01fd
comment out jobs for now
fadidurah c878ded
comment out jobs for now
fadidurah 664ee44
fix gradle
fadidurah 38eeca6
fix gradle
fadidurah 7e3ca58
try without filtering
fadidurah 42d9441
add java location
fadidurah b4be4e2
test
fadidurah 5c986f3
test
fadidurah fc1f660
test
fadidurah 6ea74e7
Merge branch 'dev' into copilot/add-code-coverage-check
fadidurah File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,324 @@ | ||
| # Code Coverage Check Workflow | ||
| # | ||
| # This workflow runs code coverage checks for PRs targeting the 'dev' branch. | ||
| # It compares code coverage between the PR branch and the latest dev branch. | ||
| # | ||
| # Features: | ||
| # - Runs only for PRs targeting 'dev' branch | ||
| # - Can be skipped with 'code-coverage-skip' label | ||
| # - Compares total code coverage percentage (PR vs dev) | ||
| # - Fails if coverage decreases | ||
| # - Shows clear output with before/after coverage and delta | ||
|
|
||
| name: code-coverage | ||
|
|
||
| on: | ||
| pull_request: | ||
| branches: | ||
| - dev | ||
| types: [opened, reopened, synchronize, labeled, unlabeled] | ||
|
|
||
| permissions: | ||
| contents: read | ||
| pull-requests: write | ||
| checks: write | ||
|
|
||
| # Prevent multiple simultaneous runs for the same PR | ||
| concurrency: | ||
| group: code-coverage-${{ github.event.pull_request.number }} | ||
| cancel-in-progress: true | ||
|
|
||
| jobs: | ||
| code-coverage: | ||
| name: Code Coverage Check | ||
| runs-on: ubuntu-latest | ||
|
|
||
| # Skip if PR has 'code-coverage-skip' label | ||
| if: "!contains(github.event.pull_request.labels.*.name, 'code-coverage-skip')" | ||
|
|
||
| steps: | ||
| - name: Check for skip label | ||
| id: check_skip | ||
| run: | | ||
| echo "Running code coverage check (no skip label found)" | ||
|
|
||
| - name: Checkout PR branch | ||
| uses: actions/checkout@v4 | ||
| with: | ||
| fetch-depth: 0 | ||
|
|
||
| - name: Set up JDK 17 | ||
| uses: actions/setup-java@v4 | ||
| with: | ||
| java-version: '17' | ||
| distribution: 'temurin' | ||
| cache: 'gradle' | ||
|
|
||
| - name: Grant execute permission for gradlew | ||
| run: chmod +x gradlew | ||
|
|
||
| - name: Enable public Maven repositories | ||
| run: | | ||
| echo "Enabling mavenCentral and public repositories for GitHub Actions..." | ||
| # Uncomment mavenCentral in build.gradle | ||
| sed -i 's|// mavenCentral()|mavenCentral()|g' build.gradle | ||
|
|
||
| # Create gradle.properties with dummy credentials to avoid errors | ||
| if [ ! -f gradle.properties ]; then | ||
| echo "Creating gradle.properties..." | ||
| touch gradle.properties | ||
| fi | ||
|
|
||
| # Add dummy credentials for VSTS Maven (will fallback to mavenCentral) | ||
| echo "vstsUsername=dummy" >> gradle.properties | ||
| echo "vstsMavenAccessToken=dummy" >> gradle.properties | ||
|
|
||
| - name: Run tests with code coverage on PR branch | ||
| id: pr_coverage | ||
| run: | | ||
| echo "Running code coverage on PR branch..." | ||
|
|
||
| # Run the coverage task as defined in the Azure pipeline | ||
| ./gradlew :msal:localDebugMsalUnitTestCoverageReport -PcodeCoverageEnabled=true --no-daemon || true | ||
|
cacosta33 marked this conversation as resolved.
Outdated
|
||
|
|
||
| # Check if coverage report was generated | ||
| COVERAGE_FILE="msal/build/reports/jacoco/localDebugMsalUnitTestCoverageReport/localDebugMsalUnitTestCoverageReport.xml" | ||
| if [ ! -f "$COVERAGE_FILE" ]; then | ||
| echo "⚠️ Coverage report not found at $COVERAGE_FILE" | ||
| echo "Attempting to find coverage files..." | ||
|
|
||
| # Try to find the coverage XML file | ||
| find msal/build -name "*.xml" -path "*/jacoco/*" || true | ||
|
|
||
| echo "pr_coverage=0.0" >> $GITHUB_OUTPUT | ||
| echo "pr_coverage_found=false" >> $GITHUB_OUTPUT | ||
| else | ||
| # Extract coverage percentage from XML report | ||
| # Jacoco XML format: <counter type="INSTRUCTION" missed="X" covered="Y"/> | ||
| # Coverage % = (covered / (covered + missed)) * 100 | ||
|
|
||
| COVERED=$(grep -o 'type="INSTRUCTION" missed="[0-9]*" covered="[0-9]*"' "$COVERAGE_FILE" | head -1 | grep -o 'covered="[0-9]*"' | grep -o '[0-9]*') | ||
| MISSED=$(grep -o 'type="INSTRUCTION" missed="[0-9]*" covered="[0-9]*"' "$COVERAGE_FILE" | head -1 | grep -o 'missed="[0-9]*"' | grep -o '[0-9]*') | ||
|
|
||
|
cacosta33 marked this conversation as resolved.
Outdated
|
||
| if [ -n "$COVERED" ] && [ -n "$MISSED" ]; then | ||
| TOTAL=$((COVERED + MISSED)) | ||
| if [ $TOTAL -gt 0 ]; then | ||
| PR_COVERAGE=$(awk "BEGIN {printf \"%.2f\", ($COVERED / $TOTAL) * 100}") | ||
| echo "✅ PR Coverage: ${PR_COVERAGE}% (Covered: $COVERED, Missed: $MISSED, Total: $TOTAL)" | ||
| echo "pr_coverage=$PR_COVERAGE" >> $GITHUB_OUTPUT | ||
| echo "pr_coverage_found=true" >> $GITHUB_OUTPUT | ||
| else | ||
| echo "pr_coverage=0.0" >> $GITHUB_OUTPUT | ||
| echo "pr_coverage_found=false" >> $GITHUB_OUTPUT | ||
| fi | ||
| else | ||
| echo "⚠️ Could not extract coverage data from XML" | ||
| echo "pr_coverage=0.0" >> $GITHUB_OUTPUT | ||
| echo "pr_coverage_found=false" >> $GITHUB_OUTPUT | ||
| fi | ||
| fi | ||
| continue-on-error: true | ||
|
|
||
| - name: Checkout dev branch | ||
| run: | | ||
| echo "Switching to dev branch for baseline coverage..." | ||
| git fetch origin dev:dev | ||
| git checkout dev | ||
|
|
||
| - name: Run tests with code coverage on dev branch | ||
| id: dev_coverage | ||
| run: | | ||
| echo "Running code coverage on dev branch..." | ||
|
|
||
| # Clean previous build artifacts | ||
| ./gradlew clean --no-daemon | ||
|
|
||
| # Run the coverage task as defined in the Azure pipeline | ||
| ./gradlew :msal:localDebugMsalUnitTestCoverageReport -PcodeCoverageEnabled=true --no-daemon || true | ||
|
cacosta33 marked this conversation as resolved.
Outdated
|
||
|
|
||
| # Check if coverage report was generated | ||
| COVERAGE_FILE="msal/build/reports/jacoco/localDebugMsalUnitTestCoverageReport/localDebugMsalUnitTestCoverageReport.xml" | ||
| if [ ! -f "$COVERAGE_FILE" ]; then | ||
| echo "⚠️ Coverage report not found at $COVERAGE_FILE" | ||
| echo "dev_coverage=0.0" >> $GITHUB_OUTPUT | ||
| echo "dev_coverage_found=false" >> $GITHUB_OUTPUT | ||
| else | ||
| # Extract coverage percentage from XML report | ||
| COVERED=$(grep -o 'type="INSTRUCTION" missed="[0-9]*" covered="[0-9]*"' "$COVERAGE_FILE" | head -1 | grep -o 'covered="[0-9]*"' | grep -o '[0-9]*') | ||
| MISSED=$(grep -o 'type="INSTRUCTION" missed="[0-9]*" covered="[0-9]*"' "$COVERAGE_FILE" | head -1 | grep -o 'missed="[0-9]*"' | grep -o '[0-9]*') | ||
|
cacosta33 marked this conversation as resolved.
Outdated
|
||
|
|
||
| if [ -n "$COVERED" ] && [ -n "$MISSED" ]; then | ||
| TOTAL=$((COVERED + MISSED)) | ||
| if [ $TOTAL -gt 0 ]; then | ||
| DEV_COVERAGE=$(awk "BEGIN {printf \"%.2f\", ($COVERED / $TOTAL) * 100}") | ||
| echo "✅ Dev Coverage: ${DEV_COVERAGE}% (Covered: $COVERED, Missed: $MISSED, Total: $TOTAL)" | ||
| echo "dev_coverage=$DEV_COVERAGE" >> $GITHUB_OUTPUT | ||
| echo "dev_coverage_found=true" >> $GITHUB_OUTPUT | ||
| else | ||
| echo "dev_coverage=0.0" >> $GITHUB_OUTPUT | ||
| echo "dev_coverage_found=false" >> $GITHUB_OUTPUT | ||
| fi | ||
| else | ||
| echo "⚠️ Could not extract coverage data from XML" | ||
| echo "dev_coverage=0.0" >> $GITHUB_OUTPUT | ||
| echo "dev_coverage_found=false" >> $GITHUB_OUTPUT | ||
| fi | ||
| fi | ||
| continue-on-error: true | ||
|
|
||
| - name: Compare coverage and determine result | ||
| id: compare | ||
| run: | | ||
| PR_COVERAGE="${{ steps.pr_coverage.outputs.pr_coverage }}" | ||
| DEV_COVERAGE="${{ steps.dev_coverage.outputs.dev_coverage }}" | ||
| PR_FOUND="${{ steps.pr_coverage.outputs.pr_coverage_found }}" | ||
| DEV_FOUND="${{ steps.dev_coverage.outputs.dev_coverage_found }}" | ||
|
|
||
| echo "PR Coverage Found: $PR_FOUND" | ||
| echo "Dev Coverage Found: $DEV_FOUND" | ||
|
|
||
| # Default to 0.0 if not set | ||
| PR_COVERAGE="${PR_COVERAGE:-0.0}" | ||
| DEV_COVERAGE="${DEV_COVERAGE:-0.0}" | ||
|
|
||
| echo "📊 Coverage Comparison:" | ||
| echo " Dev branch: ${DEV_COVERAGE}%" | ||
| echo " PR branch: ${PR_COVERAGE}%" | ||
|
|
||
| # Calculate delta using awk for floating point arithmetic | ||
| DELTA=$(awk "BEGIN {printf \"%.2f\", $PR_COVERAGE - $DEV_COVERAGE}") | ||
| echo " Delta: ${DELTA}%" | ||
|
|
||
| # Determine if coverage increased, decreased, or stayed the same | ||
| if (( $(echo "$DELTA < 0" | bc -l) )); then | ||
| RESULT="decreased" | ||
| STATUS="❌ FAILED" | ||
| EXIT_CODE=1 | ||
| elif (( $(echo "$DELTA > 0" | bc -l) )); then | ||
|
cacosta33 marked this conversation as resolved.
Outdated
|
||
| RESULT="increased" | ||
| STATUS="✅ PASSED" | ||
| EXIT_CODE=0 | ||
| else | ||
| RESULT="unchanged" | ||
| STATUS="✅ PASSED" | ||
| EXIT_CODE=0 | ||
| fi | ||
|
|
||
| echo "" | ||
| echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" | ||
| echo "$STATUS - Code Coverage Check" | ||
| echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" | ||
| echo "" | ||
| echo "📈 Coverage Summary:" | ||
| echo " Before (dev): ${DEV_COVERAGE}%" | ||
| echo " After (PR): ${PR_COVERAGE}%" | ||
| echo " Delta: ${DELTA}%" | ||
| echo " Result: Coverage $RESULT" | ||
| echo "" | ||
|
|
||
| if [ "$RESULT" = "decreased" ]; then | ||
| echo "⚠️ Code coverage has decreased by ${DELTA#-}%" | ||
| echo " Please add tests to maintain or improve coverage." | ||
| elif [ "$RESULT" = "increased" ]; then | ||
| echo "🎉 Great job! Code coverage improved by ${DELTA}%" | ||
| else | ||
| echo "✓ Code coverage maintained at ${PR_COVERAGE}%" | ||
| fi | ||
|
|
||
| echo "" | ||
| echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" | ||
|
|
||
| # Set outputs for comment | ||
| echo "pr_coverage=$PR_COVERAGE" >> $GITHUB_OUTPUT | ||
| echo "dev_coverage=$DEV_COVERAGE" >> $GITHUB_OUTPUT | ||
| echo "delta=$DELTA" >> $GITHUB_OUTPUT | ||
| echo "result=$RESULT" >> $GITHUB_OUTPUT | ||
| echo "status=$STATUS" >> $GITHUB_OUTPUT | ||
| echo "exit_code=$EXIT_CODE" >> $GITHUB_OUTPUT | ||
|
|
||
| # Exit with appropriate code | ||
| exit $EXIT_CODE | ||
|
|
||
| - name: Post coverage comment | ||
| if: always() | ||
|
cacosta33 marked this conversation as resolved.
Outdated
|
||
| uses: actions/github-script@v7 | ||
| env: | ||
| PR_COVERAGE: ${{ steps.compare.outputs.pr_coverage }} | ||
| DEV_COVERAGE: ${{ steps.compare.outputs.dev_coverage }} | ||
| DELTA: ${{ steps.compare.outputs.delta }} | ||
| RESULT: ${{ steps.compare.outputs.result }} | ||
| STATUS: ${{ steps.compare.outputs.status }} | ||
| with: | ||
| script: | | ||
| const prCoverage = process.env.PR_COVERAGE || '0.0'; | ||
| const devCoverage = process.env.DEV_COVERAGE || '0.0'; | ||
| const delta = process.env.DELTA || '0.0'; | ||
| const result = process.env.RESULT || 'unknown'; | ||
| const status = process.env.STATUS || '❓ UNKNOWN'; | ||
|
|
||
| let emoji = '📊'; | ||
| let message = ''; | ||
|
|
||
| if (result === 'decreased') { | ||
| emoji = '⚠️'; | ||
| message = 'Code coverage has **decreased** by ' + delta.replace('-', '') + '%. Please add tests to maintain or improve coverage.'; | ||
|
cacosta33 marked this conversation as resolved.
Outdated
|
||
| } else if (result === 'increased') { | ||
| emoji = '🎉'; | ||
| message = 'Great job! Code coverage **improved** by ' + delta + '%.'; | ||
| } else if (result === 'unchanged') { | ||
| emoji = '✅'; | ||
| message = 'Code coverage **maintained** at ' + prCoverage + '%.'; | ||
| } | ||
|
|
||
| let comment = '## ' + emoji + ' Code Coverage Report\n\n'; | ||
| comment += status + '\n\n'; | ||
| comment += '| Branch | Coverage | Delta |\n'; | ||
| comment += '|--------|----------|-------|\n'; | ||
| comment += '| dev (baseline) | ' + devCoverage + '% | - |\n'; | ||
| comment += '| PR branch | ' + prCoverage + '% | ' + delta + '% |\n\n'; | ||
| comment += message + '\n\n'; | ||
| comment += '---\n'; | ||
| comment += '*This check can be skipped by adding the `code-coverage-skip` label to the PR.*'; | ||
|
|
||
| await github.rest.issues.createComment({ | ||
| owner: context.repo.owner, | ||
| repo: context.repo.repo, | ||
| issue_number: context.issue.number, | ||
| body: comment | ||
| }); | ||
|
|
||
| # Handle skipped case with explicit success | ||
| code-coverage-skipped: | ||
| name: Code Coverage Check (Skipped) | ||
| runs-on: ubuntu-latest | ||
|
|
||
| # Run only if PR has 'code-coverage-skip' label | ||
| if: "contains(github.event.pull_request.labels.*.name, 'code-coverage-skip')" | ||
|
|
||
| steps: | ||
| - name: Skip coverage check | ||
| run: | | ||
| echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" | ||
| echo "✅ PASSED - Code Coverage Check (Skipped)" | ||
| echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" | ||
| echo "" | ||
| echo "Code coverage check skipped due to 'code-coverage-skip' label." | ||
| echo "" | ||
| echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" | ||
|
|
||
| - name: Post skip comment | ||
| uses: actions/github-script@v7 | ||
| with: | ||
| script: | | ||
| let comment = '## ⏭️ Code Coverage Check Skipped\n\n'; | ||
| comment += '✅ **PASSED** (Skipped)\n\n'; | ||
| comment += 'This PR has the `code-coverage-skip` label, so the code coverage check was skipped.\n\n'; | ||
| comment += '---\n'; | ||
| comment += '*To re-enable coverage checks, remove the `code-coverage-skip` label.*'; | ||
|
|
||
| await github.rest.issues.createComment({ | ||
| owner: context.repo.owner, | ||
| repo: context.repo.repo, | ||
| issue_number: context.issue.number, | ||
| body: comment | ||
| }); | ||
|
cacosta33 marked this conversation as resolved.
Outdated
|
||
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.