Compare commits

...

14 Commits

14 changed files with 182 additions and 80 deletions

View File

@@ -1,17 +0,0 @@
on: [push]
name: Build
jobs:
build-ubuntu:
name: Commit release
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2
- name: Setup JDK
uses: actions/setup-java@v1
with:
java-version: 11
- name: Build
run: ./gradlew build packageUberJarForCurrentOS

View File

@@ -19,12 +19,12 @@ jobs:
- name: Set version from gradle.properties - name: Set version from gradle.properties
run: echo "version=` cat gradle.properties | grep ^version= | grep -o [\\.0-9]* `" >> $GITHUB_ENV run: echo "version=` cat gradle.properties | grep ^version= | grep -o [\\.0-9]* `" >> $GITHUB_ENV
- name: Build - name: Build
run: ./gradlew build packageUberJarForCurrentOS run: ./gradlew build packageReleaseUberJarForCurrentOS
- name: Publish Web - name: Publish Web
uses: peaceiris/actions-gh-pages@v3 uses: peaceiris/actions-gh-pages@v3
with: with:
github_token: ${{ secrets.GITHUB_TOKEN }} github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./web/build/distributions publish_dir: ./core/build/dist/js/productionExecutable
publish_branch: site publish_branch: site
- name: Create Release - name: Create Release
id: create_release id: create_release

View File

@@ -0,0 +1,48 @@
package dev.inmo.kmppscriptbuilder.core.export
import dev.inmo.kmppscriptbuilder.core.models.MavenConfig
const val generateCentralSonatypeUploadingPartImports = """import java.nio.charset.StandardCharsets
import java.net.http.HttpClient
import java.net.http.HttpRequest
import java.net.http.HttpResponse"""
const val generateCentralSonatypeUploadingPart = """if ((project.hasProperty('SONATYPE_USER') || System.getenv('SONATYPE_USER') != null) && (project.hasProperty('SONATYPE_PASSWORD') || System.getenv('SONATYPE_PASSWORD') != null)) {
def taskName = "uploadSonatypePublication"
if (rootProject.tasks.names.contains(taskName) == false) {
rootProject.tasks.register(taskName) {
doLast {
def username = project.hasProperty('SONATYPE_USER') ? project.property('SONATYPE_USER') : System.getenv('SONATYPE_USER')
def password = project.hasProperty('SONATYPE_PASSWORD') ? project.property('SONATYPE_PASSWORD') : System.getenv('SONATYPE_PASSWORD')
def bearer = Base64.getEncoder().encodeToString("${"$"}username:${"$"}password".getBytes(StandardCharsets.UTF_8))
def client = HttpClient.newHttpClient()
def request = HttpRequest.newBuilder()
.uri(URI.create("https://ossrh-staging-api.central.sonatype.com/manual/search/repositories?state=open"))
.GET()
.header("Content-Type", "application/json")
.header("Authorization", "Bearer ${"$"}bearer")
.build()
def response = client.send(request, HttpResponse.BodyHandlers.ofString())
def keys = new ArrayList<String>()
response.body().findAll("\"key\"[\\s]*:[\\s]*\"[^\"]+\"").forEach {
def key = it.find("[^\"]+\"\$").find("[^\"]+")
keys.add(key)
}
keys.forEach {
println("Start uploading ${"$"}it")
def uploadRequest = HttpRequest.newBuilder()
.uri(URI.create("https://ossrh-staging-api.central.sonatype.com/manual/upload/repository/${"$"}it?publishing_type=user_managed"))
.POST(HttpRequest.BodyPublishers.ofString(""))
.header("Content-Type", "application/json")
.header("Authorization", "Bearer ${"$"}bearer")
.build()
def uploadResponse = client.send(uploadRequest, HttpResponse.BodyHandlers.ofString())
if (uploadResponse.statusCode() != 200) {
throw IllegalStateException("Faced error of uploading for repo with key ${"$"}it. Response: ${"$"}uploadResponse")
}
}
}
}
}
}"""

View File

