kotlin库_您的Kotlin多平台库的连续交付

kotlin库

As part of the MagicLab family, one of my main projects was involved in the team that created Reaktive library — Reaktive Extensions on pure Kotlin.

作为MagicLab家族的一部分,我的主要项目之一是参与创建Reaktive库的团队-在纯Kotlin上创建Reaktive扩展。

In the case of Kotlin Multiplatform I discovered that continuous integration and continuous delivery require additional configuration. You need to have multiple virtual machines with different operating systems in order to build a library. In this article I’ll be showing you how to configure continuous delivery for your Kotlin Multiplatform library.

对于Kotlin Multiplatform,我发现持续集成和持续交付需要额外的配置。 您需要具有多个具有不同操作系统的虚拟机才能构建库。 在本文中,我将向您展示如何为Kotlin Multiplatform库配置连续交付。

开源库的持续集成和持续交付 (Continuous integration and continuous delivery for open-source libraries)

Continuous integration and continuous delivery have been part of the open-source communities for a long time as they offer a number of useful services. Many of them provide their services for open-source projects completely free of charge: Travis CI, JitPack, CircleCI, Microsoft Azure Pipelines and also GitHub Actions, which launched recently.

长期以来,持续集成和持续交付一直是开源社区的一部分,因为它们提供了许多有用的服务。 他们中的许多人完全免费为开源项目提供服务:Travis CI,JitPack,CircleCI,Microsoft Azure Pipelines以及最近启动的GitHub Actions。

For Badoo open-source projects for Android we use Travis CI for continuous integration and JitPack for continuous delivery.

对于Android的Badoo开源项目,我们使用Travis CI进行持续集成,并使用JitPack进行持续交付。

Following implementation of iOS support in our multi-platform library, I discovered that we couldn’t build the library using JitPack, because it doesn’t provide virtual machines on macOS (iOS can only be built on macOS).

在我们的多平台库中实现iOS支持后,我发现我们无法使用JitPack构建该库,因为它没有在macOS上提供虚拟机(iOS只能在macOS上构建)。

So, a more familiar Bintray was chosen for further publication of the library. It allows published artifacts to be more finely tuned, unlike JitPack, which simply took all of the results of the publishToMavenLocal task.

因此,选择了更熟悉的Bintray来进一步发布该库。 与JitPack不同,它允许对发布的工件进行更精细的调整,而JitPack只是获取publishToMavenLocal任务的所有结果。

The Gradle Bintray Plugin is recommended for publishing, and I later configured to suit our needs. To build the project, I continued to use Travis CI for several reasons: firstly, I was already familiar with it and I had used it for nearly all of my pet projects; secondly, it provides virtual machines on macOS, which is necessary for building for iOS.

建议发布Gradle Bintray插件,我后来对其进行了配置以满足我们的需求。 为了构建该项目,出于以下几个原因,我继续使用Travis CI:首先,我已经熟悉它,并且几乎在我的所有宠物项目中都使用了它。 其次,它在macOS上提供虚拟机,这对于构建iOS是必需的。

并行构建多平台库 (Parallel building of multiplatform library)

If you look at the Kotlin documentation in detail, you will find a section on publishing multiplatform libraries.

如果您详细查看Kotlin文档,则会发现有关发布多平台库的部分

Kotlin Multiplatform developers are aware of the multiplatform building issues (not everything can be built on all operating systems) and offer the option of building the library separately on different operating systems.

Kotlin多平台开发人员意识到多平台构建问题(并非所有内容都可以在所有操作系统上构建),并提供了在不同操作系统上分别构建库的选项。

kotlin {
jvm()
js()
mingwX64()
linuxX64()
// Note that the Kotlin metadata is here, too.
// The mingwx64() target is automatically skipped as incompatible in Linux builds.
configure([targets["metadata"], jvm(), js()]) {
mavenPublication { targetPublication ->
tasks.withType(AbstractPublishToMaven)
.matching { it.publication == targetPublication }
.all { onlyIf { findProperty("isLinux") == "true" } }
}
}
}

As the code above shows, depending on the ‘isLinux’ property passed to Gradle, we enable the publishing of certain targets. By targets I mean the assembly for a specific platform. On Windows, only the Windows-target will be assembled, while on other operating systems metadata and other targets will.

如上面的代码所示,根据传递给Gradle的'isLinux'属性,我们启用某些目标的发布。 目标是指特定平台的组装。 在Windows上,仅Windows目标将被汇编,而在其他操作系统上元数据和其他目标将被汇编。

