blob: 5c8a5da90a7ec923b94137425601c9d6d63c5a28 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package publishing
import asf.AsfProject
import io.github.gradlenexus.publishplugin.NexusPublishExtension
import io.github.gradlenexus.publishplugin.NexusPublishPlugin
import io.github.gradlenexus.publishplugin.internal.StagingRepositoryDescriptorRegistryBuildService
import org.gradle.api.Project
import org.gradle.api.services.BuildServiceRegistration
import org.gradle.api.tasks.Exec
import org.gradle.kotlin.dsl.apply
import org.gradle.kotlin.dsl.named
import org.gradle.kotlin.dsl.register
/**
* Configures Apache project specific publishing tasks on the root project, for example the
* source-tarball related tasks.
*/
internal fun configureOnRootProject(project: Project) =
project.run {
apply<NexusPublishPlugin>()
val isRelease = project.hasProperty("release")
val sourceTarball = tasks.register<Exec>("sourceTarball")
sourceTarball.configure {
group = "build"
description =
"Generate a source tarball for a release to be uploaded to dist.apache.org/repos/dist"
val e = project.extensions.getByType(PublishingHelperExtension::class.java)
doFirst { mkdir(e.distributionDir) }
executable = "git"
args(
"archive",
"--prefix=${e.baseName.get()}/",
"--format=tar.gz",
// use a fixed mtime for reproducible tarballs, using the same timestamp as jars do
"--mtime=1980-02-01 00:00:00",
"--output=${e.sourceTarball.get().asFile.relativeTo(projectDir)}",
"HEAD",
)
workingDir(project.projectDir)
outputs.file(e.sourceTarball)
}
val digestSourceTarball =
tasks.register<GenerateDigest>("digestSourceTarball") {
description = "Generate the source tarball digest"
mustRunAfter(sourceTarball)
file.set {
val e = project.extensions.getByType(PublishingHelperExtension::class.java)
e.sourceTarball.get().asFile
}
}
sourceTarball.configure { finalizedBy(digestSourceTarball) }
signTaskOutputs(sourceTarball)
val releaseEmailTemplate = tasks.register("releaseEmailTemplate")
releaseEmailTemplate.configure {
group = "publishing"
description =
"Generate release-vote email subject + body, including the staging repository URL, if run during the Maven release."
mustRunAfter("initializeApacheStagingRepository")
doFirst {
val e = project.extensions.getByType(PublishingHelperExtension::class.java)
val asfName = e.asfProjectId.get()
val gitCommitId = GitInfo.memoized(rootProject).gitHead
val repos = project.extensions.getByType(NexusPublishExtension::class.java).repositories
val repo = repos.iterator().next()
val stagingRepositoryUrlRegistryRegistration =
gradle.sharedServices.registrations.named<
BuildServiceRegistration<StagingRepositoryDescriptorRegistryBuildService, *>
>(
"stagingRepositoryUrlRegistry"
)
val staginRepoUrl =
if (stagingRepositoryUrlRegistryRegistration.isPresent) {
val stagingRepositoryUrlRegistryBuildServiceRegistration =
stagingRepositoryUrlRegistryRegistration.get()
val stagingRepositoryUrlRegistryService =
stagingRepositoryUrlRegistryBuildServiceRegistration.getService()
if (stagingRepositoryUrlRegistryService.isPresent) {
val registry = stagingRepositoryUrlRegistryService.get().registry
try {
val stagingRepoDesc = registry.get(repo.name)
val stagingRepoId = stagingRepoDesc.stagingRepositoryId
"https://repository.apache.org/content/repositories/$stagingRepoId/"
} catch (e: IllegalStateException) {
"NO STAGING REPOSITORY ($e)"
}
} else {
"NO STAGING REPOSITORY (no registry service) !!"
}
} else {
"NO STAGING REPOSITORY (no build service) !!"
}
val asfProject = AsfProject.memoized(project, asfName)
val asfProjectName =
e.overrideName.orElse(project.provider { "Apache ${asfProject.name}" }).get()
val versionNoRc = version.toString().replace("-rc-?[0-9]+".toRegex(), "")
val subjectFile = e.distributionFile("vote-email-subject.txt").relativeTo(projectDir)
val bodyFile = e.distributionFile("vote-email-body.txt").relativeTo(projectDir)
val emailSubject = "[VOTE] Release $asfProjectName $version"
subjectFile.writeText(emailSubject)
val emailBody =
"""
Hi everyone,
I propose that we release the following RC as the official
$asfProjectName $versionNoRc release.
* This corresponds to the tag: apache-$asfName-$version
* https://github.com/apache/$asfName/commits/apache-$asfName-$version
* https://github.com/apache/$asfName/tree/$gitCommitId
The release tarball, signature, and checksums are here:
* https://dist.apache.org/repos/dist/dev/incubator/$asfName/apache-$asfName-$version
You can find the KEYS file here:
* https://downloads.apache.org/incubator/$asfName/KEYS
Convenience binary artifacts are staged on Nexus. The Maven repository URL is:
* $staginRepoUrl
Please download, verify, and test.
Please vote in the next 72 hours.
[ ] +1 Release this as Apache $asfName $version
[ ] +0
[ ] -1 Do not release this because...
Only PPMC members and mentors have binding votes, but other community members are
encouraged to cast non-binding votes. This vote will pass if there are
3 binding +1 votes and more binding +1 votes than -1 votes.
NB: if this vote pass, a new vote has to be started on the Incubator general mailing
list.
Thanks
Regards
"""
logger.lifecycle(
"""
The email for your release vote mail:
-------------------------------------
Suggested subject: (also in file $subjectFile)
$emailSubject
Suggested body: (also in file $bodyFile)
$emailBody
"""
.trimIndent()
)
bodyFile.writeText(emailBody.trimIndent())
}
}
if (isRelease) {
sourceTarball.configure { finalizedBy(releaseEmailTemplate) }
}
afterEvaluate {
tasks.named("closeApacheStagingRepository") { mustRunAfter(releaseEmailTemplate) }
}
}