@@ -8,18 +8,41 @@ fun GpgSigning.generateMavenConfig() = when (this) {
""" """
if (project.hasProperty("signing.gnupg.keyName")) { if (project.hasProperty("signing.gnupg.keyName")) {
apply plugin: 'signing' apply plugin: 'signing'
signing { signing {
useGpgCmd() useGpgCmd()
sign publishing.publications sign publishing.publications
} }
task signAll { task signAll {
tasks.withType(Sign).forEach { tasks.withType(Sign).forEach {
dependsOn(it) dependsOn(it)
} }
} }
// Workaround to make android sign operations depend on signing tasks
project.getTasks().withType(AbstractPublishToMaven.class).configureEach {
def signingTasks = project.getTasks().withType(Sign.class)
mustRunAfter(signingTasks)
}
// Workaround to make test tasks use sign
project.getTasks().withType(Sign.class).configureEach { signTask ->
def withoutSign = (signTask.name.startsWith("sign") ? signTask.name.minus("sign") : signTask.name)
def pubName = withoutSign.endsWith("Publication") ? withoutSign.substring(0, withoutSign.length() - "Publication".length()) : withoutSign
// These tasks only exist for native targets, hence findByName() to avoid trying to find them for other targets
// Task ':linkDebugTest<platform>' uses this output of task ':sign<platform>Publication' without declaring an explicit or implicit dependency
def debugTestTask = tasks.findByName("linkDebugTest${'$'}pubName")
if (debugTestTask != null) {
signTask.mustRunAfter(debugTestTask)
}
// Task ':compileTestKotlin<platform>' uses this output of task ':sign<platform>Publication' without declaring an explicit or implicit dependency
def testTask = tasks.findByName("compileTestKotlin${'$'}pubName")
if (testTask != null) {
signTask.mustRunAfter(testTask)
}
}
} }
""" """
GpgSigning.Enabled -> GpgSigning.Enabled ->
@@ -37,5 +60,28 @@ task signAll {
dependsOn(it) dependsOn(it)
} }
} }
// Workaround to make android sign operations depend on signing tasks
project.getTasks().withType(AbstractPublishToMaven.class).configureEach {
def signingTasks = project.getTasks().withType(Sign.class)
mustRunAfter(signingTasks)
}
// Workaround to make test tasks use sign
project.getTasks().withType(Sign.class).configureEach { signTask ->
def withoutSign = (signTask.name.startsWith("sign") ? signTask.name.minus("sign") : signTask.name)
def pubName = withoutSign.endsWith("Publication") ? withoutSign.substring(0, withoutSign.length() - "Publication".length()) : withoutSign
// These tasks only exist for native targets, hence findByName() to avoid trying to find them for other targets
// Task ':linkDebugTest<platform>' uses this output of task ':sign<platform>Publication' without declaring an explicit or implicit dependency
def debugTestTask = tasks.findByName("linkDebugTest${'$'}pubName")
if (debugTestTask != null) {
signTask.mustRunAfter(debugTestTask)
}
// Task ':compileTestKotlin<platform>' uses this output of task ':sign<platform>Publication' without declaring an explicit or implicit dependency
def testTask = tasks.findByName("compileTestKotlin${'$'}pubName")
if (testTask != null) {
signTask.mustRunAfter(testTask)
}
}
""" """
} }

View File