An excellent and concise solution that only works for publishToMavenLocal or publish from the maven-publish plugin, which is not suitable for us because of the use of Gradle Bintray Plugin.

一个优秀的,简洁的解决方案,它仅适用于publishToMavenLocalpublishmaven-publish插件,这是因为使用的不适合我们GradleBintray插件

I decided to use the environment variable for selecting the target, as this code was previously written in Groovy, was in a separate Groovy Gradle script, and access to the environment variables is from a static scope.

我决定使用环境变量来选择目标,因为该代码以前是用Groovy编写的,是在单独的Groovy Gradle脚本中进行的,并且从静态作用域访问环境变量。

enum class Target {
ALL,
COMMON,
IOS,
META; val common: Boolean
@JvmName("isCommon")
get() = this == ALL || this == COMMON val ios: Boolean
@JvmName("isIos")
get() = this == ALL || this == IOS val meta: Boolean
@JvmName("isMeta")
get() = this == ALL || this == META companion object {
@JvmStatic
fun currentTarget(): Target {
val value = System.getProperty("MP_TARGET")
return values().find { it.name.equals(value, ignoreCase = true) } ?: ALL
}
}
}

As part of our project, I have identified four target groups:

作为我们项目的一部分,我确定了四个目标群体:

  1. ALL — all targets are set up and assembled and used for development and as a default.

    ALL-所有目标均已设置,组装并用于开发(默认情况下)。
  2. COMMON — only Linux-compatible targets are set up and assembled. In our case, this is JavaScript, JVM, Android JVM, Linux x64 and Linux ARM x32.

    COMMON-仅设置和组装与Linux兼容的目标。 在我们的例子中,这是JavaScript,JVM,Android JVM,Linux x64和Linux ARM x32。
  3. IOS — only iOS-targets are set up and assembled; used for assembly on MacOS.

    IOS-仅设置和组装iOS目标; 用于在MacOS上进行组装。
  4. META — all targets are set up, but only the module with meta information for Gradle Metadata is assembled.

    META —设置了所有目标,但仅组装了具有Gradle元数据的元信息的模块。

With these target groups, we can parallelise the assembly of the project on three different virtual machines (COMMON — Linux, IOS — macOS, META — Linux).

通过这些目标组,我们可以在三个不同的虚拟机(COMMON-Linux,IOS-macOS,META-Linux)上并行进行项目组装。

Currently, it is possible to assemble everything on macOS, but my solution has two advantages. Firstly, if we decide to implement Windows support, all we need to do is add a new target group and a new virtual machine on Windows. Secondly, there is no need to spend virtual machine resources on macOS for items that can be assembled on Linux. CPU time on these virtual machines is usually twice as expensive.

当前,可以在macOS上组装所有内容,但是我的解决方案有两个优点。 首先,如果我们决定实现Windows支持,那么我们要做的就是在Windows上添加一个新的目标组和一个新的虚拟机。 其次,无需在macOS上花费虚拟机资源来购买可在Linux上组装的项目。 这些虚拟机上的CPU时间通常是两倍。

Gradle元数据 (Gradle Metadata)

What is Gradle Metadata and what is it for?

什么是Gradle元数据,其用途是什么?

Currently, Maven uses POM (Project Object Model) to resolve dependencies.

当前,Maven使用POM(项目对象模型)来解决依赖关系。

<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<groupId>com.jakewharton.rxbinding2</groupId>
<artifactId>rxbinding-leanback-v17-kotlin</artifactId>
<version>2.2.0</version>
<packaging>aar</packaging>
<name>RxBinding Kotlin (leanback-v17)</name>
<description>RxJava binding APIs for Android's UI widgets.</description>
<url>https://github.com/JakeWharton/RxBinding/</url>
<licenses>
<license>
<name>The Apache Software License, Version 2.0</name>
<url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
<distribution>repo</distribution>
</license>
</licenses>
<developers>
<developer>
<id>jakewharton</id>
<name>Jake Wharton</name>
</developer>
</developers>
<scm>
<connection>scm:git:git://github.com/JakeWharton/RxBinding.git</connection>
<developerConnection>scm:git:ssh://git@github.com/JakeWharton/RxBinding.git</developerConnection>
<url>https://github.com/JakeWharton/RxBinding/</url>
</scm>
<dependencies>
<dependency>
<groupId>com.android.support</groupId>
<artifactId>support-annotations</artifactId>
<version>28.0.0</version>
<scope>compile</scope>
</dependency>
</dependencies>
</project>

