11name : Build and Test SDK
22
3+ concurrency :
4+ group : ${{ github.workflow }}-${{ github.ref }}
5+ cancel-in-progress : true
6+
37on :
48 pull_request :
5- branches : " **"
9+ branches : [ "**"]
610
711env :
8- DIFF_COVERAGE_THRESHOLD : ' 80'
12+ DIFF_COVERAGE_THRESHOLD : " 80"
13+
14+ permissions :
15+ contents : read
16+ pull-requests : write
17+ issues : write
918
1019jobs :
1120 build :
12- runs-on : ubuntu-24.04
21+ runs-on : ubuntu-latest
1322 steps :
1423 - name : " [Checkout] Repo"
1524 uses : actions/checkout@v4
@@ -26,35 +35,97 @@ jobs:
2635 - name : " [Test] SDK Unit Tests"
2736 working-directory : OneSignalSDK
2837 run : |
29- ./gradlew testReleaseUnitTest --console=plain --continue
30- - name : " [Coverage] Generate JaCoCo merged XML"
31- working-directory : OneSignalSDK
32- run : |
33- ./gradlew jacocoTestReportAll jacocoMergedReport --console=plain --continue
34- - name : " [Setup] Python"
35- uses : actions/setup-python@v5
36- with :
37- python-version : ' 3.x'
38- - name : " [Diff Coverage] Install diff-cover"
38+ ./gradlew testDebugUnitTest --console=plain --continue
39+ - name : " [Diff Coverage] Check for bypass"
40+ id : coverage_bypass
3941 run : |
40- python -m pip install --upgrade pip diff-cover
41- - name : " [Diff Coverage] Check and HTML report"
42+ # Check if PR has Skip Coverage Check label
43+ if [ "${{ github.event_name }}" = "pull_request" ]; then
44+ LABELS="${{ toJson(github.event.pull_request.labels.*.name) }}"
45+ if echo "$LABELS" | grep -qiE "Skip Coverage Check|skip-coverage-check"; then
46+ echo "bypass=true" >> $GITHUB_OUTPUT
47+ echo "reason=PR has 'Skip Coverage Check' label" >> $GITHUB_OUTPUT
48+ echo "⚠️ Coverage check will not fail build (PR has 'Skip Coverage Check' label)"
49+ echo " Coverage will still be checked and reported"
50+ else
51+ echo "bypass=false" >> $GITHUB_OUTPUT
52+ fi
53+ else
54+ echo "bypass=false" >> $GITHUB_OUTPUT
55+ fi
56+ - name : " [Diff Coverage] Check coverage"
4257 working-directory : OneSignalSDK
4358 run : |
44- REPORT=build/reports/jacoco/merged/jacocoMergedReport.xml
45- test -f "$REPORT" || { echo "Merged JaCoCo report not found at $REPORT" >&2; exit 1; }
46- python -m diff_cover.diff_cover_tool "$REPORT" \
47- --compare-branch=origin/main \
48- --fail-under=$DIFF_COVERAGE_THRESHOLD
49- python -m diff_cover.diff_cover_tool "$REPORT" \
50- --compare-branch=origin/main \
51- --html-report diff_coverage.html || true
52- - name : Upload diff coverage HTML
53- if : always()
54- uses : actions/upload-artifact@v4
59+ # Use the shared coverage check script for consistency
60+ # Generate markdown report for PR comments
61+ # If bypassed, still run the check but don't fail the build
62+ set +e # Don't exit on error - we want to generate the report even if coverage fails
63+ if [ "${{ steps.coverage_bypass.outputs.bypass }}" = "true" ]; then
64+ SKIP_COVERAGE_CHECK=true GENERATE_MARKDOWN=true DIFF_COVERAGE_THRESHOLD=$DIFF_COVERAGE_THRESHOLD ./coverage/checkCoverage.sh
65+ else
66+ GENERATE_MARKDOWN=true DIFF_COVERAGE_THRESHOLD=$DIFF_COVERAGE_THRESHOLD ./coverage/checkCoverage.sh
67+ fi
68+ COVERAGE_EXIT_CODE=$?
69+ set -e # Re-enable exit on error
70+
71+ # Check if markdown report was generated
72+ if [ -f "diff_coverage.md" ]; then
73+ echo "✅ Coverage report generated"
74+ else
75+ echo "⚠️ Coverage report not generated"
76+ fi
77+
78+ # Only fail the build if coverage is below threshold AND not bypassed
79+ if [ "${{ steps.coverage_bypass.outputs.bypass }}" != "true" ] && [ $COVERAGE_EXIT_CODE -ne 0 ]; then
80+ echo "❌ Coverage check failed - build will fail"
81+ exit $COVERAGE_EXIT_CODE
82+ elif [ "${{ steps.coverage_bypass.outputs.bypass }}" = "true" ]; then
83+ echo "⚠️ Coverage check completed (bypassed - build will not fail)"
84+ exit 0
85+ else
86+ echo "✅ Coverage check passed"
87+ exit 0
88+ fi
89+ - name : Comment PR with coverage summary
90+ if : always() && github.event_name == 'pull_request'
91+ uses : actions/github-script@v7
5592 with :
56- name : diff-coverage-report
57- path : OneSignalSDK/diff_coverage.html
93+ script : |
94+ const fs = require('fs');
95+ const path = 'OneSignalSDK/diff_coverage.md';
96+ if (fs.existsSync(path)) {
97+ const content = fs.readFileSync(path, 'utf8');
98+ const body = `## 📊 Diff Coverage Report\n\n${content}\n\n📥 [View workflow run](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }})`;
99+
100+ // Find existing comment
101+ const comments = await github.rest.issues.listComments({
102+ owner: context.repo.owner,
103+ repo: context.repo.repo,
104+ issue_number: context.issue.number,
105+ });
106+
107+ const botComment = comments.data.find(comment =>
108+ comment.user.type === 'Bot' && comment.body.includes('Diff Coverage Report')
109+ );
110+
111+ if (botComment) {
112+ // Update existing comment
113+ await github.rest.issues.updateComment({
114+ owner: context.repo.owner,
115+ repo: context.repo.repo,
116+ comment_id: botComment.id,
117+ body: body
118+ });
119+ } else {
120+ // Create new comment
121+ await github.rest.issues.createComment({
122+ owner: context.repo.owner,
123+ repo: context.repo.repo,
124+ issue_number: context.issue.number,
125+ body: body
126+ });
127+ }
128+ }
58129 - name : Unit tests results
59130 if : failure()
60131 uses : actions/upload-artifact@v4
0 commit comments