@@ -1,19 +1,23 @@
package dev.inmo.kmppscriptbuilder.core.export.js_only package dev.inmo.kmppscriptbuilder.core.export.js_only
import dev.inmo.kmppscriptbuilder.core.export.generateCentralSonatypeUploadingPart
import dev.inmo.kmppscriptbuilder.core.export.generateCentralSonatypeUploadingPartImports
import dev.inmo.kmppscriptbuilder.core.export.generateMavenConfig import dev.inmo.kmppscriptbuilder.core.export.generateMavenConfig
import dev.inmo.kmppscriptbuilder.core.models.* import dev.inmo.kmppscriptbuilder.core.models.*
fun MavenConfig.buildJsOnlyMavenConfig(licenses: List<License>): String = """ fun MavenConfig.buildJsOnlyMavenConfig(licenses: List<License>): String = """
${if (includeCentralSonatypeUploadingScript) "$generateCentralSonatypeUploadingPartImports\n" else ""}
apply plugin: 'maven-publish' apply plugin: 'maven-publish'
${if (includeCentralSonatypeUploadingScript) "$generateCentralSonatypeUploadingPart\n" else ""}
task javadocJar(type: Jar) { task javadocJar(type: Jar) {
classifier = 'javadoc' archiveClassifier = 'javadoc'
} }
task sourcesJar(type: Jar) { task sourcesJar(type: Jar) {
kotlin.sourceSets.all { kotlin.sourceSets.all {
from(kotlin) from(kotlin)
} }
classifier = 'sources' archiveClassifier = 'sources'
} }
publishing { publishing {

View File

@@ -1,18 +1,22 @@
package dev.inmo.kmppscriptbuilder.core.export.jvm_only package dev.inmo.kmppscriptbuilder.core.export.jvm_only
import dev.inmo.kmppscriptbuilder.core.export.generateCentralSonatypeUploadingPart
import dev.inmo.kmppscriptbuilder.core.export.generateCentralSonatypeUploadingPartImports
import dev.inmo.kmppscriptbuilder.core.export.generateMavenConfig import dev.inmo.kmppscriptbuilder.core.export.generateMavenConfig
import dev.inmo.kmppscriptbuilder.core.models.* import dev.inmo.kmppscriptbuilder.core.models.*
fun MavenConfig.buildJvmOnlyMavenConfig(licenses: List<License>): String = """ fun MavenConfig.buildJvmOnlyMavenConfig(licenses: List<License>): String = """
${if (includeCentralSonatypeUploadingScript) "$generateCentralSonatypeUploadingPartImports\n" else ""}
apply plugin: 'maven-publish' apply plugin: 'maven-publish'
${if (includeCentralSonatypeUploadingScript) "$generateCentralSonatypeUploadingPart\n" else ""}
task javadocJar(type: Jar) { task javadocJar(type: Jar) {
from javadoc from javadoc
classifier = 'javadoc' archiveClassifier = 'javadoc'
} }
task sourcesJar(type: Jar) { task sourcesJar(type: Jar) {
from sourceSets.main.allSource from sourceSets.main.allSource
classifier = 'sources' archiveClassifier = 'sources'
} }
publishing { publishing {

View File

@@ -1,13 +1,16 @@
package dev.inmo.kmppscriptbuilder.core.export.mpp package dev.inmo.kmppscriptbuilder.core.export.mpp
import dev.inmo.kmppscriptbuilder.core.export.generateCentralSonatypeUploadingPart
import dev.inmo.kmppscriptbuilder.core.export.generateCentralSonatypeUploadingPartImports
import dev.inmo.kmppscriptbuilder.core.export.generateMavenConfig import dev.inmo.kmppscriptbuilder.core.export.generateMavenConfig
import dev.inmo.kmppscriptbuilder.core.models.* import dev.inmo.kmppscriptbuilder.core.models.*
fun MavenConfig.buildMultiplatformMavenConfig(licenses: List<License>): String = """ fun MavenConfig.buildMultiplatformMavenConfig(licenses: List<License>): String = """
${if (includeCentralSonatypeUploadingScript) "$generateCentralSonatypeUploadingPartImports\n" else ""}
apply plugin: 'maven-publish' apply plugin: 'maven-publish'
${if (includeCentralSonatypeUploadingScript) "$generateCentralSonatypeUploadingPart\n" else ""}
task javadocsJar(type: Jar) { task javadocsJar(type: Jar) {
classifier = 'javadoc' archiveClassifier = 'javadoc'
} }
publishing { publishing {
@@ -24,23 +27,19 @@ publishing {
url = "$vcsUrl" url = "$vcsUrl"
} }
developers { developers {${developers.joinToString("\n") { """
${developers.joinToString("\n") { """ developer {
developer { id = "${it.id}"
id = "${it.id}" name = "${it.name}"
name = "${it.name}" email = "${it.eMail}"
email = "${it.eMail}" }""" }}
}
""" }}
} }
licenses { licenses {${licenses.joinToString("\n") { """
${licenses.joinToString("\n") { """ license {
license { name = "${it.title}"
name = "${it.title}" url = "${it.url}"
url = "${it.url}" }""" }}
}
""" }}
} }
} }
repositories { repositories {

View File

@@ -26,6 +26,7 @@ data class MavenConfig(
val gpgSigning: GpgSigning = GpgSigning.Disabled, val gpgSigning: GpgSigning = GpgSigning.Disabled,
@Deprecated("Replaced with gpgSigning") @Deprecated("Replaced with gpgSigning")
val includeGpgSigning: Boolean = false, val includeGpgSigning: Boolean = false,
val includeCentralSonatypeUploadingScript: Boolean = false,
) )
@Serializable @Serializable
@@ -61,8 +62,7 @@ return """
credentials { credentials {
username = project.hasProperty('${usernameProperty}') ? project.property('${usernameProperty}') : System.getenv('${usernameProperty}') username = project.hasProperty('${usernameProperty}') ? project.property('${usernameProperty}') : System.getenv('${usernameProperty}')
password = project.hasProperty('${passwordProperty}') ? project.property('${passwordProperty}') : System.getenv('${passwordProperty}') password = project.hasProperty('${passwordProperty}') ? project.property('${passwordProperty}') : System.getenv('${passwordProperty}')
} }"""
"""
} }
companion object { companion object {
@@ -86,7 +86,10 @@ return """
name = "$headerName" name = "$headerName"
value = project.hasProperty('${headerValueProperty}') ? project.property('${headerValueProperty}') : System.getenv('${headerValueProperty}') value = project.hasProperty('${headerValueProperty}') ? project.property('${headerValueProperty}') : System.getenv('${headerValueProperty}')
} }
"""
authentication {
header(HttpHeaderAuthentication)
}"""
} }
companion object { companion object {
@@ -115,3 +118,4 @@ ${credsType.buildCredsPart()}
} }
val SonatypeRepository = MavenPublishingRepository("sonatype", "https://oss.sonatype.org/service/local/staging/deploy/maven2/") val SonatypeRepository = MavenPublishingRepository("sonatype", "https://oss.sonatype.org/service/local/staging/deploy/maven2/")
val CentralSonatypeRepository = MavenPublishingRepository("sonatype", "https://ossrh-staging-api.central.sonatype.com/service/local/staging/deploy/maven2/")

View File

@@ -1,6 +1,7 @@
package dev.inmo.kmppscriptbuilder.core.ui package dev.inmo.kmppscriptbuilder.core.ui
import androidx.compose.runtime.* import androidx.compose.runtime.*
import dev.inmo.kmppscriptbuilder.core.models.CentralSonatypeRepository
import dev.inmo.kmppscriptbuilder.core.models.GpgSigning import dev.inmo.kmppscriptbuilder.core.models.GpgSigning
import dev.inmo.kmppscriptbuilder.core.models.MavenConfig import dev.inmo.kmppscriptbuilder.core.models.MavenConfig
import dev.inmo.kmppscriptbuilder.core.models.SonatypeRepository import dev.inmo.kmppscriptbuilder.core.models.SonatypeRepository
@@ -23,22 +24,31 @@ class MavenInfoView : VerticalView("Project information") {
internal var projectVcsUrlProperty by mutableStateOf("") internal var projectVcsUrlProperty by mutableStateOf("")
internal var gpgSignProperty by mutableStateOf<GpgSigning>(GpgSigning.Disabled) internal var gpgSignProperty by mutableStateOf<GpgSigning>(GpgSigning.Disabled)
internal var publishToMavenCentralProperty by mutableStateOf(false) internal var publishToMavenCentralProperty by mutableStateOf(false)
internal var publishToCentralSonatypeProperty by mutableStateOf(false)
internal var includeCentralSonatypeUploadingScriptProperty by mutableStateOf(false)
internal val developersView = DevelopersView() internal val developersView = DevelopersView()
internal val repositoriesView = RepositoriesView() internal val repositoriesView = RepositoriesView()
var mavenConfig: MavenConfig var mavenConfig: MavenConfig
get() = MavenConfig( get() = MavenConfig(
projectNameProperty.ifBlank { defaultProjectName }, name = projectNameProperty.ifBlank { defaultProjectName },
projectDescriptionProperty.ifBlank { defaultProjectDescription }, description = projectDescriptionProperty.ifBlank { defaultProjectDescription },
projectUrlProperty, url = projectUrlProperty,
projectVcsUrlProperty, vcsUrl = projectVcsUrlProperty,
developersView.developers, developers = developersView.developers,
repositoriesView.repositories + if (publishToMavenCentralProperty) { repositories = repositoriesView.repositories + if (publishToMavenCentralProperty) {
listOf(SonatypeRepository) listOf(
if (publishToCentralSonatypeProperty) {
CentralSonatypeRepository
} else {
SonatypeRepository
}
)
} else { } else {
emptyList() emptyList()
}, },
gpgSignProperty gpgSigning = gpgSignProperty,
includeCentralSonatypeUploadingScript = includeCentralSonatypeUploadingScriptProperty
) )
set(value) { set(value) {
projectNameProperty = value.name projectNameProperty = value.name
@@ -50,9 +60,11 @@ class MavenInfoView : VerticalView("Project information") {
} else { } else {
value.gpgSigning value.gpgSigning
} }
publishToMavenCentralProperty = value.repositories.any { it == SonatypeRepository } publishToMavenCentralProperty = value.repositories.any { it == SonatypeRepository || it == CentralSonatypeRepository }
developersView.developers = value.developers developersView.developers = value.developers
repositoriesView.repositories = value.repositories.filter { it != SonatypeRepository } repositoriesView.repositories = value.repositories.filter { it != SonatypeRepository && it != CentralSonatypeRepository }
publishToCentralSonatypeProperty = value.repositories.any { it == CentralSonatypeRepository }
includeCentralSonatypeUploadingScriptProperty = value.includeCentralSonatypeUploadingScript
} }
private val gpgSigningDrawer = GpgSigningOptionDrawerWithView(this) private val gpgSigningDrawer = GpgSigningOptionDrawerWithView(this)
@@ -100,6 +112,20 @@ class MavenInfoView : VerticalView("Project information") {
publishToMavenCentralProperty, publishToMavenCentralProperty,
placeSwitchAtTheStart = true placeSwitchAtTheStart = true
) { publishToMavenCentralProperty = it } ) { publishToMavenCentralProperty = it }
if (publishToMavenCentralProperty) {
SwitchWithLabel(
"Use Central Sonatype instead of OSSRH (OSSRH has been deprecated)",
publishToCentralSonatypeProperty,
placeSwitchAtTheStart = true
) { publishToCentralSonatypeProperty = it }
if (publishToCentralSonatypeProperty) {
SwitchWithLabel(
"Add 'uploadSonatypePublication' root project task (required for Central Sonatype publishing)",
includeCentralSonatypeUploadingScriptProperty,
placeSwitchAtTheStart = true
) { includeCentralSonatypeUploadingScriptProperty = it }
}
}
developersView.build() developersView.build()
repositoriesView.build() repositoriesView.build()
} }

