github CycloneDX/cyclonedx-gradle-plugin cyclonedx-gradle-plugin-3.0.0-alpha-0
3.0.0-alpha-0

pre-release14 days ago

What's Changed

  • build(deps): bump org.cyclonedx.bom from 2.3.0 to 2.3.1 by @dependabot[bot] in #622
  • Update Gradle Wrapper from 8.14 to 8.14.1 by @github-actions[bot] in #621
  • build: run one build with multijdk tests by @skhokhlov in #623
  • build(deps): bump com.diffplug.spotless from 6.13.0 to 7.0.4 by @dependabot[bot] in #624
  • build(deps): bump org.apache.maven:maven-core from 3.9.9 to 3.9.10 by @dependabot[bot] in #628
  • build(deps): bump gradle/actions from 4.4.0 to 4.4.1 by @dependabot[bot] in #633
  • build(deps): bump com.diffplug.spotless from 7.0.4 to 7.1.0 by @dependabot[bot] in #640
  • build(deps): bump org.apache.maven:maven-core from 3.9.10 to 3.9.11 by @dependabot[bot] in #642
  • build(deps): bump commons-codec:commons-codec from 1.18.0 to 1.19.0 by @dependabot[bot] in #649
  • build(deps): bump com.diffplug.spotless from 7.1.0 to 7.2.1 by @dependabot[bot] in #648
  • build(deps): bump commons-io:commons-io from 2.19.0 to 2.20.0 by @dependabot[bot] in #645
  • build: enable build cache and configuration cache by @skhokhlov in #651
  • build: explicitly set java 8 as a target version and java 21 to run g… by @skhokhlov in #653
  • docs: update CONTRIBUTING.md by @skhokhlov in #652
  • fix: use provider for component version convention by @sergej-koscejev in #650
  • build: Make org.cyclonedx:cyclonedx-core-java an api dependency by @zarebski-m in #656
  • build: upgrade to gradle 9 by @skhokhlov in #657
  • build(deps): bump gradle/actions from 4.4.1 to 4.4.2 by @dependabot[bot] in #658
  • build(deps): bump org.junit.jupiter:junit-jupiter-api from 5.11.4 to 5.13.4 by @dependabot[bot] in #646
  • fix: scrub credentials from git url by @MalickBurger in #663
  • refactor: use Logging#getLogger for logs by @skhokhlov in #664
  • build(deps): bump actions/checkout from 4.2.2 to 5.0.0 by @dependabot[bot] in #662
  • refactor: migrate to jspecify annotations by @skhokhlov in #665
  • feat: collect sbom per project, add cyclonedxAggregateBom task by @skhokhlov in #661
  • build(deps): bump com.uber.nullaway:nullaway from 0.12.8 to 0.12.9 by @dependabot[bot] in #666
  • build: prepare version 3.0.0-alpha-0 by @skhokhlov in #668

New Contributors

Full Changelog: cyclonedx-gradle-plugin-2.3.1...cyclonedx-gradle-plugin-3.0.0-alpha-0

CycloneDX Gradle Plugin Migration Guide: 2.3.1 → 3.0.0

This guide covers the breaking changes and migration steps required when upgrading from CycloneDX Gradle Plugin version 2.3.1 to 3.0.0.

Prerequisites and System Requirements

New System Requirements in 3.0.0

  • Java 17 or newer (previously supported older versions)
  • Gradle 9.0 or newer (previously supported Gradle 8.0+)

The plugin might be still compatible with older versions, but it's not tested.

⚠️ Important: If you cannot upgrade to these requirements, continue using version 2.x.x.

Task Behavior and Naming Changes

Version 2.3.1: Single Task Model

# Single task for all scenarios
gradle cyclonedxBom

Version 3.0.0: Dual Task Model

# Generate per-project SBOMs (individual projects)
gradle cyclonedxDirectBom

# Generate aggregated SBOM (multi-project builds)
gradle cyclonedxBom

Task Behavior Changes

Aspect Version 2.3.1 Version 3.0.0
Per-project SBOMs Single task handled both cyclonedxDirectBom task
Multi-project aggregation Single task handled both cyclonedxBom task (when plugin applied to root)
Output location ./build/reports/bom.{xml,json} Direct: build/reports/cyclonedx-direct/bom.{xml,json}
Aggregate: build/reports/cyclonedx/bom.{xml,json}
Task types Single task class CyclonedxDirectTask and CyclonedxAggregateTask

Configuration Method Changes

❌ Version 2.3.1: Direct Task Configuration

