1919 # Run every Monday at 03:00 UTC
2020 - cron : ' 0 3 * * 1'
2121 workflow_dispatch :
22- # Do not scan concurrently; OSS Index has per-account rate limits
22+ # Opt in per pull request by applying the "vulnerability scan" label. Applying a label
23+ # requires write access, so only a committer can start a scan.
24+ pull_request :
25+ types : [labeled, synchronize, reopened]
26+ # Used only to tell a fork pull request that it cannot be scanned. A `pull_request` run
27+ # raised from a fork gets neither the Sonatype credentials nor a token that can comment,
28+ # so the notice has to come from `pull_request_target`. That job checks out the base
29+ # branch and never runs anything from the pull request.
30+ pull_request_target :
31+ types : [labeled, synchronize, reopened]
32+ # Do not scan concurrently; OSS Index has per-account rate limits.
33+ # The event name is part of the group so the `pull_request` scan and the `pull_request_target`
34+ # notice for the same pull request cannot cancel one another.
2335concurrency :
24- group : ${{ github.workflow }}-${{ github.ref }}
25- cancel-in-progress : false
36+ group : ${{ github.workflow }}-${{ github.event_name }}-${{ github.event.pull_request.number || github. ref }}
37+ cancel-in-progress : ${{ github.event_name == 'pull_request' || github.event_name == 'pull_request_target' }}
2638jobs :
2739 scan-grails-core :
2840 name : " OSS Index Scan - grails-core"
41+ if : github.event_name == 'schedule' || github.event_name == 'workflow_dispatch'
2942 runs-on : ubuntu-24.04
3043 permissions :
3144 contents : read
3245 steps :
3346 - name : " 📥 Checkout repository"
3447 uses : actions/checkout@v6
48+ - name : " ☕️ Determine Java version from .sdkmanrc"
49+ # Read the JDK the build targets out of the file that already declares it, so a
50+ # baseline bump does not leave a stale literal behind here. Only the major is kept:
51+ # a scan is outside the reproducible-build surface, so CI takes the runner's current
52+ # release of that major rather than pinning the patch version.
53+ id : sdkmanrc
54+ run : |
55+ set -euo pipefail
56+ sdkman_java=$(grep -E '^java=' .sdkmanrc | cut -d= -f2 || true)
57+ if [ -z "${sdkman_java}" ]; then
58+ echo "❌ Could not determine the java version from .sdkmanrc" >&2
59+ exit 1
60+ fi
61+ echo "Scanning with JDK ${sdkman_java%%.*} (from .sdkmanrc: ${sdkman_java})"
62+ echo "java-version=${sdkman_java%%.*}" >> "$GITHUB_OUTPUT"
3563 - name : " ☕️ Setup JDK"
3664 uses : actions/setup-java@v4
3765 with :
3866 distribution : liberica
39- java-version : 17
67+ java-version : ${{ steps.sdkmanrc.outputs.java-version }}
4068 - name : " 🐘 Setup Gradle"
4169 uses : gradle/actions/setup-gradle@50e97c2cd7a37755bbfafc9c5b7cafaece252f6e # v6.1.0
4270 with :
@@ -50,30 +78,109 @@ jobs:
5078 run : ./gradlew ossIndexAudit --continue --info 2>&1 | tee /tmp/ossindex-scan.log; exit ${PIPESTATUS[0]}
5179 - name : " 📋 Publish Vulnerability Summary"
5280 if : always()
81+ run : >
82+ .github/scripts/ossIndexReport.sh
83+ /tmp/ossindex-scan.log
84+ '${{ steps.scan.outcome }}'
85+ '🔍 OSS Index Vulnerability Scan — grails-core'
86+ >> $GITHUB_STEP_SUMMARY
87+
88+ scan-pull-request :
89+ name : " OSS Index Scan - pull request"
90+ # `synchronize` and `reopened` re-scan a pull request that already carries the label.
91+ if : >-
92+ github.event_name == 'pull_request'
93+ && contains(github.event.pull_request.labels.*.name, 'vulnerability scan')
94+ && github.event.pull_request.head.repo.full_name == github.repository
95+ runs-on : ubuntu-24.04
96+ permissions :
97+ contents : read
98+ pull-requests : write
99+ steps :
100+ - name : " 📥 Checkout pull request"
101+ uses : actions/checkout@v6
102+ - name : " ☕️ Determine Java version from .sdkmanrc"
103+ # Read the JDK the build targets out of the file that already declares it, so a
104+ # baseline bump does not leave a stale literal behind here. Only the major is kept:
105+ # a scan is outside the reproducible-build surface, so CI takes the runner's current
106+ # release of that major rather than pinning the patch version.
107+ id : sdkmanrc
53108 run : |
54- echo "## 🔍 OSS Index Vulnerability Scan — grails-core" >> $GITHUB_STEP_SUMMARY
55- if [ "${{ steps.scan.outcome }}" = "success" ]; then
56- echo "✅ No vulnerabilities found." >> $GITHUB_STEP_SUMMARY
57- else
58- echo "❌ Vulnerabilities detected." >> $GITHUB_STEP_SUMMARY
59- echo "" >> $GITHUB_STEP_SUMMARY
60- echo '```' >> $GITHUB_STEP_SUMMARY
61- awk '
62- BEGIN { in_section=0; in_vuln=0 }
63- { gsub(/\033\[[0-9;]*m/, "") }
64- /^##\[ossIndexAudit:begin\]/ { in_section=1; next }
65- /^##\[ossIndexAudit:end\]/ { in_section=0; in_vuln=0; next }
66- !in_section { next }
67- /^\[[0-9]+\/[0-9]+\] - pkg:maven\// {
68- sub(/^\[[0-9]+\/[0-9]+\] - /, "")
69- if (!seen_coord[$0]++) { print ""; print }
70- next
71- }
72- /^ Vulnerability Title:/ { in_vuln=1; block=$0 "\n"; cve_id=""; next }
73- in_vuln && /^ CVE:/ { match($0,/CVE-[0-9-]+/); if (RSTART) cve_id=substr($0,RSTART,RLENGTH); block=block $0 "\n"; next }
74- in_vuln && /^ Reference:/ { block=block $0 "\n"; if (cve_id && !seen_cve[cve_id]++) printf "%s",block; in_vuln=0; next }
75- in_vuln { block=block $0 "\n" }
76- ' /tmp/ossindex-scan.log >> $GITHUB_STEP_SUMMARY \
77- || echo "(no scan output captured — check the full log)" >> $GITHUB_STEP_SUMMARY
78- echo '```' >> $GITHUB_STEP_SUMMARY
109+ set -euo pipefail
110+ sdkman_java=$(grep -E '^java=' .sdkmanrc | cut -d= -f2 || true)
111+ if [ -z "${sdkman_java}" ]; then
112+ echo "❌ Could not determine the java version from .sdkmanrc" >&2
113+ exit 1
79114 fi
115+ echo "Scanning with JDK ${sdkman_java%%.*} (from .sdkmanrc: ${sdkman_java})"
116+ echo "java-version=${sdkman_java%%.*}" >> "$GITHUB_OUTPUT"
117+ - name : " ☕️ Setup JDK"
118+ uses : actions/setup-java@v4
119+ with :
120+ distribution : liberica
121+ java-version : ${{ steps.sdkmanrc.outputs.java-version }}
122+ - name : " 🐘 Setup Gradle"
123+ uses : gradle/actions/setup-gradle@50e97c2cd7a37755bbfafc9c5b7cafaece252f6e # v6.1.0
124+ with :
125+ develocity-access-key : ${{ secrets.DEVELOCITY_ACCESS_KEY }}
126+ - name : " 🔍 Run OSS Index Vulnerability Scan"
127+ env :
128+ SONATYPE_GUIDE_USERNAME : ${{ secrets.SONATYPE_GUIDE_USERNAME }}
129+ SONATYPE_GUIDE_TOKEN : ${{ secrets.SONATYPE_GUIDE_TOKEN }}
130+ continue-on-error : true
131+ id : scan
132+ run : ./gradlew ossIndexAudit --continue --info 2>&1 | tee /tmp/ossindex-scan.log; exit ${PIPESTATUS[0]}
133+ - name : " 📋 Build Vulnerability Report"
134+ if : always()
135+ # 60000 bytes keeps the listing clear of GitHub's 65536 character comment limit.
136+ run : >
137+ .github/scripts/ossIndexReport.sh
138+ /tmp/ossindex-scan.log
139+ '${{ steps.scan.outcome }}'
140+ '🔍 OSS Index Vulnerability Scan — pull request'
141+ 60000
142+ > /tmp/ossindex-report.md
143+ - name : " 📝 Publish Vulnerability Summary"
144+ if : always()
145+ run : cat /tmp/ossindex-report.md >> $GITHUB_STEP_SUMMARY
146+ - name : " 💬 Comment Vulnerability Report"
147+ if : always()
148+ env :
149+ GH_TOKEN : ${{ secrets.GITHUB_TOKEN }}
150+ run : >
151+ .github/scripts/postStickyComment.sh
152+ '${{ github.event.pull_request.number }}'
153+ '<!-- grails-vulnerability-scan -->'
154+ /tmp/ossindex-report.md
155+
156+ notify-fork-pull-request :
157+ name : " OSS Index Scan - unavailable"
158+ # A fork pull request cannot reach the Sonatype credentials, so say so instead of
159+ # leaving the label looking as though a scan ran.
160+ if : >-
161+ github.event_name == 'pull_request_target'
162+ && contains(github.event.pull_request.labels.*.name, 'vulnerability scan')
163+ && github.event.pull_request.head.repo.full_name != github.repository
164+ runs-on : ubuntu-24.04
165+ permissions :
166+ pull-requests : write
167+ steps :
168+ # Checks out the base branch, not the pull request; nothing from the fork is executed.
169+ - name : " 📥 Checkout base branch"
170+ uses : actions/checkout@v6
171+ - name : " 📋 Build Notice"
172+ run : |
173+ {
174+ echo "## 🔍 OSS Index Vulnerability Scan — pull request"
175+ echo "⚠️ Vulnerability scanning is not available because this branch is not on \`${{ github.repository }}\`."
176+ echo
177+ echo "The scan needs Sonatype Guide credentials, which GitHub withholds from workflow runs raised by a fork. Push the branch to \`${{ github.repository }}\` and open a pull request from there to have it scanned."
178+ } > /tmp/ossindex-report.md
179+ - name : " 💬 Comment Notice"
180+ env :
181+ GH_TOKEN : ${{ secrets.GITHUB_TOKEN }}
182+ run : >
183+ .github/scripts/postStickyComment.sh
184+ '${{ github.event.pull_request.number }}'
185+ '<!-- grails-vulnerability-scan -->'
186+ /tmp/ossindex-report.md
0 commit comments