The POM file contains information about the library version, its creator and the required dependencies.

POM文件包含有关库版本,其创建者和所需依赖项的信息。

What if we want to have two library versions for different JDKs? For example, there are two versions of kotlin-stdlib: kotlin-stdlib-jdk8 and kotlin-stdlib-jdk7. Users need to connect to the required version themselves.

如果我们想为不同的JDK提供两个库版本怎么办? 例如,有两种版本的kotlin-stdlibkotlin-stdlib-jdk8kotlin-stdlib-jdk7 。 用户需要自己连接到所需版本。

When updating the JDK version, it is very easy to forget the external dependencies. Gradle Metadata was created in order to solve this problem; it allows you to add additional conditions for a particular library.

更新JDK版本时,很容易忘记外部依赖项。 为了解决这个问题,创建了Gradle元数据。 它允许您为特定库添加其他条件。

One of the supported Gradle Metadata attributes is org.gradle.jvm.version, which specifies the JDK version. Therefore, a simplified metadata file for kotlin-stdlib might look like this:

支持的Gradle元数据属性之一是org.gradle.jvm.version ,它指定了JDK版本。 因此,用于kotlin-stdlib的简化元数据文件可能如下所示:

{
"formatVersion": "1.0",
"component": {
"group": "org.jetbrains.kotlin",
"module": "kotlin-stdlib",
"version": "1.3.0"
},
"variants": [
{
"name": "apiElements",
"attributes": {
"org.gradle.jvm.version": 8
},
"available-at": {
"url": "../../kotlin-stdlib-jdk8/1.3.0/kotlin-stdlib-jdk8.module",
"group": "org.jetbrains.kotlin",
"module": "kotlin-stdlib-jdk8",
"version": "1.3.0"
}
},
{
"name": "apiElements",
"attributes": {
"org.gradle.jvm.version": 7
},
"available-at": {
"url": "../../kotlin-stdlib-jdk7/1.3.0/kotlin-stdlib-jdk7.module",
"group": "org.jetbrains.kotlin",
"module": "kotlin-stdlib-jdk7",
"version": "1.3.0"
}
}
]
}

In our case, reaktive-1.0.0-rc1.module in simplified form looks like this:

在我们的情况下,简化形式的reaktive-1.0.0-rc1.module看起来像这样:

{
"formatVersion": "1.0",
"component": {
"group": "com.badoo.reaktive",
"module": "reaktive",
"version": "1.0.0-rc1",
"attributes": {
"org.gradle.status": "release"
}
},
"createdBy": {
"gradle": {
"version": "5.4.1",
"buildId": "tv44qntk2zhitm23bbnqdngjam"
}
},
"variants": [
{
"name": "android-releaseRuntimeElements",
"attributes": {
"com.android.build.api.attributes.BuildTypeAttr": "release",
"com.android.build.api.attributes.VariantAttr": "release",
"org.gradle.usage": "java-runtime",
"org.jetbrains.kotlin.platform.type": "androidJvm"
},
"available-at": {
"url": "../../reaktive-android/1.0.0-rc1/reaktive-android-1.0.0-rc1.module",
"group": "com.badoo.reaktive",
"module": "reaktive-android",
"version": "1.0.0-rc1"
}
},
{
"name": "ios64-api",
"attributes": {
"org.gradle.usage": "kotlin-api",
"org.jetbrains.kotlin.native.target": "ios_arm64",
"org.jetbrains.kotlin.platform.type": "native"
},
"available-at": {
"url": "../../reaktive-ios64/1.0.0-rc1/reaktive-ios64-1.0.0-rc1.module",
"group": "com.badoo.reaktive",
"module": "reaktive-ios64",
"version": "1.0.0-rc1"
}
},
{
"name": "linuxX64-api",
"attributes": {
"org.gradle.usage": "kotlin-api",
"org.jetbrains.kotlin.native.target": "linux_x64",
"org.jetbrains.kotlin.platform.type": "native"
},
"available-at": {
"url": "../../reaktive-linuxx64/1.0.0-rc1/reaktive-linuxx64-1.0.0-rc1.module",
"group": "com.badoo.reaktive",
"module": "reaktive-linuxx64",
"version": "1.0.0-rc1"
}
},
]
}

Thanks to the org.jetbrains.kotlin attributes, Gradle knows when a particular dependency needs to be pulled into the required source set.

多亏了org.jetbrains.kotlin属性,Gradle知道何时需要将特定的依赖项拉入所需的源集中。

Metadata can be enabled using:

