JetBrains Space ヘルプ

Kotlin コードを実行する

オートメーション DSL は Kotlin に基づいているため、ジョブステップ内で任意の Kotlin コードを実行できます。コンテナーの場合は、コードを kotlinScript ブロック内に置く必要があります。例:

job("Build and publish") { container(displayName = "Run publish script", image = "gradle:6.1.1-jre11") { kotlinScript { api -> api.gradle("build") try { api.gradle("publish") } catch (ex: Exception) { println("Publishing failed") } } } }

内部での動作 (一部簡略化してあります): Space はスクリプトを .jar ファイルにコンパイルし、java -jar script.jar のようなコマンドで実行します。これはスクリプトの実行に使用するイメージには JRE/JDK が含まれている必要があります (バージョン 11 以降) を意味します。

Kotlin コードからのビルドツール、オートメーション機能、Space モジュールの操作

kotlinScript ブロックは、さまざまなヘルパー API を提供します。

  • ビルドツールの使用 (現時点では Gradle のみ)。

  • ビルド関連の情報と機能へのアクセス: Git ブランチ、スクリプト実行番号の取得、ファイル共有へのアクセスなど。

  • Kotlin コードからさまざまな Space モジュール (チャット、ドキュメント、課題など) に直接アクセスします。詳細

API の完全なリストはここで参照してください。

以下の例では、api.gradlew() を使用して Gradle ラッパーを使用してコマンドを実行し、api.gitBranch() を使用して現在のブランチの名前を取得します。

job("Example") { container(image = "gradle:7.1-jre11", displayName = "Use helper APIs") { kotlinScript { api -> api.gradlew("build") // run publish task for release branches if (api.gitBranch().contains("release")) { api.gradlew("publish") } } } }

Maven ライブラリを使用する

kotlinScript を使用すると、外部パッケージの関数を使用できます。これを行うには、@file:DependsOn("$package_name") アノテーションを使用して必要なパッケージを参照する必要があります。$package_name は、Maven セントラル(英語)で使用できるパッケージの名前です。

例: 次のスクリプトは、OkHttp クライアントを使用して example.com のコンテンツを取得し、それをジョブのログに出力します。

@file:DependsOn("com.squareup.okhttp:okhttp:2.7.4") import com.squareup.okhttp.* job("Get example.com") { container(image = "amazoncorretto:17-alpine") { kotlinScript { val client = OkHttpClient() val request = Request.Builder().url("http://example.com").build() val response = client.newCall(request).execute() println(response) } } }

Kotlin を最大限に活用する

オートメーションスクリプトの最も優れた点の 1 つは、フル機能の Kotlin を使用できることです。.space.kts では、クラス、拡張メソッドの作成、コルーチンの使用などを行うことができます。

例: 次のジョブは、複数のファイル (ビルドアーティファクトなど) を HTTP 経由で外部サーバーにアップロードします。これには時間がかかる可能性があるため、ジョブは Kotlin コルーチンを使用してファイルを非同期的にアップロードします。

この例では Ktor HTTP クライアント(英語)を使用します。HTTP リクエストの送信に関する詳細

@file:DependsOn("io.ktor:ktor-client-core:1.6.0", "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.0", "org.jetbrains.kotlinx:kotlinx-coroutines:0.19.2") import io.ktor.client.* import io.ktor.client.call.* import io.ktor.client.request.* import io.ktor.http.* import java.io.File import io.ktor.client.request.forms.* import io.ktor.client.statement.* import io.ktor.utils.io.core.* import kotlinx.coroutines.async import kotlinx.coroutines.runBlocking job("Use Kotlin coroutines") { container(image = "amazoncorretto:17-alpine", displayName = "Upload files to external server") { // get auth token from a project secret env["TOKEN"] = "{{ project:test-secret }}" kotlinScript { val url = "https://external-service.url/upload" val token = System.getenv("TOKEN") // generate random text files // in real life, this could be build artifacts println("Generating files...") val files = FileGenerator.getTxtFiles(10, 100000, "log") // run a coroutine val client = HttpClient() coroutineScope { println("Starting upload...") files.map { file -> launch { val response = client.uploadFile(url, token, file) println("Response from server: ${response.body<String>()}") } }.joinAll() } } } } // upload a file to a remote server suspend fun HttpClient.uploadFile(url: String, authToken: String, file: File): HttpResponse { return this.post("$url/$authToken") { headers { append("Authorization", "Bearer $authToken") } setBody(MultiPartFormDataContent(formData { this.appendInput( key = file.name, headers = Headers.build { append(HttpHeaders.ContentDisposition, "filename=${file.name}") }, size = file.length() ) { buildPacket { writeFully(file.readBytes()) } } })) } } // put all file generation activity in one place object FileGenerator { // create text files with random content // these files emulate output of a build script fun getTxtFiles(numberOfFiles: Int, length: Int, name: String): List<File> { return (0..numberOfFiles) .map { val file = File("$name$it.txt") file.writeText(getRandomString(length)) file } } private fun getRandomString(length: Int) : String { val chars = ('A'..'Z') + ('a'..'z') + ('0'..'9') return (1..length) .map { chars.random() } .joinToString("") } }