mirror of
https://github.com/mamoe/mirai.git
synced 2024-12-28 09:30:10 +08:00
GPG sign for artifacts
This commit is contained in:
parent
3a8003057a
commit
d37675f5c2
5
.gitignore
vendored
5
.gitignore
vendored
@ -45,4 +45,7 @@ keys.properties
|
||||
|
||||
token.txt
|
||||
bintray.user.txt
|
||||
bintray.key.txt
|
||||
bintray.key.txt
|
||||
|
||||
# For gpg sign
|
||||
/build-gpg-sign
|
||||
|
@ -64,6 +64,7 @@ configure<kotlinx.validation.ApiValidationExtension> {
|
||||
}
|
||||
|
||||
project.ext.set("isAndroidSDKAvailable", false)
|
||||
GpgSigner.setup(project)
|
||||
|
||||
tasks.register("publishMiraiCoreArtifactsToMavenLocal") {
|
||||
group = "mirai"
|
||||
|
100
buildSrc/src/main/kotlin/GpgSigner.kt
Normal file
100
buildSrc/src/main/kotlin/GpgSigner.kt
Normal file
@ -0,0 +1,100 @@
|
||||
/*
|
||||
* Copyright 2019-2021 Mamoe Technologies and contributors.
|
||||
*
|
||||
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
|
||||
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
|
||||
*
|
||||
* https://github.com/mamoe/mirai/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
|
||||
import org.gradle.api.Project
|
||||
import java.io.File
|
||||
|
||||
open class GpgSigner(private val workdir: File) {
|
||||
private val workdirParent by lazy { workdir.parentFile ?: error("Assertion error: No parent file of $workdir") }
|
||||
private val workdirName by lazy { workdir.name }
|
||||
|
||||
fun verbose(msg: String) {
|
||||
println("[GPG SIGN] [Verbose] $msg")
|
||||
}
|
||||
|
||||
@Suppress("RemoveExplicitTypeArguments")
|
||||
private val verbosePrintOnce by lazy<Unit> {
|
||||
verbose("GPG Signer working dir: $workdir")
|
||||
verbose("GPG command working dir: $workdirParent")
|
||||
}
|
||||
|
||||
constructor(workdir: String) : this(File(workdir))
|
||||
|
||||
object NoopSigner : GpgSigner("build/gpg-noop") {
|
||||
override fun processGpg(vararg cmds: String) {
|
||||
}
|
||||
|
||||
override fun importKey(file: File) {
|
||||
}
|
||||
|
||||
override fun doSign(file: File) {
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private var initialized: Boolean = false
|
||||
var signer: GpgSigner = NoopSigner
|
||||
fun setup(project: Project) {
|
||||
if (initialized) return
|
||||
initialized = true
|
||||
val rootProject = project.rootProject
|
||||
val gpg = rootProject.projectDir.resolve("build-gpg-sign")
|
||||
gpg.mkdirs()
|
||||
val keyFile = gpg.resolve("keys.gpg")
|
||||
if (keyFile.isFile) {
|
||||
val homedir = gpg.resolve("homedir")
|
||||
signer = GpgSigner(homedir.absolutePath)
|
||||
if (!homedir.resolve("pubring.kbx").isFile) {
|
||||
signer.importKey(keyFile)
|
||||
}
|
||||
} else {
|
||||
rootProject.logger.warn("GPG Key not found.")
|
||||
rootProject.logger.warn("GPG Signer will not setup")
|
||||
rootProject.logger.warn("Key file location: $keyFile")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
open fun processGpg(
|
||||
vararg cmds: String
|
||||
) {
|
||||
workdir.mkdirs()
|
||||
verbosePrintOnce
|
||||
|
||||
val response = ProcessBuilder().command(ArrayList<String>().apply {
|
||||
add("gpg")
|
||||
add("--homedir"); add(workdirName)
|
||||
addAll(cmds)
|
||||
}.also {
|
||||
verbose("Processing " + it.joinToString(" "))
|
||||
}).directory(workdirParent)
|
||||
.inheritIO()
|
||||
.start()
|
||||
.waitFor()
|
||||
if (response != 0) {
|
||||
error("Exit Response $response")
|
||||
}
|
||||
}
|
||||
|
||||
open fun importKey(file: File) {
|
||||
processGpg("--batch", "--import", file.toString())
|
||||
}
|
||||
|
||||
open fun doSign(file: File) {
|
||||
if (!file.isFile) {
|
||||
println("[GPG SIGN] $file not a file")
|
||||
return
|
||||
}
|
||||
println("[GPG SIGN] Signing $file")
|
||||
File("${file.path}.asc").delete()
|
||||
processGpg("-a", "--batch", "--no-tty", "--sign", file.toString())
|
||||
}
|
||||
|
||||
}
|
@ -115,5 +115,6 @@ inline fun Project.configurePublishing(
|
||||
artifact(sourcesJar.get())
|
||||
}
|
||||
}
|
||||
configGpgSign(this@configurePublishing)
|
||||
}
|
||||
}
|
@ -42,10 +42,13 @@ fun Project.configureMppPublishing() {
|
||||
.forEach { publication ->
|
||||
val moduleFile = buildDir.resolve("publications/${publication.name}/module.json")
|
||||
if (moduleFile.exists()) {
|
||||
publication.artifact(object :
|
||||
val artifact = (object :
|
||||
org.gradle.api.publish.maven.internal.artifact.FileBasedMavenArtifact(moduleFile) {
|
||||
override fun getDefaultExtension() = "module"
|
||||
})
|
||||
publication.artifact(artifact)
|
||||
GpgSigner.signer.doSign(moduleFile)
|
||||
publication.artifact(GPGSignMavenArtifact(artifact))
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -86,6 +89,7 @@ fun Project.configureMppPublishing() {
|
||||
}
|
||||
}
|
||||
}
|
||||
configGpgSign(this@configureMppPublishing)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -129,6 +133,6 @@ val publishPlatformArtifactsInRootModule: Project.(MavenPublication) -> Unit = {
|
||||
}
|
||||
}
|
||||
|
||||
private fun MavenArtifact.smartToString(): String {
|
||||
public fun MavenArtifact.smartToString(): String {
|
||||
return "${file.path}, classifier=${classifier}, ext=${extension}"
|
||||
}
|
||||
|
102
buildSrc/src/main/kotlin/PublishingGpgSign.kt
Normal file
102
buildSrc/src/main/kotlin/PublishingGpgSign.kt
Normal file
@ -0,0 +1,102 @@
|
||||
/*
|
||||
* Copyright 2019-2021 Mamoe Technologies and contributors.
|
||||
*
|
||||
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
|
||||
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
|
||||
*
|
||||
* https://github.com/mamoe/mirai/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.internal.tasks.DefaultTaskDependency
|
||||
import org.gradle.api.internal.tasks.TaskDependencyInternal
|
||||
import org.gradle.api.publish.PublishingExtension
|
||||
import org.gradle.api.publish.maven.MavenArtifact
|
||||
import org.gradle.api.publish.maven.MavenPublication
|
||||
import org.gradle.api.publish.maven.internal.artifact.AbstractMavenArtifact
|
||||
import org.gradle.api.publish.maven.internal.publication.DefaultMavenPublication
|
||||
import java.io.File
|
||||
|
||||
open class GPGSignMavenArtifact(
|
||||
private val delegate: MavenArtifact,
|
||||
private val tasks: TaskDependencyInternal = TaskDependencyInternal.EMPTY
|
||||
) : AbstractMavenArtifact() {
|
||||
override fun getFile(): File {
|
||||
return File(delegate.file.path + ".asc")
|
||||
}
|
||||
|
||||
override fun shouldBePublished(): Boolean = (delegate as? AbstractMavenArtifact)?.shouldBePublished() ?: true
|
||||
override fun getDefaultExtension(): String = delegate.extension + ".asc"
|
||||
override fun getDefaultClassifier(): String = delegate.classifier ?: ""
|
||||
override fun getDefaultBuildDependencies(): TaskDependencyInternal = tasks
|
||||
}
|
||||
|
||||
class NameCounter(val name: String) {
|
||||
var counter = 0
|
||||
val nextName: String
|
||||
get() = name + if (counter == 0) {
|
||||
counter = 1; ""
|
||||
} else {
|
||||
counter++; counter
|
||||
}
|
||||
}
|
||||
|
||||
object PublishingAccess {
|
||||
fun getMetadataArtifacts(publication: MavenPublication): Collection<MavenArtifact> {
|
||||
if (publication is DefaultMavenPublication) {
|
||||
return DefaultMavenPublication::class.java.getDeclaredField("metadataArtifacts")
|
||||
.also { it.isAccessible = true }
|
||||
.get(publication) as Collection<MavenArtifact>
|
||||
}
|
||||
return emptyList()
|
||||
}
|
||||
}
|
||||
|
||||
fun PublishingExtension.configGpgSign(project: Project) {
|
||||
if (GpgSigner.signer === GpgSigner.NoopSigner) {
|
||||
return
|
||||
}
|
||||
val tasks = DefaultTaskDependency()
|
||||
val signArtifactsGPG = NameCounter("signArtifactsGPG")
|
||||
|
||||
publications.forEach { publication ->
|
||||
if (publication is MavenPublication) {
|
||||
val artifacts0: Collection<Pair<Collection<MavenArtifact>, (MavenArtifact) -> Unit>> = listOf(
|
||||
publication.artifacts to { publication.artifact(it) }, // main artifacts
|
||||
PublishingAccess.getMetadataArtifacts(publication).let { artifacts -> // pom files
|
||||
if (artifacts is MutableCollection<MavenArtifact>) {
|
||||
artifacts to { artifacts.add(it) }
|
||||
} else {
|
||||
artifacts to { publication.artifact(it) }
|
||||
}
|
||||
}
|
||||
)
|
||||
val allArtifacts = artifacts0.flatMap { it.first }.toList()
|
||||
|
||||
if (allArtifacts.isNotEmpty()) {
|
||||
tasks.add(project.tasks.create(signArtifactsGPG.nextName) {
|
||||
group = "publishing"
|
||||
doLast {
|
||||
allArtifacts.forEach { artifact ->
|
||||
if ((artifact as? AbstractMavenArtifact)?.shouldBePublished() != false) {
|
||||
GpgSigner.signer.doSign(artifact.file)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
allArtifacts.forEach {
|
||||
dependsOn(it.buildDependencies)
|
||||
}
|
||||
})
|
||||
|
||||
artifacts0.forEach { (artifacts, artifactsRegister) ->
|
||||
artifacts.toList().forEach { artifact ->
|
||||
logPublishing("gpg sign for artifact ${artifact.smartToString()}")
|
||||
artifactsRegister(GPGSignMavenArtifact(artifact, tasks))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -12,7 +12,7 @@
|
||||
import org.gradle.api.attributes.Attribute
|
||||
|
||||
object Versions {
|
||||
const val project = "2.3.2"
|
||||
const val project = "2.3.2-dev-publish-1"
|
||||
|
||||
const val core = project
|
||||
const val console = project
|
||||
|
Loading…
Reference in New Issue
Block a user