可以使用以下方式启用元数据:

enableFeaturePreview(“GRADLE_METADATA”)

Detailed information can be found in documentation.

详细信息可在文档中找到。

发布配置 (Publishing configuration)

Once we have dealt with the targets and assembly parallelisation, we need to configure exactly what we are going to publish and how we’ll do it.

一旦处理了目标和程序集的并行化,就需要准确配置要发布的内容以及如何进行。

For publishing we use Gradle Bintray Plugin, so first of all we will refer to its README and configure information about our repository and the credentials for publishing.

对于发布,我们使用Gradle Bintray插件,因此首先,我们将参考其自述文件并配置有关存储库和发布凭据的信息。

The entire configuration will be performed in our own plugin in the buildSrc folder.

整个配置将在buildSrc文件夹中的我们自己的插件中执行。

There are a number of advantages of using buildSrc. For example, autocomplete works in nearly all cases (except for Kotlin scripts where it doesn’t always work and often requires an apply dependencies call), classes from it can be reused and accessed from Groovy and Kotlin scripts. You can see a usage example here buildSrc from the latest Google I/O (Gradle section).

使用buildSrc有许多优点。 例如,自动完成功能几乎可以在所有情况下工作(除了Kotlin脚本并不总是有效并且经常需要应用依赖项调用)之外,可以重新使用其中的类并从Groovy和Kotlin脚本中对其进行访问。 您可以在这里从最新的Google I / O(Gradle部分)中的buildSrc看到一个使用示例

private fun setupBintrayPublishingInformation(target: Project) {
// We apply Bintray Plugin to the project
target.plugins.apply(BintrayPlugin::class)
// And we configure it
target.extensions.getByType(BintrayExtension::class).apply {
user = target.findProperty("bintray_user")?.toString()
key = target.findProperty("bintray_key")?.toString()
pkg.apply {
repo = "maven"
name = "reaktive"
userOrg = "badoo"
vcsUrl = "https://github.com/badoo/Reaktive.git"
setLicenses("Apache-2.0")
version.name = target.property("reaktive_version")?.toString()
}
}
}

I use three dynamic project properties: bintray_user and bintray_key, which can be retrieved from the personal profile settings on Bintray, and the reaktive_version, which is set in the build.gradle root file.

我使用了三个动态项目属性: bintray_userbintray_key (可以从Bintray上的个人资料设置中检索 )以及reaktive_version (在build.gradle根文件中设置)。

For each target, Kotlin Multiplatform Plugin creates MavenPublication, which is available in PublishingExtension.

对于每个目标,Kotlin Multiplatform插件都会创建MavenPublication ,可在PublishingExtension中使用它

Using the example code from the Kotlin documentation, which I mentioned above, we can create this configuration:

使用我上面提到的Kotlin文档中的示例代码,我们可以创建以下配置:

private fun createConfigurationMap(): Map<String, Boolean> {
val mppTarget = Target.currentTarget()
return mapOf(
"kotlinMultiplatform" to mppTarget.meta,
KotlinMultiplatformPlugin.METADATA_TARGET_NAME to mppTarget.meta,
"jvm" to mppTarget.common,
"js" to mppTarget.common,
"androidDebug" to mppTarget.common,
"androidRelease" to mppTarget.common,
"linuxX64" to mppTarget.common,
"linuxArm32Hfp" to mppTarget.common,
"iosArm32" to mppTarget.ios,
"iosArm64" to mppTarget.ios,
"iosX64" to mppTarget.ios
)
}

In this simple map we illustrate which publications should be released on a specific virtual machine. The name of the publication is the name of the target. This configuration is completely consistent with the target groups description which I gave above.

在此简单图中,我们说明了应在特定虚拟机上发布哪些出版物。 出版物的名称是目标的名称。 此配置与我上面给出的目标组描述完全一致。

private fun setupBintrayPublishing(
target: Project,
taskConfigurationMap: Map<String, Boolean>
) {
target.tasks.named(BintrayUploadTask.getTASK_NAME(), BintrayUploadTask::class) {
doFirst {
// Configuration here
}
}
}

Anyone who begins working with the Bintray plugin quickly realises that the repository has been gathering dust for a while (the last update was about six months ago), and that all of the problems can be solved with all sorts of hacks and temporary solutions in the Issues tab. Support for a technology as new as Gradle Metadata has not been set up, but with issue, you can find a solution, which is the one that we use.