// OLD - No longer supported
tasks.cyclonedxBom {
    setIncludeConfigs(["runtimeClasspath"])
    setDestination(file("build/reports"))
    setOutputName("bom")
    setOutputFormat("json")
}

✅ Version 3.0.0: Extension-Based Configuration

// NEW - Preferred approach
cyclonedxBom {
    includeConfigs = ["runtimeClasspath"]
    jsonOutput = file("build/reports/sbom/bom.json")
    xmlOutput = file("build/reports/sbom/bom.xml")
}

Plugin Application Recommendations

Version 2.3.1: Multiple Application Strategies

// Applied to individual projects OR used init scripts
plugins {
    id 'org.cyclonedx.bom' version '2.3.1'
}

Version 3.0.0: Root Project Application

// ROOT PROJECT build.gradle - RECOMMENDED
plugins {
    id 'org.cyclonedx.bom' version '3.0.0'
}

cyclonedxBom {
    // Configuration applies to both direct and aggregate tasks
}

Benefits of root project application:

  • Automatic aggregation across all subprojects
  • Centralized configuration
  • No need for init scripts in multi-project builds
  • Access to both cyclonedxDirectBom and cyclonedxBom tasks

Output Configuration Changes

Version 2.3.1: Combined Output Properties

cyclonedxBom {
    destination = file("build/reports")           // Directory
    outputName = "bom"                           // Base filename
    outputFormat = "json"                        // Format: xml, json, all
}

Version 3.0.0: Explicit File Properties

cyclonedxBom {
    // Explicit file paths for each format
    jsonOutput = file("build/reports/sbom/bom.json")
    xmlOutput = file("build/reports/sbom/bom.xml")
}

// Or disable specific formats
tasks.withType<CyclonedxDirectTask> {
    xmlOutput.unsetConvention()  // Generate JSON only
}

Migration Example

// OLD (2.3.1)
cyclonedxBom {
    destination = file("build/custom")
    outputName = "my-sbom"
    outputFormat = "json"
}

// NEW (3.0.0)
cyclonedxBom {
    jsonOutput = file("build/custom/my-sbom.json")
    // xmlOutput omitted = only JSON generated
}

Schema Version Configuration Changes

Version 2.3.1: String-Based

cyclonedxBom {
    schemaVersion = "1.6"
}

Version 3.0.0: Enum-Based

import org.cyclonedx.model.schema.SchemaVersion

cyclonedxBom {
    schemaVersion = SchemaVersion.VERSION_16
}

Organizational Entity Configuration

Version 2.3.1: Closure-Based Configuration

cyclonedxBom {
    // Closure-based approach
    organizationalEntity { oe ->
        oe.name = 'Test Company'
        oe.url = ['www.test1.com', 'www.test2.com']
        oe.addContact(organizationalContact)
    }
}

Version 3.0.0: Direct Object Assignment

import org.cyclonedx.model.*

cyclonedxBom {
    // Direct object assignment
    organizationalEntity = OrganizationalEntity().apply {
        name = "ACME Corporation"
        urls = listOf("https://www.acme.com", "https://security.acme.com")
        addContact(OrganizationalContact().apply {
            name = "Security Team"
            email = "security@acme.com"
            phone = "+1-555-SECURITY"
        })
    }
}

License Choice Configuration

Version 2.3.1: Closure-Based Configuration

cyclonedxBom {
    // Closure-based approach
    licenseChoice { lc ->
        License license = new License()
        license.setName("Apache-2.0")
        license.setUrl("https://www.apache.org/licenses/LICENSE-2.0.txt")
        lc.addLicense(license)
    }
}

Version 3.0.0: Direct Object Assignment

import org.cyclonedx.model.*

cyclonedxBom {
    // Direct object assignment
    licenseChoice = LicenseChoice().apply {
        addLicense(License().apply {
            name = "Apache-2.0"
            url = "https://www.apache.org/licenses/LICENSE-2.0.txt"
        })
    }
}

External References Configuration

Version 2.3.1: VCS Git Configuration

cyclonedxBom {
    // VCS-specific configuration
    setVCSGit { vcs ->
        vcs.url = "https://github.com/example/repo.git"
        vcs.comment = "Source repository"
    }
}

Version 3.0.0: Generic External References

import org.cyclonedx.model.*

cyclonedxBom {
    // Generic external references
    externalReferences = listOf(
        ExternalReference().apply {
            url = "https://github.com/example/repo.git"
            type = ExternalReference.Type.VCS
        },
        ExternalReference().apply {
            url = "https://example.com/docs"
            type = ExternalReference.Type.DOCUMENTATION
        }
    )
}