View File

@@ -4,18 +4,6 @@ kotlin.js.generate.externals=true
kotlin.incremental=true kotlin.incremental=true
kotlin.incremental.js=true kotlin.incremental.js=true
kotlin_version=1.7.20
kotlin_coroutines_version=1.6.4
kotlin_serialisation_core_version=1.4.1
ktor_version=2.1.3
micro_utils_version=0.14.2
compose_version=1.2.1
# Dokka
dokka_version=1.7.20
# Project data # Project data
group=dev.inmo group=dev.inmo

View File

@@ -1,15 +1,15 @@
[versions] [versions]
kt = "1.7.20" kt = "1.9.20"
kt-serialization = "1.4.1" kt-serialization = "1.6.0"
kt-coroutines = "1.6.4" kt-coroutines = "1.7.3"
jb-compose = "1.2.1" jb-compose = "1.5.10"
jb-dokka = "1.7.20" jb-dokka = "1.9.10"
microutils = "0.14.2" microutils = "0.20.11"
kjsuikit = "0.4.1" kjsuikit = "0.7.3"
ktor = "2.1.3" ktor = "2.3.5"
gh-release = "2.4.1" gh-release = "2.4.1"

View File

@@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-bin.zip

View File

@@ -13,7 +13,7 @@ kotlin {
commonMain { commonMain {
dependencies { dependencies {
implementation kotlin('stdlib') implementation kotlin('stdlib')
api "org.jetbrains.kotlinx:kotlinx-serialization-json:$kotlin_serialisation_core_version" api libs.kt.serialization
} }
} }
commonTest { commonTest {

View File

@@ -1,4 +1,4 @@
project.version = "$version" + System.getenv("additional_version") project.version = "$version" + (System.getenv("additional_version") == null ? "" : System.getenv("additional_version"))
project.group = "$group" project.group = "$group"
// apply from: "$publishGradlePath" // apply from: "$publishGradlePath"
@@ -14,7 +14,7 @@ kotlin {
commonMain { commonMain {
dependencies { dependencies {
implementation kotlin('stdlib') implementation kotlin('stdlib')
api "org.jetbrains.kotlinx:kotlinx-serialization-json:$kotlin_serialisation_core_version" api libs.kt.serialization
} }
} }
commonTest { commonTest {