任何开始使用Bintray插件的人都会很快意识到该存储库已经收集了一段时间的灰尘(最近一次更新大约是六个月前),并且所有的问题都可以通过各种hack和临时解决方案来解决。问题标签。 尚未建立对诸如Gradle Metadata之类的新技术的支持,但是由于存在问题 ,您可以找到一种解决方案,这就是我们使用的解决方案。

val publishing = project.extensions.getByType(PublishingExtension::class)
publishing.publications
.filterIsInstance<MavenPublication>()
.forEach { publication ->
val moduleFile = project.buildDir.resolve("publications/${publication.name}/module.json")
if (moduleFile.exists()) {
publication.artifact(object : FileBasedMavenArtifact(moduleFile) {
override fun getDefaultExtension() = "module"
})
}
}

With this code, we add to the list of artifacts for publishing the file module.json, which enables Gradle Metadata to work.

通过此代码,我们将添加到工件列表中以发布文件module.json ,从而使Gradle元数据能够正常工作。

However, this is not the last of our problems. When you try to run bintrayPublish, nothing happens.

但是,这不是我们的最后一个问题。 当您尝试运行bintrayPublish ,什么都没有发生。

In the case of regular Java and Kotlin libraries, Bintray automatically takes the available publications and publishes them. However, in the case of Kotlin Multiplatform, the plugin simply crashes with an error. Speaking of which, there is an issue on GitHub for this, too. And we will use the solution from there again, only filtering the publications we need.

对于常规Java和Kotlin库,Bintray会自动获取可用的出版物并将其发布。 但是,在Kotlin Multiplatform的情况下,该插件仅因错误而崩溃。 说到这, GitHub上也有一个问题 。 我们将再次从那里使用该解决方案,只过滤我们需要的出版物。

val publications = publishing.publications
.filterIsInstance<MavenPublication>()
.filter {
val res = taskConfigurationMap[it.name] == true
logger.warn("Artifact '${it.groupId}:${it.artifactId}:${it.version}' from publication '${it.name}' should be published: $res")
res
}
.map {
logger.warn("Uploading artifact '${it.groupId}:${it.artifactId}:${it.version}' from publication '${it.name}'")
it.name
}
.toTypedArray()
setPublications(*publications)

But this code doesn’t work either!

但是此代码也不起作用!

This is because bintrayUpload doesn’t have a task in the dependencies able to build the project and create the files needed for publication. The most obvious solution would be to set publishToMavenLocal as a bintrayUpload dependency, but it’s not as simple as that.

这是因为bintrayUpload在依赖bintrayUpload中没有能够构建项目和创建发布所需文件的任务。 最明显的解决方案是将publishToMavenLocal设置为bintrayUpload依赖项,但这并不那么简单。

When assembling metadata, we set up all of the targets to the project. This means that publishToMavenLocal will result in all of the targets being compiled, as the dependencies for this task are publishToMavenLocalAndroidDebug, publishToMavenLocalAndroiRelase, publishToMavenLocalJvm, etc.

组装元数据时,我们为项目设置了所有目标。 这意味着publishToMavenLocal将导致编译所有目标,因为此任务的依赖项是publishToMavenLocalAndroidDebugpublishToMavenLocalAndroiRelasepublishToMavenLocalJvm等。

We will therefore create a separate proxy task, and we will only put the publishToMavenLocalX tasks that we need in the dependency, and we will put the task itself as a dependency of bintrayPublish.

因此,我们将创建一个单独的代理任务,并且仅将所需的publishToMavenLocalX任务放入依赖项中,并将该任务本身作为bintrayPublish的依赖bintrayPublish

private fun setupLocalPublishing(
target: Project,
taskConfigurationMap: Map<String, Boolean>
) {
target.project.tasks.withType(AbstractPublishToMaven::class).configureEach {
val configuration = publication?.name ?: run {
// The Android-plugin does not immediately set the publication of the PublishToMaven task, which is why we use the heuristic method to find its name
val configuration = taskConfigurationMap.keys.find { name.contains(it, ignoreCase = true) }
logger.warn("Found $configuration for $name")
configuration
}
// We enable or disable the task depending on the current configuration
enabled = taskConfigurationMap[configuration] == true
}
}private fun createFilteredPublishToMavenLocalTask(target: Project) {
// We create a proxy task and set it to depend only on the publishToMavenLocal tasks
target.tasks.register(TASK_FILTERED_PUBLISH_TO_MAVEN_LOCAL) {
dependsOn(project.tasks.matching { it is AbstractPublishToMaven && it.enabled })
}
}

All that is left to do is to assemble all code together and apply the resulting plugin to the project in which publication is required.

