Skip to content

spdx/spdx-gradle-plugin

Repository files navigation

spdx-gradle-plugin

An spdx gradle plugin

This project currently produces valid sboms for the projects we've tested. If it does not work for your case, please let us know in a new issue we can handle new use cases.

Usage

Gradle Plugin Portal Gradle Plugin Portal

This plugin is published to Gradle Plugin Portal: https://plugins.gradle.org/plugin/org.spdx.sbom

Local Development

You can build and deploy locally and then use in your project

Install into local maven

$ git clone git@github.com:spdx/spdx-gradle-plugin
$ ./gradlew publishToMavenLocal -Pskip.signing

Add mavenLocal as a plugin repository (settings.gradle.kts)

pluginManagement {
 repositories {
     mavenLocal()
     gradlePluginPortal()
 }
}

Basic Usage

Apply and configure the plugin

plugins {
  `java`
  ...
  id("org.spdx.sbom") version "0.10.0"
}
...
// there is no default build, you *must* specify a target
spdxSbom {
  targets {
    // create a target named "release",
    // this is used for the task name (spdxSbomForRelease)
    // and output file (release.spdx.json)
    create("release") {
      // configure here
    }
  }
}

run sbom generation (use --stacktrace to report bugs)

./gradlew :spdxSbomForRelease
# or use the aggregate task spdxSbom to run all sbom tasks
# ./gradlew :spdxSbom

output in: build/spdx/release.spdx.json

Example output for the plugin run on this project is example.spdx.json

Configuration

Tasks can be configured via the extension

spdxSbom {
  targets {
    // create a target named "release",
    // this is used for the task name (spdxSbomForRelease)
    // and output file (build/spdx/release.spdx.json)
    create("release") {
      // use a different configuration (or multiple configurations)
      // android users will need to set this to an android build specific configuration
      configurations.set(listOf("myCustomConfiguration"))

      // override the default output file
      outputFile.set(layout.buildDirectory.file("custom-spdx.filename"))

      // provide scm info (usually from your CI)
      scm {
        uri.set("my-scm-repository")
        revision.set("asdfasdfasdf...")
      }

      // adjust properties of the document
      document {
        name.set("my spdx document")
        namespace.set("https://my.org/spdx/<some UUID>")
        creator.set("Person:Goose Loosebazooka")
        supplier.set("Organization:loosebazooka industries")

        // add an uber package on the document between the document and the
        // root module of the project being analyzed, you probably don't need this
        // but it's available if you want to describe the artifact in a special way
        uberPackage {
          // you must set all or none of these
          name.set("goose")
          version.set("1.2.3")
          supplier.set("Organization:loosebazooka industries")
        }
    }
    // optionally have multiple targets
    // create("another") {
    // }
  }
}

Notes

  • Licensing and copyright is somewhat incomplete (works well for maven deps)
  • Output is always json

Experimental

If you use these experimental features, they will change them whenever with no notification. They are to support very specific build usecases and are not for general consumption

Project Isolation (unreleased)

To inject project information that would otherwise be unresolvable for all project dependencies by the tooling when setting -Dorg.gradle.unsafe.isolated-projects=true.

Using this extension with caution and note the following behavior:

  • This data is accessed by the org.spdx.sbom plugin whether you are in isolated-projects mode or not.
  • You cannot change the values on the current project that an sbom is being generated for, only on its project dependencies. Setting the IsolatedProjectInfo on the project in question will just be ignored.
  • The plugin makes no effort to validate your inputs here, and if this goes out of sync with your project build setup you may end up with inconsistent sboms.
import org.spdx.sbom.gradle.project.IsolatedProjectInfo

spdxSbom {
  targets {
    create ("release") {
      ...
      isolatedProjects {
        isolatedProjectInfo.set(project.provider {
          mapOf<String, IsolatedProjectInfo>(
            ":" to IsolatedProjectInfo.of(":", "root-project-version"),
            ":sub-project" to IsolatedProjectInfo.of(":sub-project", "sub-project-version")
          )
        })
      }
    }
  }
}

Task Extension (probably bad idea to use)

use taskExtension to modify sbom data provided to the sbom task. The goal is to gradually move these into the plugin extension, but they here for now. This may mess with up-to-date checks and caching so be careful when using.

tasks.withType<SpdxSbomTask> {
   taskExtension.set(object : SpdxSbomTaskExtension {
       override fun mapRepoUri(input: URI, moduleId: ModuleVersionIdentifier): URI {
           // ignore input and return duck
           return URI.create("https://duck.com/repository")
       }
       override fun mapScmForProject(original: ScmInfo, projectInfo: ProjectInfo): ScmInfo {
           // ignore provided scminfo (from extension) and project info (the project we are looking for scm info)
           return ScmInfo.from("github.com/goose", "my-sha-is-also-a-goose")
       }
       override fun shouldCreatePackageForProject(projectInfo: ProjectInfo): Boolean {
           // return false to skip adding the project into SBOM if it doesn't represent an external dependency. All
           // dependencies of the skipped project will be analyzed and represented in the SBOM as dependencies of the
           // project's parent.
           return false
       }
   })
}

You can use the abstract class DefaultSpdxSbomTaskExtension if you don't want to implement all the methods of the interface SpdxSbomTaskExtension.

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Languages