You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Several task properties currently expose cyclonedx-core-java model and enum types directly. This makes ordinary
plugin configuration depend on the implementation library's API and turns core upgrades into migration work for
plugin users.
Users need a configuration surface that is natural in both Groovy and Kotlin, remains stable when CycloneDX Core
evolves, and offers a gradual migration from existing 3.x builds.
Desired outcome
CycloneDX Gradle Plugin 4.0 provides a plugin-owned, Gradle-native DSL directly on the Direct and Aggregate SBOM tasks.
Users can configure the same effective metadata available through the existing core-backed properties without
constructing CycloneDX Core objects.
The 4.0 experience should have these properties:
The canonical DSL uses plugin-owned terms and types, with validated string aliases where they improve Groovy and
Kotlin usability.
It has capability parity with every effective field reachable through the five existing core-backed properties,
rather than attempting to mirror the complete CycloneDX object model.
Existing 3.x configurations using schemaVersion, projectType, organizationalEntity, licenseChoice, and externalReferences remain functional throughout 4.x as a deprecated compatibility facade. Removal is no earlier
than 5.0.
Canonical and legacy configuration describe one result: equivalent duplicate values are accepted and conflicts fail
with actionable diagnostics rather than silent precedence.
Migration guidance is mechanical and example-driven for both Groovy and Kotlin. Detectable legacy use produces at
most one migration warning per build.
The canonical DSL does not expose a raw CycloneDX Core escape hatch.
CycloneDX 1.7 becomes the default SBOM schema in 4.0 after support is delivered by Add support for CycloneDX v1.7 schema #832. Explicitly selecting 1.6
remains supported for users who need the previous output contract.
Apart from explicitly documented 4.0 output-contract changes, equivalent legacy and canonical configuration must
produce equivalent parsed CycloneDX meaning. Serializer formatting and irrelevant collection ordering are not
compatibility guarantees.
Proposed DSL shape
The following examples preserve the direction discussed during planning. They are a reference for the task-local
hierarchy and migration experience, not a commitment to every identifier before Groovy and Kotlin compilation
fixtures validate the final API.
Kotlin, using plugin-owned typed values:
tasks.cyclonedxDirectBom {
bom {
schemaVersion(SchemaVersion.VERSION_17)
projectType(ProjectType.APPLICATION)
organization {
name ="Example"
url("https://example.com")
contact {
name ="Security"
email ="security@example.com"
}
}
licenses {
license {
id ="Apache-2.0"
}
}
externalReference {
type =ExternalReferenceType.WEBSITE
url ="https://example.com/project"
}
}
}
Groovy, demonstrating the permanent normalized string aliases:
tasks.named("cyclonedxDirectBom") {
bom {
schemaVersion "1.7"
projectType "application"
organization {
name ="Example"
url "https://example.com"
contact {
name ="Security"
email ="security@example.com"
}
}
licenses {
license {
id ="Apache-2.0"
}
}
externalReference {
type ="website"
url ="https://example.com/project"
}
}
}
The same bom block is available on cyclonedxBom. It owns schema selection, the main component, and Metadata
Enrichment only. Dependency selection, project discovery, aggregation membership, outputs, and root-to-member
relationships remain outside this block.
Architecture outcome
Configuration remains task-local, as recorded in ADR 0003;
no shared root-owned plugin extension is introduced.
Gradle-managed DSL values normalize into a plugin-owned internal configuration model. CycloneDX Core types exist
only at the compatibility boundary and in a one-way mapping layer used to build the SBOM.
The canonical DSL and resolved configuration stay independent of project discovery, aggregation membership,
outgoing variants, and root-to-member dependency-edge policy.
A shared service may deduplicate a migration diagnostic only. It must not become a mutable registry of projects,
task state, artifacts, aggregation members, or dependency edges.
User problem
Several task properties currently expose
cyclonedx-core-javamodel and enum types directly. This makes ordinaryplugin configuration depend on the implementation library's API and turns core upgrades into migration work for
plugin users.
Users need a configuration surface that is natural in both Groovy and Kotlin, remains stable when CycloneDX Core
evolves, and offers a gradual migration from existing 3.x builds.
Desired outcome
CycloneDX Gradle Plugin 4.0 provides a plugin-owned, Gradle-native DSL directly on the Direct and Aggregate SBOM tasks.
Users can configure the same effective metadata available through the existing core-backed properties without
constructing CycloneDX Core objects.
The 4.0 experience should have these properties:
Kotlin usability.
rather than attempting to mirror the complete CycloneDX object model.
schemaVersion,projectType,organizationalEntity,licenseChoice, andexternalReferencesremain functional throughout 4.x as a deprecated compatibility facade. Removal is no earlierthan 5.0.
with actionable diagnostics rather than silent precedence.
most one migration warning per build.
remains supported for users who need the previous output contract.
Apart from explicitly documented 4.0 output-contract changes, equivalent legacy and canonical configuration must
produce equivalent parsed CycloneDX meaning. Serializer formatting and irrelevant collection ordering are not
compatibility guarantees.
Proposed DSL shape
The following examples preserve the direction discussed during planning. They are a reference for the task-local
hierarchy and migration experience, not a commitment to every identifier before Groovy and Kotlin compilation
fixtures validate the final API.
Kotlin, using plugin-owned typed values:
tasks.cyclonedxDirectBom { bom { schemaVersion(SchemaVersion.VERSION_17) projectType(ProjectType.APPLICATION) organization { name = "Example" url("https://example.com") contact { name = "Security" email = "security@example.com" } } licenses { license { id = "Apache-2.0" } } externalReference { type = ExternalReferenceType.WEBSITE url = "https://example.com/project" } } }Groovy, demonstrating the permanent normalized string aliases:
The same
bomblock is available oncyclonedxBom. It owns schema selection, the main component, and MetadataEnrichment only. Dependency selection, project discovery, aggregation membership, outputs, and root-to-member
relationships remain outside this block.
Architecture outcome
ADR 0003;
no shared root-owned plugin extension is introduced.
only at the compatibility boundary and in a one-way mapping layer used to build the SBOM.
outgoing variants, and root-to-member dependency-edge policy.
Isolation in Support Gradle Project Isolation #847. It neither implements nor competes with those issues.
task state, artifacts, aggregation members, or dependency edges.
ADR 0004.
Acceptance outcomes
legacy property.
CycloneDX Core 13 and schema 1.7.
selectors.
Out of scope