剩下要做的就是将所有代码组装在一起,并将生成的插件应用于需要发布的项目。

abstract class PublishPlugin : Plugin<Project> {    
override fun apply(target: Project) {
val taskConfigurationMap = createConfigurationMap()
createFilteredPublishToMavenLocalTask(target)
setupLocalPublishing(target, taskConfigurationMap)
setupBintrayPublishingInformation(target)
setupBintrayPublishing(target, taskConfigurationMap)
}apply plugin: PublishPlugin

You can find the complete PublishPlugin code in our repository here.

你可以找到完整的PublishPlugin在我们的资料库代码在这里

Travis CI配置 (Travis CI configuration)

The hardest part is over. Travis CI still needs to be configured so that it parallelises the assembly and publishes the artifacts in Bintray when a new version is released.

最困难的部分结束了。 仍然需要配置Travis CI,以使其在发布新版本时并行化程序集并在Bintray中发布工件。

When a new version is released, we will create a tag on the commit.

发布新版本时,我们将在提交上创建一个标签。

# We use the matrix build (parallel execution)
matrix:
include:
# On Linux, Android and Chrome to assemble JS, JVM, Android JVM and Linux targets
- os: linux
dist: trusty
addons:
chrome: stable
language: android
android:
components:
- build-tools-28.0.3
- android-28
# We use MP_TARGET in order to set the required target group for assembly
env: MP_TARGET=COMMON
# We can skip the install step — Gradle will bring up all the dependencies itself
install: true
# When assembling in JVM, we also build a compatibility library with RxJava2
script: ./gradlew reaktive:check reaktive-test:check rxjava2-interop:check -DMP_TARGET=$MP_TARGET
# On macOS for assembling iOS-targets
- os: osx
osx_image: xcode10.2
language: java
env: MP_TARGET=IOS
install: true
script: ./gradlew reaktive:check reaktive-test:check -DMP_TARGET=$MP_TARGET
# On Linux to assemble metadata
- os: linux
language: android
android:
components:
- build-tools-28.0.3
- android-28
env: MP_TARGET=META
# Metadata assembly does not require any verification
install: true
script: true
# Recommended Gradle caching settings (to avoid loading all dependencies between builds on the same branch every time)
before_cache:
- rm -f $HOME/.gradle/caches/modules-2/modules-2.lock
- rm -fr $HOME/.gradle/caches/*/plugin-resolution/
cache:
directories:
- $HOME/.gradle/caches/
- $HOME/.gradle/wrapper/
# We start publishing artifacts in Bintray when creating a new tag, this block will be run on each virtual machine from the matrix
deploy:
skip_cleanup: true
provider: script
script: ./gradlew bintrayUpload -DMP_TARGET=$MP_TARGET -Pbintray_user=$BINTRAY_USER -Pbintray_key=$BINTRAY_KEY
on:
tags: true

If for some reason the assembly on one of the virtual machines does not work properly, the metadata and other targets will still be uploaded to the Bintray server. That is why we do not add a block with automatic library release on Bintray through their API.

如果出于某种原因,其中一个虚拟机上的程序集无法正常运行,则元数据和其他目标仍将上载到Bintray服务器。 这就是为什么我们不通过其API在Bintray上添加自动发布库的块的原因。

When the version is released, you need to make sure that everything is in order, and simply click on the button to publish a new version on the site, as all the artifacts are already uploaded.

发布版本后,您需要确保一切都井井有条,只需单击按钮即可在网站上发布新版本,因为所有工件都已上传。

结论 (Conclusion)

We have used this process to set up continuous integration and continuous delivery for our Kotlin Multiplatform project.

我们已经使用此过程为Kotlin Multiplatform项目设置了持续集成和持续交付。

By parallelising the tasks of assembling, running tests and publishing artifacts, we have made effective use of the free resources available to us.

通过并行化组装,运行测试和发布工件的任务,我们有效地利用了可用的免费资源。

And if you use Linux, you no longer need to ask someone using macOS to publish the library every time a new version is released.

而且,如果您使用Linux,则无需在每次发布新版本时要求使用macOS的人发布该库。

I hope that after this article is published, more developers will start using this approach to automate routine actions for their projects.

我希望在本文发表之后,更多的开发人员将开始使用这种方法来自动化其项目的常规操作。

Thanks for reading!

谢谢阅读!

翻译自: https://medium.com/bumble-tech/continuous-delivery-for-your-kotlin-multiplatform-library-3ab5ad5cba59

kotlin库

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值