From c2fd48b09c7072a4c182835d0a7e04721e7a7d13 Mon Sep 17 00:00:00 2001 From: Moritz Halbritter Date: Wed, 29 May 2024 09:51:50 +0200 Subject: [PATCH] Configure Gradle's processResources to include the SBOM This also configures the BootWar task to add the SBOM location to the manifest. --- .../gradle/plugin/CycloneDxPluginAction.java | 59 ++++++++++++++++--- 1 file changed, 50 insertions(+), 9 deletions(-) diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/plugin/CycloneDxPluginAction.java b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/plugin/CycloneDxPluginAction.java index f0b57648ba36..e258ed92bbc1 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/plugin/CycloneDxPluginAction.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/plugin/CycloneDxPluginAction.java @@ -21,9 +21,16 @@ import org.gradle.api.Action; import org.gradle.api.Plugin; import org.gradle.api.Project; +import org.gradle.api.Task; +import org.gradle.api.UnknownTaskException; +import org.gradle.api.plugins.JavaPluginExtension; +import org.gradle.api.tasks.Copy; +import org.gradle.api.tasks.SourceSet; import org.gradle.api.tasks.TaskProvider; +import org.gradle.api.tasks.bundling.Jar; import org.springframework.boot.gradle.tasks.bundling.BootJar; +import org.springframework.boot.gradle.tasks.bundling.BootWar; /** * {@link Action} that is executed in response to the {@link CycloneDxPlugin} being @@ -40,22 +47,56 @@ public Class> getPluginClass() { @Override public void execute(Project project) { - TaskProvider cyclonedxBom = project.getTasks().named("cyclonedxBom", CycloneDxTask.class); - cyclonedxBom.configure((task) -> { + SourceSet main = project.getExtensions() + .getByType(JavaPluginExtension.class) + .getSourceSets() + .getByName(SourceSet.MAIN_SOURCE_SET_NAME); + TaskProvider cycloneDxTaskProvider = project.getTasks() + .named("cyclonedxBom", CycloneDxTask.class); + cycloneDxTaskProvider.configure((task) -> { task.getProjectType().convention("application"); task.getOutputFormat().convention("json"); task.getOutputName().convention("application.cdx"); task.getIncludeLicenseText().convention(false); }); - project.getTasks().named(SpringBootPlugin.BOOT_JAR_TASK_NAME, BootJar.class).configure((bootJar) -> { - CycloneDxTask cycloneDxTask = cyclonedxBom.get(); + TaskProvider processResourcesProvider = project.getTasks() + .named(main.getProcessResourcesTaskName(), Copy.class); + TaskProvider bootJarProvider = getTaskIfAvailable(project, SpringBootPlugin.BOOT_JAR_TASK_NAME, + BootJar.class); + TaskProvider bootWarProvider = getTaskIfAvailable(project, SpringBootPlugin.BOOT_WAR_TASK_NAME, + BootWar.class); + processResourcesProvider.configure((processResources) -> { + processResources.dependsOn(cycloneDxTaskProvider); + CycloneDxTask cycloneDxTask = cycloneDxTaskProvider.get(); String sbomFileName = cycloneDxTask.getOutputName().get() + getSbomExtension(cycloneDxTask); - bootJar.from(cycloneDxTask, (spec) -> spec.include(sbomFileName).into("META-INF/sbom")); - bootJar.manifest((manifest) -> { - manifest.getAttributes().put("Sbom-Format", "CycloneDX"); - manifest.getAttributes().put("Sbom-Location", "META-INF/sbom/" + sbomFileName); - }); + processResources.from(cycloneDxTask, (spec) -> spec.include(sbomFileName).into("META-INF/sbom")); }); + if (bootJarProvider != null) { + bootJarProvider.configure((bootJar) -> configureTask(bootJar, cycloneDxTaskProvider)); + } + if (bootWarProvider != null) { + bootWarProvider.configure((bootWar) -> configureTask(bootWar, cycloneDxTaskProvider)); + } + + } + + private void configureTask(Jar task, TaskProvider cycloneDxTaskTaskProvider) { + task.dependsOn(cycloneDxTaskTaskProvider); + CycloneDxTask cycloneDxTask = cycloneDxTaskTaskProvider.get(); + String sbomFileName = cycloneDxTask.getOutputName().get() + getSbomExtension(cycloneDxTask); + task.manifest((manifest) -> { + manifest.getAttributes().put("Sbom-Format", "CycloneDX"); + manifest.getAttributes().put("Sbom-Location", "META-INF/sbom/" + sbomFileName); + }); + } + + private TaskProvider getTaskIfAvailable(Project project, String name, Class type) { + try { + return project.getTasks().named(name, type); + } + catch (UnknownTaskException ex) { + return null; + } } private String getSbomExtension(CycloneDxTask task) {