jdaugherty opened a new pull request, #455: URL: https://github.com/apache/grails-intellij-plugin/pull/455
## Why The Sonatype `scan-gradle-plugin` registers `ossIndexAudit` as a task that is incompatible with the configuration cache, so every build that ran it discarded the cache entry: ``` Configuration cache entry discarded because incompatible task was found: 'task `:libs-grails-rt:ossIndexAudit` of type `org.sonatype.gradle.plugins.scan.ossindex.OssIndexAuditTask`'. ``` grails-core replaced it with its own scanner in [`build-logic/vulnerability-scan`](https://github.com/apache/grails-core/tree/8.0.x/build-logic/vulnerability-scan). This PR ports that scanner here, and adds the CycloneDX SBOM grails-core ships for its jars. ## Vulnerability scan The scanner is this build's own code in `build-logic`, package `org.apache.grails.intellij.build.scan`, ported from grails-core with the same behaviour and tests. - **`vulnerabilityScan`**, in every project that compiles, looks the resolved `runtimeClasspath` and `compileClasspath` up in [OSV](https://osv.dev). When `SONATYPE_GUIDE_USERNAME` and `SONATYPE_GUIDE_TOKEN` are set, it also queries Sonatype Guide. - **Credentials are read when the scan runs**, so they never enter the configuration cache entry, and a rotated token reuses the entry. - **Answers are cached** in the Gradle user home for an hour. The cache sits in the directory grails-core uses, so a machine that builds both projects asks the databases once. - **`vulnerabilityScanReport`**, on the root project, writes a Markdown summary to `build/reports/vulnerability-scan/summary.md`. It covers failed scans too, and it lists exclusions that no longer match anything. - **Exclusions need a reason.** The built-in list in `BuiltInExclusions` is empty, and a project adds its own with `vulnerabilityScan { exclude(id, module, reason) }`. Three things differ from grails-core because this is an IntelliJ plugin build: - **The IntelliJ Platform's own components are skipped.** The platform Gradle plugin puts about 800 IDE modules and bundled plugins on every compile classpath, as `bundledModule:` and `bundledPlugin:` coordinates. No vulnerability database knows them, so the `intellij-platform` convention sets `vulnerabilityScan.ignoredGroups` to leave them out. Real Maven artifacts the platform pulls in are still scanned. - **`java-legacy` projects scan `runtimeClasspath` only.** Their compile-only dependencies are era-pinned Grails 1.x/2.x and Groovy 2.4 stubs of the environment they run in, never shipped. - **`libs/testFramework` scans `runtimeClasspath` only.** Its compile classpath is JetBrains' test-framework jars at the platform version. The first full scan found 11 advisories there, in the Jackson 3.1.4 and Bouncy Castle 1.84 jars those test frameworks depend on. They are on no runtime classpath and in no distribution, and only a platform bump moves them. The workflow keeps its weekly run and manual dispatch. It now also runs on a pull request a committer labels `vulnerability scan`, posting the summary as a sticky comment. ⚠️ That label does not exist on this repository yet. ## SBOM - **`sbom`** turns the CycloneDX output into the file that ships. It is byte-for-byte reproducible: the timestamp is the epoch or `SOURCE_DATE_EPOCH`, the serial number is derived from the content, and dependency lists are sorted. - **Licenses follow ASF policy.** Each dependency is recorded under the one license `SbomLicensePolicy` picks for it, and a license the policy does not permit fails the build. The mapping and exception tables are empty, because everything in the ZIP is built from this repository today. - **It ships twice in the plugin ZIP:** as `sbom.json` next to `LICENSE` and `NOTICE`, and in the composed jar as `META-INF/sbom.json`, with `Sbom-Location` and `Sbom-Format` manifest attributes. IPGP writes the composed jar's manifest itself, so those attributes are set on `composedJar` as well. ## Verification Run locally on this branch: - **`./gradlew check`** passed, with no compile errors. That covers the plugin's 1202 tests, the license audit and the build-logic tests. - **build-logic tests:** 68 pass. The scan and SBOM tests run the convention plugins through TestKit against stubs of the OSV and Sonatype Guide APIs and a local Maven repository, with the configuration cache on and its problems fatal. - **Configuration cache:** `./gradlew vulnerabilityScan vulnerabilityScanReport --continue` stores the entry, then reuses it. The scan finds no known vulnerabilities in the 16 projects, checked against OSV only, because no Sonatype token was set. - **Reproducibility:** two `./gradlew clean buildPlugin --no-build-cache` runs produced byte-identical ZIPs with the SBOM included. - **`./gradlew validateActions`** passed. The workflow only uses actions already pinned in the other workflows. Not verified locally: the Sonatype Guide path against the real API, and the pull-request trigger with its sticky comment. A labelled run on this PR would exercise both once the label exists. Closes the "Generate a CycloneDX SBOM" item in `IMPROVEMENT-PLAN.md`. 🤖 Generated with [Claude Code](https://claude.com/claude-code) -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
