Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ plugins {
alias(libs.plugins.diffplug.spotless) apply false
alias(libs.plugins.nodegradle.node) apply false
alias(libs.plugins.openapi.generator) apply false
alias(libs.plugins.cyclonedx) apply false
alias(libs.plugins.logchange)
}

Expand Down Expand Up @@ -220,6 +221,7 @@ apply from: file('gradle/hacks/turbocharge-jvm-opts.gradle')
apply from: file('gradle/hacks/dummy-outputs.gradle')

apply from: file('gradle/solr/packaging.gradle')
apply from: file('gradle/solr/sbom.gradle')
apply from: file('gradle/solr/solr-forbidden-apis.gradle')

apply from: file('gradle/node.gradle')
Expand Down
12 changes: 12 additions & 0 deletions changelog/unreleased/cyclonedx-sboms-SOLR-17328.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# See https://github.com/apache/solr/blob/main/dev-docs/changelog.adoc

title: >
Ship a CycloneDX SBOM for the binary distributions, as bom.json in the archive root and as
solr-<version>.tgz.cdx.json next to the archive
type: added
authors:
- name: Piotr P. Karwasz
nick: ppkarwasz
links:
- name: SOLR-17328
url: https://issues.apache.org/jira/browse/SOLR-17328
5 changes: 5 additions & 0 deletions dev-docs/gradle-help/publishing.txt
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,11 @@ All distribution artifacts will be placed under:

solr/distribution/build/release

Each binary distribution carries its CycloneDX SBOM as "bom.json" in the archive root, and the
same file is published next to the archive as solr-<version>.tgz.cdx.json (and the -slim
equivalent) so that it can be fetched without downloading the distribution. Both get a checksum
and, when signing is enabled, a signature, like every other release artifact.

Artifact signing is optional (but required if you're really making a release).


Expand Down
51 changes: 26 additions & 25 deletions dev-tools/scripts/smokeTestRelease.py
Original file line number Diff line number Diff line change
Expand Up @@ -237,18 +237,15 @@ def checkAllJARs(topDir, gitRevision, version):
def checkSigs(urlString, version, tmpDir, isSigned, keysFile):
print(' test basics...')
ents = getDirEntries(urlString)
artifact = None
changesURL = None
openApiURL = None
mavenURL = None
dockerURL = None
artifactURL = None
expectedSigs = []
if isSigned:
expectedSigs.append('asc')
expectedSigs.extend(['sha512'])
sigs = []
artifacts = []
candidates = []

for text, subURL in ents:
if text == '.gitrev':
Expand All @@ -267,31 +264,35 @@ def checkSigs(urlString, version, tmpDir, isSigned, keysFile):
if text not in ('openApi/', 'openApi-%s/' % version):
raise RuntimeError('solr: found %s vs expected openApi-%s/' % (text, version))
openApiURL = subURL
elif artifact is None:
artifact = text
artifactURL = subURL
else:
candidates.append((text, subURL))

# Split the remaining entries into artifacts and the signatures that belong to them.
# An entry is a signature if its file name is the name of another artifact with a signature extension.
names = {text for text, subURL in candidates}
artifacts = []
sigs = {}
for text, subURL in candidates:
for ext in expectedSigs:
if text.endswith('.' + ext) and text[:-(len(ext) + 1)] in names:
sigs.setdefault(text[:-(len(ext) + 1)], []).append(ext)
break
else:
expected = 'solr-%s' % version
if not artifact.startswith(expected):
if not text.startswith(expected):
raise RuntimeError('solr: unknown artifact %s: expected prefix %s' % (text, expected))
sigs = []
elif text.startswith(artifact + '.'):
sigs.append(subURL.rsplit(".")[-1:][0])
else:
if sigs != expectedSigs:
raise RuntimeError('solr: artifact %s has wrong sigs: expected %s but got %s' % (artifact, expectedSigs, sigs))
artifacts.append((artifact, artifactURL))
artifact = text
artifactURL = subURL
sigs = []

if sigs != []:
artifacts.append((artifact, artifactURL))
if sigs != expectedSigs:
raise RuntimeError('solr: artifact %s has wrong sigs: expected %s but got %s' % (artifact, expectedSigs, sigs))
artifacts.append((text, subURL))

for artifact, subURL in artifacts: # pylint: disable=redefined-argument-from-local
actualSigs = sorted(sigs.get(artifact, []))
if actualSigs != expectedSigs:
raise RuntimeError('solr: artifact %s has wrong sigs: expected %s but got %s' % (artifact, expectedSigs, actualSigs))

expected = ['solr-%s-src.tgz' % version,
'solr-%s.tgz' % version,
'solr-%s-slim.tgz' % version]
'solr-%s-slim.tgz' % version,
'solr-%s.tgz.cdx.json' % version,
'solr-%s-slim.tgz.cdx.json' % version]

actual = [x[0] for x in artifacts]
expected.sort()
Expand Down Expand Up @@ -395,7 +396,7 @@ def testOpenApi(version, openApiDirUrl):
specFound = True

if not specFound:
raise RuntimeError('Did not see %s in %s' % expectedSpecFileName, openApiDirUrl)
raise RuntimeError('Did not see %s in %s' % (expectedSpecFileName, openApiDirUrl))


def testChangelogMd(dir, version):
Expand Down
4 changes: 4 additions & 0 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,9 @@ commons-io = "2.22.0"
compose = "1.11.1"
cuvs-java = "26.06.0"
cuvs-lucene = "25.12.0"
cyclonedx = "3.0.2"
# @keep npm tool generating the SBOM of the OpenAPI JS client, installed by :solr:webapp:js-client
Comment thread
ppkarwasz marked this conversation as resolved.
cyclonedx-npm = "6.0.0"
decompose = "3.5.0"
diffplug-spotless = "8.7.0"
# @keep Use for dockerfile JRE version
Expand Down Expand Up @@ -203,6 +206,7 @@ xerial-snappy = "1.1.10.8"
[plugins]
benmanes-versions = { id = "com.github.ben-manes.versions", version.ref = "benmanes-versions" }
compose-compiler = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" }
cyclonedx = { id = "org.cyclonedx.bom", version.ref = "cyclonedx" }
diffplug-spotless = { id = "com.diffplug.spotless", version.ref = "diffplug-spotless" }
jetbrains-compose = { id = "org.jetbrains.compose", version.ref = "compose" }
kotlin-multiplatform = { id = "org.jetbrains.kotlin.multiplatform", version.ref = "kotlin" }
Expand Down
4 changes: 4 additions & 0 deletions gradle/solr/packaging.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,10 @@ configure(allprojects
return true
}
}
// A copied configuration inherits neither the consistent resolution nor the lock state of
// its source, so realign it: without this the module ships whichever versions it resolves
// on its own, which are not the ones that were tested (and not the ones the SBOM lists).
alignWithRuntimeClasspath(externalLibs)
return externalLibs - configurations.solrPlatformLibs
}, {
into "lib"
Expand Down
Loading
Loading