diff --git a/dev-tools/scripts/smokeTestRelease.py b/dev-tools/scripts/smokeTestRelease.py index 554c664559d..3d57f6d98f9 100755 --- a/dev-tools/scripts/smokeTestRelease.py +++ b/dev-tools/scripts/smokeTestRelease.py @@ -220,6 +220,7 @@ def checkSigs(urlString, version, tmpDir, isSigned, keysFile): ents = getDirEntries(urlString) artifact = None changesURL = None + openApiURL = None mavenURL = None dockerURL = None artifactURL = None @@ -243,6 +244,10 @@ def checkSigs(urlString, version, tmpDir, isSigned, keysFile): if text not in ('changes/', 'changes-%s/' % version): raise RuntimeError('solr: found %s vs expected changes-%s/' % (text, version)) changesURL = subURL + elif text.startswith('openApi'): + 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 @@ -296,6 +301,12 @@ def checkSigs(urlString, version, tmpDir, isSigned, keysFile): raise RuntimeError('solr is missing changes-%s' % version) testChanges(version, changesURL) + if openApiURL is None: + stopGpgAgent(gpgHomeDir, logfile) + raise RuntimeError('solr is missing OpenAPI specification' % version) + testOpenApi(version, openApiURL) + + for artifact, urlString in artifacts: # pylint: disable=redefined-argument-from-local print(' download %s...' % artifact) scriptutil.download(artifact, urlString, tmpDir, force_clean=FORCE_CLEAN) @@ -349,6 +360,17 @@ def testChanges(version, changesURLString): s = load(changesURL) checkChangesContent(s, version, changesURL, True) +def testOpenApi(version, openApiDirUrl): + print(' check OpenAPI specification...') + specFound = False + expectedSpecFileName = 'solr-openapi-' + version + '.json' + for text, subURL in getDirEntries(openApiDirUrl): + if text == expectedSpecFileName: + specFound = True + + if not specFound: + raise RuntimeError('Did not see %s in %s' % expectedSpecFileName, openApiDirUrl) + def testChangesText(dir, version): "Checks all CHANGES.txt under this dir." diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt index 2fd94304a24..9505b2c6f53 100644 --- a/solr/CHANGES.txt +++ b/solr/CHANGES.txt @@ -171,6 +171,9 @@ Other Changes * SOLR-16949: Restrict certain file types from being uploaded to or downloaded from Config Sets (janhoy, Houston Putman) +* SOLR-16880: Solr now produces an OpenAPI Specification artifact on releases ("solr-openapi-x.y.z.json") that covers + Solr's v2 APIs. (Jason Gerlowski, Houston Putman) + ================== 9.4.0 ================== New Features --------------------- diff --git a/solr/api/build.gradle b/solr/api/build.gradle index ecd93125e86..bbcf66170e1 100644 --- a/solr/api/build.gradle +++ b/solr/api/build.gradle @@ -28,7 +28,7 @@ ext { jsClientDir = "${buildDir}/generated/js" pythonClientDir = "${buildDir}/generated/python" openApiSpecDir = "${buildDir}/generated/openapi" - openApiSpecFile = "${project.openApiSpecDir}/openapi.json" + openApiSpecFile = "${project.openApiSpecDir}/solr-openapi-${version}.json" } configurations { @@ -50,6 +50,7 @@ resolve { classpath = sourceSets.main.runtimeClasspath resourcePackages = ["org.apache.solr.client.api.util", "org.apache.solr.client.api.endpoint"] outputDir = file(project.openApiSpecDir) + outputFileName = "solr-openapi-${version}" prettyPrint = true } @@ -91,7 +92,7 @@ tasks.withType(org.openapitools.generator.gradle.plugin.tasks.GenerateTask) { artifacts { // Ensure the OAS is available to other modules who want to generate code (i.e. solrj) - openapiSpec resolve.outputDir, { + openapiSpec file(openApiSpecFile), { builtBy resolve } diff --git a/solr/distribution/build.gradle b/solr/distribution/build.gradle index d1ad6b62256..8ebc5872f53 100644 --- a/solr/distribution/build.gradle +++ b/solr/distribution/build.gradle @@ -54,11 +54,13 @@ apply from: buildscript.sourceFile.toPath().resolveSibling("source-release.gradl // Set up the HTML-rendered "changes" distribution artifact by linking to documentation's output. configurations { changesHtml + openApiSpecFile docker } dependencies { changesHtml project(path: ":solr:documentation", configuration: "changesHtml") + openApiSpecFile project(path: ":solr:api", configuration: "openapiSpec") docker project(path: ':solr:docker', configuration: 'packagingOfficial') } @@ -73,11 +75,13 @@ task computeChecksums(type: Checksum) { [ tasks.assembleSourceTgz, fullDistTarTask, - slimDistTarTask, + slimDistTarTask ].each { dep -> dependsOn dep files += dep.outputs.files } + dependsOn configurations.openApiSpecFile + files += configurations.openApiSpecFile outputDir = file("${buildDir}/checksums") } @@ -93,11 +97,19 @@ task signSourceTgz(type: Sign) { dependsOn tasks.assembleSourceTgz sign tasks.assembleSourceTgz.destination } +task signOpenApiSpec(type: Sign) { + dependsOn configurations.openApiSpecFile + // This is not an artifact, so we need to use "file" not "configuration" signing + doFirst { + sign configurations.openApiSpecFile.singleFile + } +} task signReleaseArchives(type: Sync) { from tasks.signFullBinaryTgz from tasks.signSlimBinaryTgz from tasks.signSourceTgz + from tasks.signOpenApiSpec into "${buildDir}/signatures" } @@ -125,6 +137,10 @@ task assembleRelease(type: Sync) { into "changes" }) + from(configurations.openApiSpecFile, { + into "openApi" + }) + from(configurations.docker, { include 'Dockerfile.official*' into "docker" @@ -139,11 +155,24 @@ task assembleRelease(type: Sync) { from fullDistTarTask from slimDistTarTask - from tasks.computeChecksums + from(tasks.computeChecksums, { + exclude { it.file.getName().contains("openapi") } + }) + from(tasks.computeChecksums, { + include { it.file.getName().contains("openapi") } + into "openApi" + }) // Conditionally, attach signatures of all the release archives. if (project.ext.withSignedArtifacts) { - from tasks.signReleaseArchives + from(tasks.signReleaseArchives, { + exclude { it.file.getName().contains("openapi") } + }) + + from(tasks.signReleaseArchives, { + include { it.file.getName().contains("openapi") } + into "openApi" + }) } into releaseDir