mirror of
https://github.com/mamoe/mirai.git
synced 2025-03-10 20:20:08 +08:00
commit
8b0694c7e3
123
.github/workflows/bintray.yml
vendored
123
.github/workflows/bintray.yml
vendored
@ -1,123 +0,0 @@
|
||||
# This is a basic workflow to help you get started with Actions
|
||||
|
||||
name: Bintray Publish
|
||||
|
||||
# Controls when the action will run. Triggers the workflow on push or pull request
|
||||
# events but only for the master branch
|
||||
on:
|
||||
release:
|
||||
types: [ created ]
|
||||
push:
|
||||
tags:
|
||||
- '*-dev*'
|
||||
|
||||
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
|
||||
jobs:
|
||||
# This workflow contains a single job called "build"
|
||||
publish-mirai:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Checkout submodules
|
||||
run: git submodule update --init --recursive --remote
|
||||
|
||||
- name: Set up JDK 1.8
|
||||
uses: actions/setup-java@v1
|
||||
with:
|
||||
java-version: 1.8
|
||||
|
||||
- name: chmod -R 777 *
|
||||
run: chmod -R 777 *
|
||||
|
||||
- name: Init gradle project
|
||||
run: ./gradlew clean --scan
|
||||
|
||||
- name: Check keys
|
||||
run: >
|
||||
./gradlew :mirai-core-utils:ensureBintrayAvailable
|
||||
:mirai-core-api:ensureBintrayAvailable
|
||||
:mirai-core:ensureBintrayAvailable
|
||||
:mirai-console:ensureBintrayAvailable
|
||||
-Dbintray_user=${{ secrets.BINTRAY_USER }} -Pbintray_user=${{ secrets.BINTRAY_USER }}
|
||||
-Dbintray_key=${{ secrets.BINTRAY_KEY }} -Pbintray_key=${{ secrets.BINTRAY_KEY }}
|
||||
|
||||
- name: fillBuildConstants
|
||||
run: >
|
||||
./gradlew
|
||||
fillBuildConstants --scan
|
||||
-Dbintray_user=${{ secrets.BINTRAY_USER }} -Pbintray_user=${{ secrets.BINTRAY_USER }}
|
||||
-Dbintray_key=${{ secrets.BINTRAY_KEY }} -Pbintray_key=${{ secrets.BINTRAY_KEY }}
|
||||
|
||||
- name: Assemble
|
||||
run: ./gradlew assemble --scan
|
||||
|
||||
- name: Check
|
||||
run: ./gradlew check --scan
|
||||
|
||||
- name: Gradle :mirai-core-utils:publish
|
||||
run: >
|
||||
./gradlew :mirai-core-utils:publish --scan
|
||||
-Dbintray_user=${{ secrets.BINTRAY_USER }} -Pbintray_user=${{ secrets.BINTRAY_USER }}
|
||||
-Dbintray_key=${{ secrets.BINTRAY_KEY }} -Pbintray_key=${{ secrets.BINTRAY_KEY }}
|
||||
|
||||
- name: Gradle :mirai-core-api:publish
|
||||
run: >
|
||||
./gradlew :mirai-core-api:publish --scan
|
||||
-Dbintray_user=${{ secrets.BINTRAY_USER }} -Pbintray_user=${{ secrets.BINTRAY_USER }}
|
||||
-Dbintray_key=${{ secrets.BINTRAY_KEY }} -Pbintray_key=${{ secrets.BINTRAY_KEY }}
|
||||
|
||||
- name: Gradle :mirai-core:publish
|
||||
run: >
|
||||
./gradlew :mirai-core:publish --scan
|
||||
-Dbintray_user=${{ secrets.BINTRAY_USER }} -Pbintray_user=${{ secrets.BINTRAY_USER }}
|
||||
-Dbintray_key=${{ secrets.BINTRAY_KEY }} -Pbintray_key=${{ secrets.BINTRAY_KEY }}
|
||||
|
||||
- name: Gradle :mirai-core-all:bintrayUpload
|
||||
run: >
|
||||
./gradlew :mirai-core-all:bintrayUpload --info
|
||||
-Dbintray_user=${{ secrets.BINTRAY_USER }} -Pbintray_user=${{ secrets.BINTRAY_USER }}
|
||||
-Dbintray_key=${{ secrets.BINTRAY_KEY }} -Pbintray_key=${{ secrets.BINTRAY_KEY }}
|
||||
|
||||
- name: Gradle :mirai-console:bintrayUpload
|
||||
run: >
|
||||
./gradlew
|
||||
:mirai-console:bintrayUpload --info
|
||||
-Dbintray_user=${{ secrets.BINTRAY_USER }} -Pbintray_user=${{ secrets.BINTRAY_USER }}
|
||||
-Dbintray_key=${{ secrets.BINTRAY_KEY }} -Pbintray_key=${{ secrets.BINTRAY_KEY }}
|
||||
|
||||
- name: Gradle :mirai-console-terminal:bintrayUpload
|
||||
run: >
|
||||
./gradlew
|
||||
:mirai-console-terminal:bintrayUpload --info
|
||||
-Dbintray_user=${{ secrets.BINTRAY_USER }} -Pbintray_user=${{ secrets.BINTRAY_USER }}
|
||||
-Dbintray_key=${{ secrets.BINTRAY_KEY }} -Pbintray_key=${{ secrets.BINTRAY_KEY }}
|
||||
|
||||
- name: Gradle :mirai-console-compiler-common:bintrayUpload
|
||||
run: >
|
||||
./gradlew
|
||||
:mirai-console-compiler-common:bintrayUpload --info
|
||||
-Dbintray_user=${{ secrets.BINTRAY_USER }} -Pbintray_user=${{ secrets.BINTRAY_USER }}
|
||||
-Dbintray_key=${{ secrets.BINTRAY_KEY }} -Pbintray_key=${{ secrets.BINTRAY_KEY }}
|
||||
|
||||
- name: Gradle :mirai-console-compiler-annotations:bintrayUpload
|
||||
run: >
|
||||
./gradlew
|
||||
:mirai-console-compiler-annotations:bintrayUpload --info
|
||||
-Dbintray_user=${{ secrets.BINTRAY_USER }} -Pbintray_user=${{ secrets.BINTRAY_USER }}
|
||||
-Dbintray_key=${{ secrets.BINTRAY_KEY }} -Pbintray_key=${{ secrets.BINTRAY_KEY }}
|
||||
|
||||
# - name: Gradle :mirai-console-intellij:bintrayUpload
|
||||
# run: >
|
||||
# ./gradlew
|
||||
# :mirai-console-intellij:bintrayUpload --info
|
||||
# -Dbintray_user=${{ secrets.BINTRAY_USER }} -Pbintray_user=${{ secrets.BINTRAY_USER }}
|
||||
# -Dbintray_key=${{ secrets.BINTRAY_KEY }} -Pbintray_key=${{ secrets.BINTRAY_KEY }}
|
||||
|
||||
- name: Publish Gradle plugin
|
||||
run: >
|
||||
./gradlew
|
||||
:mirai-console-gradle:publishPlugins --scan
|
||||
-Dgradle.publish.key=${{ secrets.GRADLE_PUBLISH_KEY }} -Pgradle.publish.key=${{ secrets.GRADLE_PUBLISH_KEY }}
|
||||
-Dgradle.publish.secret=${{ secrets.GRADLE_PUBLISH_SECRET }} -Pgradle.publish.secret=${{ secrets.GRADLE_PUBLISH_SECRET }}
|
125
.github/workflows/release.yml
vendored
Normal file
125
.github/workflows/release.yml
vendored
Normal file
@ -0,0 +1,125 @@
|
||||
# This is a basic workflow to help you get started with Actions
|
||||
|
||||
name: Release Publish
|
||||
|
||||
# Controls when the action will run. Triggers the workflow on push or pull request
|
||||
# events but only for the master branch
|
||||
on:
|
||||
release:
|
||||
types: [ created ]
|
||||
push:
|
||||
tags:
|
||||
- '*-dev*'
|
||||
|
||||
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
|
||||
jobs:
|
||||
# This workflow contains a single job called "build"
|
||||
publish-mirai:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Checkout submodules
|
||||
run: git submodule update --init --recursive --remote
|
||||
|
||||
- name: Set up JDK 1.8
|
||||
uses: actions/setup-java@v1
|
||||
with:
|
||||
java-version: 1.8
|
||||
|
||||
- name: chmod -R 777 *
|
||||
run: chmod -R 777 *
|
||||
|
||||
- name: Keys setup
|
||||
shell: bash
|
||||
run: |
|
||||
mkdir build-gpg-sign
|
||||
echo "$GPG_PRIVATE" > build-gpg-sign/keys.gpg
|
||||
echo "$GPG_PUBLIC_" > build-gpg-sign/keys.gpg.pub
|
||||
mkdir build-secret-keys
|
||||
echo "$SONATYPE_USER" > build-secret-keys/sonatype.key
|
||||
echo "$SONATYPE_KEY" >> build-secret-keys/sonatype.key
|
||||
echo "$BINTRAY_USER" > build-secret-keys/bintray.key
|
||||
echo "$BINTRAY_KEY" >> build-secret-keys/bintray.key
|
||||
env:
|
||||
GPG_PRIVATE: ${{ secrets.GPG_PRIVATE_KEY }}
|
||||
GPG_PUBLIC_: ${{ secrets.GPG_PUBLIC_KEY }}
|
||||
SONATYPE_USER: ${{ secrets.SONATYPE_USER }}
|
||||
SONATYPE_KEY: ${{ secrets.SONATYPE_KEY }}
|
||||
BINTRAY_USER: ${{ secrets.BINTRAY_USER }}
|
||||
BINTRAY_KEY: ${{ secrets.BINTRAY_KEY }}
|
||||
|
||||
- name: Init gradle project
|
||||
run: ./gradlew clean --scan
|
||||
|
||||
- name: Check keys
|
||||
run: >
|
||||
./gradlew
|
||||
:mirai-core-utils:ensureBintrayAvailable
|
||||
:mirai-core-api:ensureBintrayAvailable
|
||||
:mirai-core:ensureBintrayAvailable
|
||||
:mirai-console:ensureBintrayAvailable
|
||||
:mirai-core-utils:ensureMavenCentralAvailable
|
||||
:mirai-core-api:ensureMavenCentralAvailable
|
||||
:mirai-core:ensureMavenCentralAvailable
|
||||
:mirai-console:ensureMavenCentralAvailable
|
||||
|
||||
- name: fillBuildConstants
|
||||
run: >
|
||||
./gradlew
|
||||
fillBuildConstants --scan
|
||||
|
||||
- name: Assemble
|
||||
run: ./gradlew assemble --scan
|
||||
|
||||
- name: Check
|
||||
run: ./gradlew check --scan
|
||||
|
||||
- name: Gradle :mirai-core-utils:publish
|
||||
run: >
|
||||
./gradlew :mirai-core-utils:publish --scan
|
||||
|
||||
- name: Gradle :mirai-core-api:publish
|
||||
run: >
|
||||
./gradlew :mirai-core-api:publish --scan
|
||||
|
||||
- name: Gradle :mirai-core:publish
|
||||
run: >
|
||||
./gradlew :mirai-core:publish --scan
|
||||
|
||||
- name: Gradle :mirai-core-all:publish
|
||||
run: >
|
||||
./gradlew :mirai-core-all:publish --info
|
||||
|
||||
- name: Gradle :mirai-console:publish
|
||||
run: >
|
||||
./gradlew
|
||||
:mirai-console:publish --info
|
||||
|
||||
- name: Gradle :mirai-console-terminal:publish
|
||||
run: >
|
||||
./gradlew
|
||||
:mirai-console-terminal:publish --info
|
||||
|
||||
- name: Gradle :mirai-console-compiler-common:publish
|
||||
run: >
|
||||
./gradlew
|
||||
:mirai-console-compiler-common:publish --info
|
||||
|
||||
- name: Gradle :mirai-console-compiler-annotations:publish
|
||||
run: >
|
||||
./gradlew
|
||||
:mirai-console-compiler-annotations:publish --info
|
||||
|
||||
- name: Publish Gradle plugin
|
||||
run: >
|
||||
./gradlew
|
||||
:mirai-console-gradle:publishPlugins --scan
|
||||
-Dgradle.publish.key=${{ secrets.GRADLE_PUBLISH_KEY }} -Pgradle.publish.key=${{ secrets.GRADLE_PUBLISH_KEY }}
|
||||
-Dgradle.publish.secret=${{ secrets.GRADLE_PUBLISH_SECRET }} -Pgradle.publish.secret=${{ secrets.GRADLE_PUBLISH_SECRET }}
|
||||
|
||||
- name: Gradle :ci-release-helper:closeAndReleaseRepository
|
||||
run: >
|
||||
./gradlew
|
||||
:ci-release-helper:closeAndReleaseRepository --info
|
7
.gitignore
vendored
7
.gitignore
vendored
@ -45,4 +45,9 @@ keys.properties
|
||||
|
||||
token.txt
|
||||
bintray.user.txt
|
||||
bintray.key.txt
|
||||
bintray.key.txt
|
||||
|
||||
# For gpg sign
|
||||
/build-gpg-sign
|
||||
# Name for IDEA direction sorting
|
||||
build-secret-keys/
|
||||
|
@ -64,6 +64,7 @@ configure<kotlinx.validation.ApiValidationExtension> {
|
||||
}
|
||||
|
||||
project.ext.set("isAndroidSDKAvailable", false)
|
||||
GpgSigner.setup(project)
|
||||
|
||||
tasks.register("publishMiraiCoreArtifactsToMavenLocal") {
|
||||
group = "mirai"
|
||||
@ -138,9 +139,14 @@ subprojects {
|
||||
|
||||
tasks.register("cleanExceptIntellij") {
|
||||
group = "build"
|
||||
allprojects.forEach {
|
||||
if (it.name != "mirai-console-intellij")
|
||||
dependsOn(it.tasks.findByName("clean"))
|
||||
allprojects.forEach { proj ->
|
||||
if (proj.name != "mirai-console-intellij") {
|
||||
|
||||
// Type mismatch
|
||||
// proj.tasks.findByName("clean")?.let(::dependsOn)
|
||||
|
||||
proj.tasks.findByName("clean")?.let { dependsOn(it) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
108
buildSrc/src/main/kotlin/GpgSigner.kt
Normal file
108
buildSrc/src/main/kotlin/GpgSigner.kt
Normal file
@ -0,0 +1,108 @@
|
||||
/*
|
||||
* 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")
|
||||
val keyFilePub = gpg.resolve("keys.gpg.pub")
|
||||
if (keyFile.isFile) {
|
||||
val homedir = gpg.resolve("homedir")
|
||||
signer = GpgSigner(homedir.absolutePath)
|
||||
if (!homedir.resolve("pubring.kbx").isFile) {
|
||||
signer.importKey(keyFile)
|
||||
if (keyFilePub.isFile) {
|
||||
signer.importKey(keyFilePub)
|
||||
} else {
|
||||
println("[GPG SIGN] Missing public key storage")
|
||||
println("[GPG SIGN] GPG Sign 2nd verity may failed.")
|
||||
}
|
||||
}
|
||||
} else {
|
||||
println("[GPG SIGN] GPG Key not found.")
|
||||
println("[GPG SIGN] GPG Signer will not setup")
|
||||
println("[GPG SIGN] 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", "--detach-sig", "--sign", file.toString())
|
||||
processGpg("--verify", "$file.asc", file.toString())
|
||||
}
|
||||
|
||||
}
|
@ -13,6 +13,7 @@
|
||||
)
|
||||
|
||||
import com.github.jengelman.gradle.plugins.shadow.ShadowPlugin
|
||||
import keys.SecretKeys
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.publish.maven.MavenPublication
|
||||
import org.gradle.api.tasks.bundling.Jar
|
||||
@ -21,17 +22,9 @@ import org.gradle.kotlin.dsl.get
|
||||
import org.gradle.kotlin.dsl.register
|
||||
import org.gradle.kotlin.dsl.registering
|
||||
|
||||
/*
|
||||
* Copyright 2020 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
|
||||
*/
|
||||
|
||||
|
||||
fun Project.configureBintray() {
|
||||
fun Project.configureRemoteRepos(
|
||||
bintrayPkgName: String = "mirai-core"
|
||||
) {
|
||||
tasks.register("ensureBintrayAvailable") {
|
||||
doLast {
|
||||
if (!project.isBintrayAvailable()) {
|
||||
@ -39,19 +32,53 @@ fun Project.configureBintray() {
|
||||
}
|
||||
}
|
||||
}
|
||||
tasks.register("ensureMavenCentralAvailable") {
|
||||
doLast {
|
||||
if (GpgSigner.signer == GpgSigner.NoopSigner) {
|
||||
error("GPG Signer isn't available.")
|
||||
}
|
||||
val keys = SecretKeys.getCache(project)
|
||||
if (!keys.loadKey("sonatype").isValid) {
|
||||
error("Maven Central isn't available.")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isBintrayAvailable()) {
|
||||
publishing {
|
||||
repositories {
|
||||
publishing {
|
||||
// sonatype
|
||||
val keys = SecretKeys.getCache(project)
|
||||
repositories {
|
||||
val sonatype = keys.loadKey("sonatype")
|
||||
if (sonatype.isValid) {
|
||||
maven {
|
||||
setUrl("https://api.bintray.com/maven/him188moe/mirai/mirai-core/;publish=1;override=1")
|
||||
name = "MavenCentral"
|
||||
// Maven Central
|
||||
setUrl("https://oss.sonatype.org/service/local/staging/deploy/maven2")
|
||||
|
||||
credentials {
|
||||
username = sonatype.user
|
||||
password = sonatype.password
|
||||
}
|
||||
}
|
||||
} else {
|
||||
println("SonaType is not available")
|
||||
}
|
||||
|
||||
|
||||
if (isBintrayAvailable()) {
|
||||
maven {
|
||||
name = "Bintray"
|
||||
setUrl("https://api.bintray.com/maven/him188moe/mirai/$bintrayPkgName/;publish=1;override=1")
|
||||
|
||||
credentials {
|
||||
username = Bintray.getUser(project)
|
||||
password = Bintray.getKey(project)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
println("bintray isn't available.")
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -63,30 +90,29 @@ inline fun Project.configurePublishing(
|
||||
bintrayPkgName: String = artifactId,
|
||||
vcs: String = "https://github.com/mamoe/mirai"
|
||||
) {
|
||||
configureBintray()
|
||||
configureRemoteRepos(
|
||||
bintrayPkgName = bintrayPkgName
|
||||
)
|
||||
apply<ShadowPlugin>()
|
||||
|
||||
if (!project.isBintrayAvailable()) {
|
||||
println("bintray isn't available. NO PUBLICATIONS WILL BE SET")
|
||||
return
|
||||
}
|
||||
if (project.isBintrayAvailable()) {
|
||||
bintray {
|
||||
user = Bintray.getUser(project)
|
||||
key = Bintray.getKey(project)
|
||||
|
||||
bintray {
|
||||
user = Bintray.getUser(project)
|
||||
key = Bintray.getKey(project)
|
||||
setPublications("mavenJava")
|
||||
setConfigurations("archives")
|
||||
|
||||
setPublications("mavenJava")
|
||||
setConfigurations("archives")
|
||||
publish = true
|
||||
override = true
|
||||
|
||||
publish = true
|
||||
override = true
|
||||
|
||||
pkg.apply {
|
||||
repo = bintrayRepo
|
||||
name = bintrayPkgName
|
||||
setLicenses("AGPLv3")
|
||||
publicDownloadNumbers = true
|
||||
vcsUrl = vcs
|
||||
pkg.apply {
|
||||
repo = bintrayRepo
|
||||
name = bintrayPkgName
|
||||
setLicenses("AGPLv3")
|
||||
publicDownloadNumbers = true
|
||||
vcsUrl = vcs
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -94,6 +120,10 @@ inline fun Project.configurePublishing(
|
||||
archiveClassifier.set("sources")
|
||||
from(sourceSets["main"].allSource)
|
||||
}
|
||||
val stubJavadoc = tasks.register("javadocJar", Jar::class) {
|
||||
@Suppress("NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS")
|
||||
archiveClassifier.set("javadoc")
|
||||
}
|
||||
|
||||
publishing {
|
||||
publications {
|
||||
@ -104,16 +134,15 @@ inline fun Project.configurePublishing(
|
||||
setArtifactId(artifactId)
|
||||
version = project.version.toString()
|
||||
|
||||
pom.withXml {
|
||||
val root = asNode()
|
||||
root.appendNode("description", description)
|
||||
root.appendNode("name", project.name)
|
||||
root.appendNode("url", vcs)
|
||||
root.children().last()
|
||||
}
|
||||
setupPom(
|
||||
project = project,
|
||||
vcs = vcs
|
||||
)
|
||||
|
||||
artifact(sourcesJar.get())
|
||||
artifact(stubJavadoc.get())
|
||||
}
|
||||
}
|
||||
configGpgSign(this@configurePublishing)
|
||||
}
|
||||
}
|
@ -21,7 +21,7 @@ fun logPublishing(message: String) {
|
||||
}
|
||||
|
||||
fun Project.configureMppPublishing() {
|
||||
configureBintray()
|
||||
configureRemoteRepos()
|
||||
|
||||
// mirai does some magic on MPP targets
|
||||
afterEvaluate {
|
||||
@ -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))
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -61,9 +64,10 @@ fun Project.configureMppPublishing() {
|
||||
logPublishing("Publications: ${publications.joinToString { it.name }}")
|
||||
|
||||
publications.filterIsInstance<MavenPublication>().forEach { publication ->
|
||||
if (publication.name != "kotlinMultiplatform") {
|
||||
publication.artifact(stubJavadoc)
|
||||
}
|
||||
// Maven Central always require javadoc.jar
|
||||
publication.artifact(stubJavadoc)
|
||||
|
||||
publication.setupPom(project)
|
||||
|
||||
logPublishing(publication.name)
|
||||
when (val type = publication.name) {
|
||||
@ -86,6 +90,7 @@ fun Project.configureMppPublishing() {
|
||||
}
|
||||
}
|
||||
}
|
||||
configGpgSign(this@configureMppPublishing)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -129,6 +134,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))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -15,6 +15,7 @@
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.Task
|
||||
import org.gradle.api.publish.PublicationContainer
|
||||
import org.gradle.api.publish.maven.MavenPublication
|
||||
import org.gradle.api.tasks.TaskContainer
|
||||
import org.gradle.kotlin.dsl.ExistingDomainObjectDelegate
|
||||
import org.gradle.kotlin.dsl.RegisteringDomainObjectDelegateProviderWithTypeAndAction
|
||||
@ -77,3 +78,40 @@ val Project.publications: PublicationContainer
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
fun MavenPublication.setupPom(
|
||||
project: Project,
|
||||
vcs: String = "https://github.com/mamoe/mirai"
|
||||
) {
|
||||
pom {
|
||||
scm {
|
||||
url.set(vcs)
|
||||
connection.set("scm:$vcs.git")
|
||||
developerConnection.set("scm:${vcs.replace("https:", "git:")}.git")
|
||||
}
|
||||
|
||||
licenses {
|
||||
license {
|
||||
name.set("GNU AGPLv3")
|
||||
url.set("https://github.com/mamoe/mirai/blob/master/LICENSE")
|
||||
}
|
||||
}
|
||||
|
||||
developers {
|
||||
developer {
|
||||
id.set("mamoe")
|
||||
name.set("Mamoe Technologies")
|
||||
email.set("support@mamoe.net")
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
pom.withXml {
|
||||
val root = asNode()
|
||||
root.appendNode("description", project.description)
|
||||
root.appendNode("name", project.name)
|
||||
root.appendNode("url", vcs)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -12,7 +12,7 @@
|
||||
import org.gradle.api.attributes.Attribute
|
||||
|
||||
object Versions {
|
||||
const val project = "2.4-M1"
|
||||
const val project = "2.4-M1-dev-publish-3"
|
||||
|
||||
const val core = project
|
||||
const val console = project
|
||||
|
123
buildSrc/src/main/kotlin/keys/SecretKeys.kt
Normal file
123
buildSrc/src/main/kotlin/keys/SecretKeys.kt
Normal file
@ -0,0 +1,123 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
package keys
|
||||
|
||||
import org.gradle.api.Project
|
||||
import java.io.BufferedReader
|
||||
|
||||
open class SecretKeys(
|
||||
val type: String,
|
||||
val user: String,
|
||||
val password: String
|
||||
) {
|
||||
class Invalid(
|
||||
type: String,
|
||||
override val isDisabled: Boolean = false
|
||||
) : SecretKeys(type, "", "") {
|
||||
override val isValid: Boolean get() = false
|
||||
override fun requireNotInvalid(): Nothing {
|
||||
error(
|
||||
"""
|
||||
Key $type not found.
|
||||
Please lease specify by creating a file $type.key in projectDir/build-secret-keys
|
||||
or by providing JVM parameter '$type.user', `$type.password`
|
||||
""".trimIndent()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
val keyCaches = mutableMapOf<Project, ProjectKeysCache>()
|
||||
|
||||
@JvmStatic
|
||||
fun getCache(project: Project): ProjectKeysCache =
|
||||
keyCaches.computeIfAbsent(project, SecretKeys::ProjectKeysCache)
|
||||
}
|
||||
|
||||
class ProjectKeysCache(val project: Project) {
|
||||
val keys = mutableMapOf<String, SecretKeys>()
|
||||
fun loadKey(type: String) = keys.computeIfAbsent(type, this::loadKey0)
|
||||
|
||||
private fun loadKey0(type: String): SecretKeys {
|
||||
|
||||
project.parent?.let { parent ->
|
||||
getCache(parent).loadKey(type).takeIf {
|
||||
it.isValid || it.isDisabled
|
||||
}?.let { return it }
|
||||
}
|
||||
|
||||
val secretKeys = project.projectDir.resolve("build-secret-keys")
|
||||
|
||||
kotlin.run {
|
||||
val secretKeyFile = secretKeys.resolve("$type.disable").takeIf { it.isFile }
|
||||
?: secretKeys.resolve("$type.disable.txt")
|
||||
if (secretKeyFile.isFile) return Invalid(type, true) // Disabled
|
||||
}
|
||||
|
||||
// Load from secretKeys/$type.key
|
||||
kotlin.run {
|
||||
val secretKeyFile = secretKeys.resolve("$type.key").takeIf { it.isFile }
|
||||
?: secretKeys.resolve("$type.key.txt")
|
||||
if (secretKeyFile.isFile) {
|
||||
secretKeyFile.bufferedReader().use {
|
||||
fun BufferedReader.readLineNonEmpty(): String {
|
||||
while (true) {
|
||||
val nextLine = readLine() ?: return ""
|
||||
if (nextLine.isNotBlank()) {
|
||||
return nextLine.trim()
|
||||
}
|
||||
}
|
||||
}
|
||||
return SecretKeys(type, it.readLineNonEmpty(), it.readLineNonEmpty())
|
||||
}
|
||||
}
|
||||
}
|
||||
// Load from project/%type.key, user
|
||||
kotlin.run {
|
||||
val userFile = project.projectDir.resolve("$type.user.txt")
|
||||
val keyFile = project.projectDir.resolve("$type.key.txt")
|
||||
if (userFile.isFile && keyFile.isFile) {
|
||||
return SecretKeys(type, userFile.readText().trim(), keyFile.readText().trim())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Load from property $type.user, $type.password
|
||||
|
||||
fun findProperty(type: String): String? {
|
||||
val p = project.findProperty(type)
|
||||
?: System.getProperty(type)
|
||||
?: System.getenv(type)
|
||||
|
||||
return p?.toString()
|
||||
}
|
||||
|
||||
val tUser = findProperty("$type.user")
|
||||
?: findProperty("${type}_user")
|
||||
|
||||
val tPassword = findProperty("$type.password")
|
||||
?: findProperty("$type.passwd")
|
||||
?: findProperty("$type.key")
|
||||
?: findProperty("${type}_password")
|
||||
?: findProperty("${type}_passwd")
|
||||
?: findProperty("${type}_key")
|
||||
|
||||
if (tUser != null && tPassword != null) {
|
||||
return SecretKeys(type, tUser, tPassword)
|
||||
}
|
||||
|
||||
return Invalid(type)
|
||||
}
|
||||
}
|
||||
|
||||
open val isValid: Boolean get() = true
|
||||
open val isDisabled: Boolean get() = false
|
||||
open fun requireNotInvalid(): SecretKeys = this
|
||||
}
|
@ -7,18 +7,9 @@
|
||||
* https://github.com/mamoe/mirai/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
import keys.SecretKeys
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.kotlin.dsl.provideDelegate
|
||||
import java.io.File
|
||||
|
||||
/*
|
||||
* Copyright 2019-2020 Mamoe Technologies and contributors.
|
||||
*
|
||||
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 with Mamoe Exceptions 许可证的约束, 可以在以下链接找到该许可证.
|
||||
* Use of this source code is governed by the GNU AFFERO GENERAL PUBLIC LICENSE version 3 with Mamoe Exceptions license that can be found via the following link.
|
||||
*
|
||||
* https://github.com/mamoe/mirai/blob/master/LICENSE
|
||||
*/
|
||||
fun Project.isBintrayAvailable() = Bintray.isBintrayAvailable(project)
|
||||
|
||||
@Suppress("DuplicatedCode")
|
||||
@ -34,76 +25,18 @@ object Bintray {
|
||||
|
||||
@JvmStatic
|
||||
fun getUser(project: Project): String {
|
||||
kotlin.runCatching {
|
||||
@Suppress("UNUSED_VARIABLE", "LocalVariableName")
|
||||
val bintray_user: String by project
|
||||
return bintray_user
|
||||
}
|
||||
|
||||
kotlin.runCatching {
|
||||
@Suppress("UNUSED_VARIABLE", "LocalVariableName")
|
||||
val bintray_user: String by project.rootProject
|
||||
return bintray_user
|
||||
}
|
||||
|
||||
System.getProperty("bintray_user", null)?.let {
|
||||
return it.trim()
|
||||
}
|
||||
|
||||
File(File(System.getProperty("user.dir")).parent, "/bintray.user.txt").let { local ->
|
||||
if (local.exists()) {
|
||||
return local.readText().trim()
|
||||
}
|
||||
}
|
||||
|
||||
File(File(System.getProperty("user.dir")), "/bintray.user.txt").let { local ->
|
||||
if (local.exists()) {
|
||||
return local.readText().trim()
|
||||
}
|
||||
}
|
||||
|
||||
error(
|
||||
"Cannot find bintray user, " +
|
||||
"please specify by creating a file bintray.user.txt in project dir, " +
|
||||
"or by providing JVM parameter 'bintray_user'"
|
||||
)
|
||||
return SecretKeys.getCache(project)
|
||||
.loadKey("bintray")
|
||||
.requireNotInvalid()
|
||||
.user
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun getKey(project: Project): String {
|
||||
kotlin.runCatching {
|
||||
@Suppress("UNUSED_VARIABLE", "LocalVariableName")
|
||||
val bintray_key: String by project
|
||||
return bintray_key
|
||||
}
|
||||
|
||||
kotlin.runCatching {
|
||||
@Suppress("UNUSED_VARIABLE", "LocalVariableName")
|
||||
val bintray_key: String by project.rootProject
|
||||
return bintray_key
|
||||
}
|
||||
|
||||
System.getProperty("bintray_key", null)?.let {
|
||||
return it.trim()
|
||||
}
|
||||
|
||||
File(File(System.getProperty("user.dir")).parent, "/bintray.key.txt").let { local ->
|
||||
if (local.exists()) {
|
||||
return local.readText().trim()
|
||||
}
|
||||
}
|
||||
|
||||
File(File(System.getProperty("user.dir")), "/bintray.key.txt").let { local ->
|
||||
if (local.exists()) {
|
||||
return local.readText().trim()
|
||||
}
|
||||
}
|
||||
|
||||
error(
|
||||
"Cannot find bintray key, " +
|
||||
"please specify by creating a file bintray.key.txt in project dir, " +
|
||||
"or by providing JVM parameter 'bintray_key'"
|
||||
)
|
||||
return SecretKeys.getCache(project)
|
||||
.loadKey("bintray")
|
||||
.requireNotInvalid()
|
||||
.password
|
||||
}
|
||||
|
||||
}
|
22
ci-release-helper/build.gradle.kts
Normal file
22
ci-release-helper/build.gradle.kts
Normal file
@ -0,0 +1,22 @@
|
||||
/*
|
||||
* 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 keys.SecretKeys
|
||||
|
||||
plugins {
|
||||
id("io.codearte.nexus-staging") version "0.22.0"
|
||||
}
|
||||
|
||||
description = "Mirai CI Methods for Releasing"
|
||||
|
||||
nexusStaging {
|
||||
packageGroup = rootProject.group.toString()
|
||||
val keys = SecretKeys.getCache(project).loadKey("sonatype")
|
||||
username = keys.user
|
||||
password = keys.password
|
||||
}
|
@ -1,11 +1,12 @@
|
||||
#
|
||||
# Copyright 2019-2020 Mamoe Technologies and contributors.
|
||||
# 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
|
||||
#
|
||||
|
||||
# style guide
|
||||
kotlin.code.style=official
|
||||
# config
|
||||
@ -17,4 +18,5 @@ org.gradle.vfs.watch=true
|
||||
kotlin.mpp.enableGranularSourceSetsMetadata=true
|
||||
kotlin.native.enableDependencyPropagation=false
|
||||
#kotlin.mpp.enableGranularSourceSetsMetadata=true
|
||||
systemProp.org.gradle.internal.publish.checksums.insecure=true
|
||||
systemProp.org.gradle.internal.publish.checksums.insecure=true
|
||||
gnsp.disableApplyOnlyOnRootProjectEnforcement=true
|
||||
|
@ -29,6 +29,7 @@ include(":mirai-core")
|
||||
include(":mirai-core-all")
|
||||
|
||||
include(":binary-compatibility-validator")
|
||||
include(":ci-release-helper")
|
||||
|
||||
|
||||
fun includeConsoleProjects() {
|
||||
|
Loading…
Reference in New Issue
Block a user