Multi-Project Setup Changes

Version 2.3.1: Init Script Approach

// init.gradle file required
gradle --init-script init.gradle cyclonedxBom

// init.gradle content:
initscript {
  repositories {
    maven { url "https://plugins.gradle.org/m2/" }
  }
  dependencies {
    classpath "org.cyclonedx:cyclonedx-gradle-plugin:2.3.1"
  }
}

allprojects {
  apply plugin: org.cyclonedx.gradle.CycloneDxPlugin
  cyclonedxBom {
    // configuration
  }
}

Version 3.0.0: Root Project Application

// Root project build.gradle - SIMPLIFIED
plugins {
    id 'org.cyclonedx.bom' version '3.0.0'
}

cyclonedxBom {
    skipProjects = listOf("test-utils", "integration-tests")
    includeConfigs = listOf("runtimeClasspath")
    // Configuration automatically applies to all subprojects
}
# Generate per-project SBOMs for all projects
./gradlew cyclonedxDirectBom

# Generate single aggregated SBOM
./gradlew cyclonedxBom

Breaking Changes Summary

🚨 Critical Breaking Changes

  1. Java 17+ and Gradle 9+ required
  2. Task configuration syntax removed - use extension configuration only
  3. Output property names changed - destination/outputName/outputFormatjsonOutput/xmlOutput
  4. Metadata configuration syntax changed - Closures → Object assignment

⚠️ Behavioral Changes

  1. New task structure - Two tasks instead of one
  2. Different default output locations
  3. Plugin should be applied to root project for aggregation
  4. includeBuildSystem defaults to true

Step-by-Step Migration Process

1. Update System Requirements

# Ensure Java 17+
java -version

# Ensure Gradle 9+
./gradlew --version

2. Update Plugin Version

plugins {
    id 'org.cyclonedx.bom' version '3.0.0'
}

3. Migrate Configuration Syntax

// Remove tasks.cyclonedxBom { } blocks
// Convert to cyclonedxBom { } extension configuration

4. Update Output Configuration

// OLD
cyclonedxBom {
    destination = file("build/reports")
    outputName = "sbom"
    outputFormat = "json"
}

// NEW
cyclonedxBom {
    jsonOutput = file("build/reports/sbom.json")
    xmlOutput.unsetConvention()
}

5. Update Schema Version

import org.cyclonedx.model.schema.SchemaVersion

cyclonedxBom {
    schemaVersion = SchemaVersion.VERSION_16
}

6. Migrate Metadata Configuration

import org.cyclonedx.model.*

cyclonedxBom {
    // Convert closure-based to object assignment
    organizationalEntity = OrganizationalEntity().apply {
        // configuration
    }
    
    licenseChoice = LicenseChoice().apply {
        // configuration
    }
    
    externalReferences = listOf(
        ExternalReference().apply {
            // configuration
        }
    )
}

7. Update Task Execution

# For per-project SBOMs
./gradlew cyclonedxDirectBom

# For aggregated SBOM (multi-project)
./gradlew cyclonedxBom

8. Verify Output Locations

Check that your SBOM files are generated in the expected locations:

  • Direct: build/reports/cyclonedx-direct/
  • Aggregated: build/reports/cyclonedx/

Common Migration Issues and Solutions

Issue: "Task configuration not found"

Problem: Using tasks.cyclonedxBom { } syntax
Solution: Use cyclonedxBom { } extension configuration

Issue: "Output files not found"

Problem: Looking in old output location
Solution: Check new default locations or configure explicit paths

Issue: "Schema version error"

Problem: Using string schema version
Solution: Import and use SchemaVersion enum

Issue: "Multi-project aggregation not working"

Problem: Plugin not applied to root project
Solution: Apply plugin to root project and use cyclonedxBom task

Testing Your Migration

  1. Clean build directory: ./gradlew clean
  2. Test per-project generation: ./gradlew cyclonedxDirectBom --info
  3. Test aggregation (if applicable): ./gradlew cyclonedxBom --info
  4. Verify output files exist in expected locations
  5. Validate SBOM content matches expectations

This migration guide should help you successfully upgrade from CycloneDX Gradle Plugin 2.3.1 to 3.0.0. The new version provides better separation of concerns with dedicated tasks and improved configuration flexibility.

Don't miss a new cyclonedx-gradle-plugin release

NewReleases is sending notifications on new releases.