diff --git a/.github/workflows/DEPLOY.yml b/.github/workflows/DEPLOY.yml index 945d704..e494c14 100644 --- a/.github/workflows/DEPLOY.yml +++ b/.github/workflows/DEPLOY.yml @@ -18,71 +18,36 @@ on: env: CI: true FORCED_VERSION: ${{ inputs.forced_version || github.ref }} - ORG_GRADLE_PROJECT_signingKey: ${{ secrets.ORG_GRADLE_PROJECT_SIGNINGKEY }} - ORG_GRADLE_PROJECT_signingPassword: ${{ secrets.ORG_GRADLE_PROJECT_SIGNINGPASSWORD }} - SONATYPE_USERNAME: ${{ secrets.SONATYPEUSERNAME }} - SONATYPE_PASSWORD: ${{ secrets.SONATYPEPASSWORD }} - JAVA_VERSION: 17 + # Vanniktech maven-publish plugin reads these exact Gradle project property names for signing + ORG_GRADLE_PROJECT_signingInMemoryKey: ${{ secrets.ORG_GRADLE_PROJECT_SIGNINGKEY }} + ORG_GRADLE_PROJECT_signingInMemoryKeyPassword: ${{ secrets.ORG_GRADLE_PROJECT_SIGNINGPASSWORD }} + # Vanniktech maven-publish plugin reads these for Central Portal auth + ORG_GRADLE_PROJECT_mavenCentralUsername: ${{ secrets.ORG_KORGE_SONATYPE_USERNAME }} + ORG_GRADLE_PROJECT_mavenCentralPassword: ${{ secrets.ORG_KORGE_SONATYPE_PASSWORD }} + JAVA_VERSION: 21 JAVA_DISTRIBUTION: zulu jobs: - ##start: - ## runs-on: ubuntu-latest - ## outputs: - ## stagedRepositoryId: ${{ steps.releaseStep.outputs.stagedRepositoryId }} - ## steps: - ## - { name: Checkout, uses: actions/checkout@v3 } - ## - { name: Set up JDK, uses: actions/setup-java@v3, with: { distribution: "${{ env.JAVA_DISTRIBUTION }}", java-version: "${{ env.JAVA_VERSION }}" } } - ## - { name: Prepare Gradle, uses: gradle/actions/setup-gradle@d9c87d481d55275bb5441eef3fe0e46805f9ef70 } # https://github.com/gradle/actions/releases/tag/v3.5.0 - ## - { id: releaseStep, name: Start Maven Central Staging Repository, run: ./gradlew --no-configuration-cache startReleasingMavenCentral } - publish: strategy: fail-fast: false matrix: include: - - { os: ubuntu-latest, publishTask: "publishLinuxX64PublicationToMavenLocal publishLinuxArm64PublicationToMavenLocal" } - - { os: ubuntu-latest, publishTask: "publishMingwX64PublicationToMavenLocal" } - - { os: ubuntu-latest, publishTask: "publishAndroidDebugPublicationToMavenLocal publishAndroidReleasePublicationToMavenLocal" } - - { os: ubuntu-latest, publishTask: "publishKotlinMultiplatformPublicationToMavenLocal publishJvmPublicationToMavenLocal" } - - { os: ubuntu-latest, publishTask: "publishJsPublicationToMavenLocal publishWasmJsPublicationToMavenLocal" } - - { os: macos-13, publishTask: "publishMacosX64PublicationToMavenLocal publishMacosArm64PublicationToMavenLocal" } - - { os: macos-13, publishTask: "publishTvosArm64PublicationToMavenLocal publishTvosSimulatorArm64PublicationToMavenLocal publishTvosX64PublicationToMavenLocal" } - - { os: macos-13, publishTask: "publishIosArm64PublicationToMavenLocal publishIosSimulatorArm64PublicationToMavenLocal publishIosX64PublicationToMavenLocal" } - - { os: macos-13, publishTask: "publishWatchosArm64PublicationToMavenLocal publishWatchosArm32PublicationToMavenLocal publishWatchosDeviceArm64PublicationToMavenLocal publishWatchosSimulatorArm64PublicationToMavenLocal" } + - { os: ubuntu-latest, publishTask: "publishLinuxX64PublicationToMavenCentral publishLinuxArm64PublicationToMavenCentral" } + - { os: ubuntu-latest, publishTask: "publishMingwX64PublicationToMavenCentral" } + - { os: ubuntu-latest, publishTask: "publishAndroidReleasePublicationToMavenCentral" } + - { os: ubuntu-latest, publishTask: "publishKotlinMultiplatformPublicationToMavenCentral publishJvmPublicationToMavenCentral" } + - { os: ubuntu-latest, publishTask: "publishJsPublicationToMavenCentral publishWasmJsPublicationToMavenCentral" } + - { os: macos-latest, publishTask: "publishMacosX64PublicationToMavenCentral publishMacosArm64PublicationToMavenCentral" } + - { os: macos-latest, publishTask: "publishTvosArm64PublicationToMavenCentral publishTvosSimulatorArm64PublicationToMavenCentral publishTvosX64PublicationToMavenCentral" } + - { os: macos-latest, publishTask: "publishIosArm64PublicationToMavenCentral publishIosSimulatorArm64PublicationToMavenCentral publishIosX64PublicationToMavenCentral" } + - { os: macos-latest, publishTask: "publishWatchosArm64PublicationToMavenCentral publishWatchosArm32PublicationToMavenCentral publishWatchosDeviceArm64PublicationToMavenCentral publishWatchosSimulatorArm64PublicationToMavenCentral" } timeout-minutes: 300 runs-on: ${{ matrix.os }} - ##needs: [start] - ##env: { stagedRepositoryId: "${{ needs.start.outputs.stagedRepositoryId }}" } steps: - ##- { name: Print stagedRepositoryId=$stagedRepositoryId, run: "echo 'stagedRepositoryId: $stagedRepositoryId'" } - - name: Replace MavenLocal with MavenLocal - id: replace - run: | - publishTaskLocal=$(echo "${{ matrix.publishTask }}" | tr -d '\n') - publishTaskRepository=$(echo "${{ matrix.publishTask }}" | sed 's/MavenLocal/MavenRepository/g' | tr -d '\n') - echo "publishTaskLocal=${publishTaskLocal}" >> $GITHUB_ENV - echo "publishTaskRepository=${publishTaskRepository}" >> $GITHUB_ENV - - { name: Print publishTaskLocal, run: "echo 'publishTaskLocal: ${{ env.publishTaskLocal }}'" } - - { name: Print publishTaskRepository, run: "echo 'publishTaskRepository: ${{ env.publishTaskRepository }}'" } - - { name: Checkout, uses: actions/checkout@v3 } - - { name: Use Node.js 20.x, uses: actions/setup-node@v3, with: { node-version: 20.x } } - - { name: Set up JDK, uses: actions/setup-java@v3, with: { distribution: "${{ env.JAVA_DISTRIBUTION }}", java-version: "${{ env.JAVA_VERSION }}" } } - - { name: Prepare Gradle, uses: gradle/actions/setup-gradle@d9c87d481d55275bb5441eef3fe0e46805f9ef70 } # https://github.com/gradle/actions/releases/tag/v3.5.0 - - { name: Initialize Gradle, run: ./gradlew --no-configuration-cache } - - { name: Publish Publications To Maven Local, run: "./gradlew --no-configuration-cache --parallel ${{ env.publishTaskLocal }}" } - - { name: Start Maven Central Staging Repository, run: ./gradlew --no-configuration-cache startReleasingMavenCentral } - - { name: Publish Publications To Maven Repository, run: "./gradlew --no-configuration-cache --parallel --max-workers=8 ${{ env.publishTaskRepository }}" } - - { name: Release to Maven Central, run: ./gradlew --no-configuration-cache releaseMavenCentral } - - ##finalize: - ## runs-on: ubuntu-latest - ## needs: [start, publish] - ## env: { stagedRepositoryId: "${{ needs.start.outputs.stagedRepositoryId }}" } - ## steps: - ## - { name: Checkout, uses: actions/checkout@v3 } - ## - { name: Use Node.js 20.x, uses: actions/setup-node@v3, with: { node-version: 20.x } } - ## - { name: Set up JDK, uses: actions/setup-java@v3, with: { distribution: "${{ env.JAVA_DISTRIBUTION }}", java-version: "${{ env.JAVA_VERSION }}" } } - ## - { name: Prepare Gradle, uses: gradle/actions/setup-gradle@d9c87d481d55275bb5441eef3fe0e46805f9ef70 } # https://github.com/gradle/actions/releases/tag/v3.5.0 - ## - { name: Initialize Gradle, run: ./gradlew --no-configuration-cache } - ## - { name: Release to Maven Central, run: ./gradlew --no-configuration-cache releaseMavenCentral } + - { name: "Checkout", uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd } # https://github.com/actions/checkout/releases/tag/v6.0.2 + - { name: "Use Node.js 24.x", uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f, with: { node-version: 24.x } } # https://github.com/actions/setup-node/releases/tag/v6.3.0 + - { name: "Set up JDK", uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654, with: { distribution: "${{ env.JAVA_DISTRIBUTION }}", java-version: "${{ env.JAVA_VERSION }}" } } # https://github.com/actions/setup-java/releases/tag/v5.2.0 + - { name: "Prepare Gradle", uses: gradle/actions/setup-gradle@39e147cb9de83bb9910b8ef8bd7fff0ee20fcd6f } # https://github.com/gradle/actions/releases/tag/v6.0.1 + - { name: "Initialize Gradle", run: "./gradlew --no-configuration-cache" } + - { name: "Publish to Maven Central", run: "./gradlew --no-configuration-cache --parallel --max-workers=8 ${{ matrix.publishTask }}" } diff --git a/.github/workflows/DOCS.yml b/.github/workflows/DOCS.yml index 9602b73..d39eebb 100644 --- a/.github/workflows/DOCS.yml +++ b/.github/workflows/DOCS.yml @@ -24,7 +24,7 @@ concurrency: env: CI: true FORCED_VERSION: ${{ inputs.forced_version || github.ref }} - JAVA_VERSION: 17 + JAVA_VERSION: 21 JAVA_DISTRIBUTION: zulu jobs: @@ -32,11 +32,11 @@ jobs: timeout-minutes: 300 runs-on: ubuntu-latest steps: - - { name: Checkout, uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 } # https://github.com/actions/checkout/releases/tag/v4.1.7 - - { name: Set up JDK, uses: actions/setup-java@99b8673ff64fbf99d8d325f52d9a5bdedb8483e9, with: { distribution: "${{ env.JAVA_DISTRIBUTION }}", java-version: "${{ env.JAVA_VERSION }}" } } # https://github.com/actions/setup-java/releases/tag/v4.2.1 - - { name: Use Node.js 20.x, uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b, with: { node-version: 20.x } } # https://github.com/actions/setup-node/releases/tag/v4.0.3 - - { name: Prepare Gradle, uses: gradle/actions/setup-gradle@d9c87d481d55275bb5441eef3fe0e46805f9ef70 } # https://github.com/gradle/actions/releases/tag/v3.5.0 - - { name: Initialize Gradle, run: ./gradlew --no-configuration-cache } - - { name: Build Documentation, run: ./gradlew --no-configuration-cache dokkaHtmlMultiModule } - - { name: Upload artifact, uses: actions/upload-pages-artifact@56afc609e74202658d3ffba0e8f6dda462b719fa, with: { path: 'build/dokka/htmlMultiModule' } } # https://github.com/actions/upload-pages-artifact/releases/tag/v3.0.1 - - { name: Deploy 🚀 to GitHub Pages, id: deployment, uses: actions/deploy-pages@d6db90164ac5ed86f2b6aed7e0febac5b3c0c03e} # https://github.com/actions/deploy-pages/releases/tag/v4.0.5 + - { name: "Checkout", uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd } # https://github.com/actions/checkout/releases/tag/v6.0.2 + - { name: "Use Node.js 24.x", uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f, with: { node-version: 24.x } } # https://github.com/actions/setup-node/releases/tag/v6.3.0 + - { name: "Set up JDK", uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654, with: { distribution: "${{ env.JAVA_DISTRIBUTION }}", java-version: "${{ env.JAVA_VERSION }}" } } # https://github.com/actions/setup-java/releases/tag/v5.2.0 + - { name: "Prepare Gradle", uses: gradle/actions/setup-gradle@39e147cb9de83bb9910b8ef8bd7fff0ee20fcd6f } # https://github.com/gradle/actions/releases/tag/v6.0.1 + - { name: "Initialize Gradle", run: "./gradlew --no-configuration-cache" } + - { name: "Build Documentation", run: "./gradlew --no-configuration-cache dokkaGenerateHtml" } + - { name: "Upload artifact", uses: actions/upload-pages-artifact@7b1f4a764d45c48632c6b24a0339c27f5614fb0b, with: { path: 'korlibs-image-core/build/dokka/html' } } # https://github.com/actions/upload-pages-artifact/releases/tag/v4.0.0 + - { name: "Deploy 🚀 to GitHub Pages", id: deployment, uses: actions/deploy-pages@cd2ce8fcbc39b97be8ca5fce6e763baed58fa128 } # https://github.com/actions/deploy-pages/releases/tag/v5.0.0 diff --git a/.github/workflows/TEST.yml b/.github/workflows/TEST.yml index 6d6d86d..20462f4 100644 --- a/.github/workflows/TEST.yml +++ b/.github/workflows/TEST.yml @@ -26,42 +26,42 @@ concurrency: env: CI: true - JAVA_VERSION: 17 - JAVA_DISTRIBUTION: temurin + JAVA_VERSION: 21 + JAVA_DISTRIBUTION: zulu jobs: test: strategy: - #fail-fast: true # Once working, comment this + fail-fast: true matrix: include: - { outputKey: testMacosIos, os: macos-latest, testTask: jvmTest macosArm64Test iosSimulatorArm64Test, buildTasks: publishMacosX64PublicationToMavenLocal } - - { outputKey: testJsAndroid, os: ubuntu-latest, testTask: "wasmBrowserTest", buildTasks: "jsBrowserTest jsDenoTest", enableAndroid: true } + - { outputKey: testJsAndroid, os: ubuntu-latest, testTask: "wasmBrowserTest", buildTasks: "jsBrowserTest jsDenoTest", upgradeYarnLock: true, enableAndroid: true } - { outputKey: testLinux, os: ubuntu-latest, testTask: apiCheck jvmTest linuxX64Test, precompileTask: compileTestKotlinJvm, enableCodecov: true, e2e: true } - - { outputKey: testWindows, os: windows-latest, testTask: jvmTest mingwX64Test jsDenoTest, precompileTask: compileTestKotlinJvm } - #if: ${{ needs.changes.outputs[matrix.outputKey] == 'true' }} + - { outputKey: testWindows, os: windows-latest, testTask: jvmTest mingwX64Test jsDenoTest, precompileTask: compileTestKotlinJvm, upgradeYarnLock: true } timeout-minutes: 60 runs-on: ${{ matrix.os }} steps: - - { uses: actions/checkout@v4 } - - { name: Use Node.js 20.x, uses: actions/setup-node@v4, with: { node-version: 20.x } } - - { name: Setup Deno, uses: denoland/setup-deno@v1, with: { deno-version: "1.44.4" } } - - { name: Set up JDK, uses: actions/setup-java@v4, with: { distribution: "${{ env.JAVA_DISTRIBUTION }}", java-version: "${{ env.JAVA_VERSION }}", cache: 'gradle' } } - #- { name: Prepare Gradle, uses: gradle/actions/setup-gradle@af1da67850ed9a4cedd57bfd976089dd991e2582 } # https://github.com/gradle/actions/releases/tag/v4.0.0 - - { name: "Cache Kotlin/Native .konan folder", uses: actions/cache@v4, with: { path: "~/.konan", key: "${{ runner.os }}-konan", restore-keys: "${{ runner.os }}-konan" } } + - { name: "Checkout", uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd } # https://github.com/actions/checkout/releases/tag/v6.0.2 + - { name: "Use Node.js 24.x", uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f, with: { node-version: 24.x } } # https://github.com/actions/setup-node/releases/tag/v6.3.0 + - { name: "Setup Deno", uses: denoland/setup-deno@e95548e56dfa95d4e1a28d6f422fafe75c4c26fb, with: { deno-version: "2.7.11" } } # https://github.com/denoland/setup-deno/releases/tag/v2.0.3 + - { name: "Set up JDK", uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654, with: { distribution: "${{ env.JAVA_DISTRIBUTION }}", java-version: "${{ env.JAVA_VERSION }}" } } # https://github.com/actions/setup-java/releases/tag/v5.2.0 + - { name: "Prepare Gradle", uses: gradle/actions/setup-gradle@39e147cb9de83bb9910b8ef8bd7fff0ee20fcd6f } # https://github.com/gradle/actions/releases/tag/v6.0.1 + - { name: "Cache Kotlin/Native .konan folder", uses: actions/cache@668228422ae6a00e4ad889ee87cd7109ec5666a7, with: { path: "~/.konan", key: "${{ runner.os }}-konan", restore-keys: "${{ runner.os }}-konan" } } # https://github.com/actions/cache/releases/tag/v5.0.4 - { name: Start gradle, run: ./gradlew } + - { if: "${{ matrix.upgradeYarnLock }}", name: "Upgrade yarn lock", run: "./gradlew kotlinUpgradeYarnLock" } - { if: "${{ matrix.precompileTask }}", name: "Building ${{ matrix.precompileTask }} classes", run: "./gradlew --stacktrace ${{ matrix.precompileTask }}" } - { if: "${{ matrix.testTask }}", name: "Run ${{ matrix.testTask }} tests", run: "./gradlew ${{ matrix.testTask }}" } - { if: "${{ matrix.buildTasks }}", name: "Run ${{ matrix.buildTasks }}", run: "./gradlew ${{ matrix.buildTasks }}" } - - name: Enable KVM + - name: "Enable KVM" if: "${{ matrix.enableAndroid }}" run: | echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules sudo udevadm control --reload-rules sudo udevadm trigger --name-match=kvm - - { name: "Run Android Tests", if: "${{ matrix.enableAndroid }}", uses: reactivecircus/android-emulator-runner@v2, with: { "api-level": 21, "script": "./gradlew connectedCheck lintDebug" } } - - { name: Archive Test Results, if: failure(), uses: actions/upload-artifact@v4, with: { name: "test-results-${{ matrix.outputKey }}", retention-days: 21, path: "**/build/reports", if-no-files-found: ignore } } - - { if: "${{ matrix.e2e }}", name: Publish to maven local, run: ./gradlew publishJvmLocal publishKotlinMultiplatformPublicationToMavenLocal } - - { if: "${{ matrix.enableCodecov }}", name: Code coverage, run: ./gradlew koverXmlReport } - - { if: "${{ matrix.enableCodecov }}", name: "Upload coverage reports to Codecov", uses: "codecov/codecov-action@e28ff129e5465c2c0dcc6f003fc735cb6ae0c673", with: { token: "${{ secrets.CODECOV_TOKEN }}" } } # https://github.com/codecov/codecov-action/releases/tag/v4.5.0 - - { name: Stop daemon, run: ./gradlew --stop } + - { name: "Run Android Tests", if: "${{ matrix.enableAndroid }}", uses: reactivecircus/android-emulator-runner@e89f39f1abbbd05b1113a29cf4db69e7540cae5a, with: { "api-level": 21, "script": "./gradlew connectedCheck lintDebug" } } # https://github.com/ReactiveCircus/android-emulator-runner/releases/tag/v2.37.0 + - { name: "Archive Test Results", if: failure(), uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f, with: { name: "test-results-${{ matrix.outputKey }}", retention-days: 21, path: "**/build/reports", if-no-files-found: ignore } } # https://github.com/actions/upload-artifact/releases/tag/v7.0.0 + - { name: "Publish to maven local", if: "${{ matrix.e2e }}", run: "./gradlew publishJvmLocal publishKotlinMultiplatformPublicationToMavenLocal" } + - { name: "Code coverage", if: "${{ matrix.enableCodecov }}", run: "./gradlew koverXmlReport" } + - { name: "Upload coverage reports to Codecov", if: "${{ matrix.enableCodecov }}", uses: codecov/codecov-action@57e3a136b779b570ffcdbf80b3bdc90e7fab3de2, with: { token: "${{ secrets.CODECOV_TOKEN }}" } } # https://github.com/codecov/codecov-action/releases/tag/v6.0.0 + - { name: "Stop daemon", run: "./gradlew --stop" } diff --git a/README.md b/README.md index ef017e2..32f7ad1 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [![test](https://github.com/korlibs/korlibs-image-core/actions/workflows/TEST.yml/badge.svg)](https://github.com/korlibs/korlibs-image-core/actions/workflows/TEST.yml) [![codecov](https://codecov.io/gh/korlibs/korlibs-image-core/graph/badge.svg)](https://codecov.io/gh/korlibs/korlibs-image-core) -[![Maven Central Version](https://img.shields.io/maven-central/v/com.soywiz/korlibs-image-core)](https://central.sonatype.com/artifact/com.soywiz/korlibs-image-core) +[![Maven Central Version](https://img.shields.io/maven-central/v/org.korge/korlibs-image-core)](https://central.sonatype.com/artifact/org.korge/korlibs-image-core) [![Discord](https://img.shields.io/discord/728582275884908604?logo=discord&label=Discord)](https://discord.korge.org/) [![KDoc](https://img.shields.io/badge/docs-kdoc-blue)](https://korlibs.github.io/korlibs-image-core/) [![Documentation](https://img.shields.io/badge/docs-documentation-purple)](https://docs.korge.org/image-core/) diff --git a/build.gradle.kts b/build.gradle.kts index 4c9156a..7f21e86 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,28 +1,18 @@ -import com.google.gson.* -import com.google.gson.JsonParser -import groovy.json.* -import groovy.util.* +import com.vanniktech.maven.publish.* import org.gradle.api.internal.tasks.testing.* import org.gradle.api.tasks.testing.logging.* -import org.gradle.jvm.tasks.Jar -import org.gradle.plugins.signing.signatory.internal.pgp.* -import org.jetbrains.dokka.gradle.* import org.jetbrains.kotlin.gradle.dsl.* import org.jetbrains.kotlin.gradle.plugin.* import org.jetbrains.kotlin.gradle.targets.js.ir.* -import java.net.* import java.util.* -import java.util.concurrent.* plugins { - kotlin("multiplatform") version "2.0.10" - id("com.android.library") version "8.2.2" - id("org.jetbrains.kotlinx.kover") version "0.8.3" apply false - id("org.jetbrains.kotlinx.binary-compatibility-validator") version "0.16.2" - id("org.jetbrains.dokka") version "1.9.20" - //id("org.ysb33r.ivypot") version "1.0.0" - `maven-publish` - signing + kotlin("multiplatform") version "2.3.20" + id("com.android.library") version "8.13.1" + id("org.jetbrains.kotlinx.kover") version "0.9.3" apply false + id("org.jetbrains.kotlinx.binary-compatibility-validator") version "0.18.1" + id("org.jetbrains.dokka") version "2.1.0" + id("com.vanniktech.maven.publish") version "0.36.0" apply false } var REAL_VERSION = System.getenv("FORCED_VERSION") @@ -36,10 +26,12 @@ var REAL_VERSION = System.getenv("FORCED_VERSION") //val REAL_VERSION = System.getenv("FORCED_VERSION") ?: "999.0.0.999" val JVM_TARGET = JvmTarget.JVM_1_8 -val JDK_VERSION = org.gradle.api.JavaVersion.VERSION_1_8 -//val JVM_TARGET = JvmTarget.JVM_11 -//val JDK_VERSION = org.gradle.api.JavaVersion.VERSION_11 -val GROUP = "com.soywiz" +// JDK_VERSION controls Android compileOptions source/target compat only. +// The Kotlin/JVM toolchain is not forced to a specific version to avoid +// toolchain auto-provisioning failures in environments without network access. +// Bytecode output for Kotlin targets is controlled by JVM_TARGET (1.8) above. +val JDK_VERSION = JavaVersion.VERSION_1_8 +val GROUP = "org.korge" kotlin { jvm() @@ -61,22 +53,11 @@ allprojects { project.apply(plugin = "kotlin-multiplatform") project.apply(plugin = "android-library") - java.toolchain.languageVersion = JavaLanguageVersion.of(JDK_VERSION.majorVersion) - kotlin.jvmToolchain(JDK_VERSION.majorVersion.toInt()) - afterEvaluate { - tasks.withType(Test::class) { - //this.javaLauncher.set() - this.javaLauncher.set(javaToolchains.launcherFor { - // 17 is latest at the current moment - languageVersion.set(JavaLanguageVersion.of(JDK_VERSION.majorVersion)) - }) - } - } - android { compileOptions { - sourceCompatibility = JDK_VERSION - targetCompatibility = JDK_VERSION + // Keep Android bytecode at Java 8 regardless of toolchain JDK version + sourceCompatibility = JavaVersion.VERSION_1_8 + targetCompatibility = JavaVersion.VERSION_1_8 } //signingConfigs { // debug { @@ -87,7 +68,7 @@ allprojects { // } //} compileSdk = 33 - namespace = "com.soywiz.${project.name.replace("-", ".")}" + namespace = "org.korge.${project.name.replace("-", ".")}" defaultConfig { minSdk = 20 } @@ -110,20 +91,20 @@ allprojects { MicroAmper(this).configure() } -fun Project.doOnce(uniqueName: String, block: () -> Unit) { - val key = "doOnce-$uniqueName" - if (!rootProject.extra.has(key)) { - rootProject.extra.set(key, true) - block() - } -} - - open class DenoTestTask : AbstractTestTask() { //open class DenoTestTask : KotlinTest() { //var isDryRun by org.jetbrains.kotlin.gradle.utils.property { false } + @get:Internal + val projectPathName: String = project.path.trim(':').replace(':', '-') + + @get:Internal + val rootDir: File = project.rootProject.rootDir + + @get:Internal + val projectDir: File = project.projectDir + init { this.group = "verification" this.dependsOn("compileTestDevelopmentExecutableKotlinJs") @@ -146,7 +127,7 @@ open class DenoTestTask : AbstractTestTask() { } override fun createTestExecuter(): TestExecuter { - return DenoTestExecuter(this.project, this.filter) + return DenoTestExecuter(projectPathName, rootDir, projectDir, this.filter) } //override fun createTestExecuter(): TestExecuter = TODO() override fun createTestExecutionSpec(): TestExecutionSpec = DenoTestExecutionSpec() @@ -155,17 +136,11 @@ open class DenoTestTask : AbstractTestTask() { outputs.upToDateWhen { false } } - class DenoTestExecuter(val project: Project, val filter: TestFilter) : TestExecuter { - private fun Project.fullPathName(): String { - //KotlinTest - if (this.parent == null) return this.name - return this.parent!!.fullPathName() + ":" + this.name - } - + class DenoTestExecuter(val projectPathName: String, val rootDir: File, val projectDir: File, val filter: TestFilter) : TestExecuter { override fun execute(testExecutionSpec: DenoTestExecutionSpec, testResultProcessor: TestResultProcessor) { - val baseTestFileNameBase = this.project.fullPathName().trim(':').replace(':', '-') + "-test" + val baseTestFileNameBase = "$projectPathName-test" val baseTestFileName = "$baseTestFileNameBase.mjs" - val runFile = File(this.project.rootProject.rootDir, "build/js/packages/$baseTestFileNameBase/kotlin/$baseTestFileName.deno.mjs") + val runFile = File(rootDir, "build/js/packages/$baseTestFileNameBase/kotlin/$baseTestFileName.deno.mjs") runFile.parentFile.mkdirs() runFile.writeText( @@ -192,7 +167,7 @@ open class DenoTestTask : AbstractTestTask() { if (filter.includePatterns.isEmpty()) { add("--filter=${filter.includePatterns.joinToString(",")}") } - add("--junit-path=${project.file("build/test-results/jsDenoTest/junit.xml").absolutePath}") + add("--junit-path=${File(projectDir, "build/test-results/jsDenoTest/junit.xml").absolutePath}") add(runFile.absolutePath) }).directory(runFile.parentFile) .start() @@ -213,7 +188,6 @@ open class DenoTestTask : AbstractTestTask() { else -> TestResult.ResultType.SUCCESS } if (type == TestResult.ResultType.FAILURE) { - testResultProcessor.output(currentTestId, DefaultTestOutputEvent(TestOutputEvent.Destination.StdErr, "FAILED\n")) testResultProcessor.failure(currentTestId, DefaultTestFailure.fromTestFrameworkFailure(Exception("FAILED").also { it.stackTrace = arrayOf() }, null)) failedCount++ } @@ -238,7 +212,7 @@ open class DenoTestTask : AbstractTestTask() { capturingOutput = false } capturingOutput -> { - testResultProcessor.output(currentTestId, DefaultTestOutputEvent(TestOutputEvent.Destination.StdOut, "$line\n")) + // Avoid deprecated DefaultTestOutputEvent constructor usage. } line.contains("...") -> { //DefaultNestedTestSuiteDescriptor() @@ -273,97 +247,60 @@ open class DenoTestTask : AbstractTestTask() { class DenoTestExecutionSpec : TestExecutionSpec } -class SonatypeProps(val project: Project) { - // Signing - val signingKey: String? = System.getenv("ORG_GRADLE_PROJECT_signingKey") ?: project.findProperty("signing.signingKey")?.toString() - val signingPassword: String? = System.getenv("ORG_GRADLE_PROJECT_signingPassword") ?: project.findProperty("signing.password")?.toString() - val globalSignatories: CachedInMemoryPgpSignatoryProvider? = when { - signingKey != null && signingPassword != null -> CachedInMemoryPgpSignatoryProvider(signingKey, signingPassword) - else -> null - } - - val sonatypePublishUserNull: String? = - (System.getenv("SONATYPE_USERNAME") ?: rootProject.findProperty("SONATYPE_USERNAME")?.toString() ?: project.findProperty("sonatypeUsername") - ?.toString()) - val sonatypePublishPasswordNull: String? = - (System.getenv("SONATYPE_PASSWORD") ?: rootProject.findProperty("SONATYPE_PASSWORD")?.toString() ?: project.findProperty("sonatypePassword") - ?.toString()) - val sonatype: Sonatype? = when { - sonatypePublishUserNull != null && sonatypePublishPasswordNull != null -> Sonatype(sonatypePublishUserNull, sonatypePublishPasswordNull) - else -> null - } - - val stagedRepositoryId: String? by lazy { - System.getenv("stagedRepositoryId") - ?: findProperty("stagedRepositoryId")?.toString() - ?: File("stagedRepositoryId").takeIf { it.exists() }?.readText()?.trim() - } - - open class StartReleasingMavenCentral : DefaultTask() { - @Input - @Optional - var sonatype: Sonatype? = null - - @TaskAction - fun action() { - val profileId = sonatype!!.findProfileIdByGroupId("com.soywiz") - val stagedRepositoryId = sonatype!!.startStagedRepository(profileId) - println("profileId=$profileId") - println("stagedRepositoryId=$stagedRepositoryId") - GithubCI.setOutput("stagedRepositoryId", stagedRepositoryId) - File("stagedRepositoryId").writeText(stagedRepositoryId) - } - } - - open class ReleaseMavenCentralTask : DefaultTask() { - @Input - @Optional - var sonatype: Sonatype? = null - - @Input - @Optional - var repositoryId: String? = null - - @TaskAction - fun action() { - //if (!sonatype.releaseGroupId(rootProject.group.toString())) { - try { - if (!sonatype!!.releaseRepositoryID(repositoryId)) { - error("Can't promote artifacts. Check log for details") - } - } finally { - File("stagedRepositoryId").delete() - } - - } - } - - fun createTasks(project: Project) = with(project) { - if (sonatype != null) { - tasks.create("startReleasingMavenCentral", StartReleasingMavenCentral::class) { - this.sonatype = this@SonatypeProps.sonatype - } - rootProject.tasks.create("releaseMavenCentral") { - this.sonatype = this@SonatypeProps.sonatype - this.repositoryId = this@SonatypeProps.stagedRepositoryId - } - } - - if (stagedRepositoryId != null) { - println("stagedRepositoryId=$stagedRepositoryId") - } - } +private fun Project.configureCentralPortalCompatibilityProps() { + // Map legacy env/property names to the exact names the Vanniktech plugin expects. + // Vanniktech reads: signingInMemoryKey, signingInMemoryKeyPassword, mavenCentralUsername, mavenCentralPassword + val extras = extensions.extraProperties + + fun mapIfAbsent(targetKey: String, vararg sources: () -> String?) { + // Skip if already set to a non-blank value via extras or project properties + if (extras.has(targetKey) && extras[targetKey]?.toString().isNullOrBlank().not()) return + if (findProperty(targetKey)?.toString().isNullOrBlank().not()) return + // Find the first non-blank value among the sources + val value = sources.firstNotNullOfOrNull { it()?.takeIf { v -> v.isNotBlank() } } ?: return + extras[targetKey] = value + } + + mapIfAbsent("signingInMemoryKey", + { System.getenv("ORG_GRADLE_PROJECT_signingInMemoryKey") }, + { System.getenv("ORG_GRADLE_PROJECT_signingKey") }, + { findProperty("signing.signingKey")?.toString() } + ) + mapIfAbsent("signingInMemoryKeyPassword", + { System.getenv("ORG_GRADLE_PROJECT_signingInMemoryKeyPassword") }, + { System.getenv("ORG_GRADLE_PROJECT_signingPassword") }, + { findProperty("signing.password")?.toString() } + ) + mapIfAbsent("mavenCentralUsername", + { System.getenv("ORG_GRADLE_PROJECT_mavenCentralUsername") }, + { System.getenv("SONATYPE_USERNAME") }, + { rootProject.findProperty("SONATYPE_USERNAME")?.toString() }, + { findProperty("sonatypeUsername")?.toString() } + ) + mapIfAbsent("mavenCentralPassword", + { System.getenv("ORG_GRADLE_PROJECT_mavenCentralPassword") }, + { System.getenv("SONATYPE_PASSWORD") }, + { rootProject.findProperty("SONATYPE_PASSWORD")?.toString() }, + { findProperty("sonatypePassword")?.toString() } + ) } -val sonatypeProps = SonatypeProps(rootProject) - -sonatypeProps.createTasks(rootProject) +private fun Project.hasSigningCredentials(): Boolean { + // A credential is only considered present when it resolves to a non-blank string. + fun String?.isPresent() = !isNullOrBlank() + return System.getenv("ORG_GRADLE_PROJECT_signingInMemoryKey").isPresent() || + System.getenv("ORG_GRADLE_PROJECT_signingKey").isPresent() || + findProperty("signingInMemoryKey")?.toString().isPresent() || + findProperty("signing.secretKeyRingFile")?.toString().isPresent() || + extensions.extraProperties.runCatching { get("signingInMemoryKey")?.toString() }.getOrNull().isPresent() +} subprojects { //apply() apply(plugin = "kotlin-multiplatform") - apply(plugin = "maven-publish") - apply(plugin = "signing") + apply(plugin = "com.vanniktech.maven.publish") + + configureCentralPortalCompatibilityProps() kotlin { js { @@ -380,7 +317,7 @@ subprojects { //if (targets.any { it.name.contains("android") }) { androidTarget { this.compilerOptions.jvmTarget.set(JVM_TARGET) - publishAllLibraryVariants() + publishLibraryVariants("release") //publishLibraryVariants("release", "debug") } //} @@ -391,8 +328,7 @@ subprojects { //println(this.findByName("compileTestKotlinJs")!!.dependsOn?.toList()) //println(this.findByName("compileTestKotlinJs")?.outputs?.files?.toList()) - val jsDenoTest by creating(DenoTestTask::class) { - } + val jsDenoTest by registering(DenoTestTask::class) } tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompilationTask::class) { @@ -406,7 +342,7 @@ subprojects { //} tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinNativeLink::class) { - // /Users/soywiz/projects/korge-korlibs/korlibs-io/build/bin/iosSimulatorArm64/debugTest + // /Users/korge/projects/korge-korlibs/korlibs-io/build/bin/iosSimulatorArm64/debugTest //println(this.target) //val target = Regex("^link(.*?)Test.*$").find(this.name)?.groupValues?.getOrNull(1)?.replaceFirstChar { it.lowercaseChar() } //println(target) @@ -417,9 +353,10 @@ subprojects { val fromFolder = File(project.projectDir, "testresources") if (folder != null) { - val copyAfterLink = tasks.create("${this.name}CopyResources", Copy::class) - copyAfterLink.from(fromFolder) - copyAfterLink.into(folder) + val copyAfterLink = tasks.register("${this.name}CopyResources", Copy::class.java) { + from(fromFolder) + into(folder) + } this.dependsOn(copyAfterLink) } } @@ -486,9 +423,10 @@ subprojects { for (taskName in listOf("jsTestProcessResources", "wasmTestProcessResources")) { tasks.findByName(taskName)?.apply { - this.dependsOn(tasks.create("${taskName}CopyResources", TestProcessResourcesLast::class).also { - it.dirs = this.outputs.files.toList().filter { it.isDirectory } - }) + val copyResourcesTask = tasks.register("${taskName}CopyResources", TestProcessResourcesLast::class.java) { + dirs = this@apply.outputs.files.toList().filter { it.isDirectory } + } + this.dependsOn(copyResourcesTask) } } @@ -507,369 +445,39 @@ subprojects { //println(tasks.findByName("jsProcessResources")!!::class) // Publishing - run { - publishing { - repositories { - if (sonatypeProps.sonatype != null) { - maven { - credentials { - username = sonatypeProps.sonatype.user - password = sonatypeProps.sonatype.pass - } - url = when { - version.toString().contains("-SNAPSHOT") -> uri("https://oss.sonatype.org/content/repositories/snapshots/") - sonatypeProps.stagedRepositoryId != null -> uri("https://oss.sonatype.org/service/local/staging/deployByRepositoryId/${sonatypeProps.stagedRepositoryId}/") - else -> uri("https://oss.sonatype.org/service/local/staging/deploy/maven2/") - } - doOnce("showDeployTo") { logger.info("DEPLOY mavenRepository: $url") } - } - } - } - - publications.withType(MavenPublication::class) { - //println(this.artifacts.stream().map { it.file }) - //copyArtifactsToDirectory.get().from(this.artifacts.stream().map { it.file }) - - val publication = this - val jarTaskName = "${publication.name}JavadocJar" - //println(jarTaskName) - val javadocJar = tasks.create(jarTaskName) { - archiveClassifier.set("javadoc") - archiveBaseName.set(jarTaskName) - } - publication.artifact(javadocJar) - - //println("PUBLICATION: ${publication.name}") - - fun getCustomProp(key: String, defaultValue: String): String { - // @TODO: Actually be able to override it - return defaultValue - } - - //if (multiplatform) { - //if (!isGradlePluginMarker) { - run { - val defaultGitUrl = "https://github.com/korlibs/korge-korlibs" - publication.pom.also { pom -> - pom.name.set(project.name) - pom.description.set(project.description ?: getCustomProp("project.description", project.description ?: project.name)) - pom.url.set(getCustomProp("project.scm.url", defaultGitUrl)) - pom.licenses { - license { - name.set(getCustomProp("project.license.name", "MIT")) - url.set(getCustomProp("project.license.url", "https://raw.githubusercontent.com/korlibs/korge-korlibs/main/LICENSE")) - } - } - pom.developers { - developer { - id.set(getCustomProp("project.author.id", "soywiz")) - name.set(getCustomProp("project.author.name", "Carlos Ballesteros Velasco")) - email.set(getCustomProp("project.author.email", "soywiz@gmail.com")) - } - } - pom.scm { - url.set(getCustomProp("project.scm.url", defaultGitUrl)) - } - } - publication.pom.withXml { - val root = NodeList(listOf(this@withXml.asNode())) - //println("baseProjectName=$baseProjectName") - val packaging = root.getAt("packaging").text() - //println("---------------") - //println("root=$root") - //println("packaging=" + (root.getAt("packaging"))) - //println("packaging=" + root.getAt("packaging")) - //println("packaging.text=" + root.getAt("packaging").text()) - if (packaging == "aar") { - val nodes: NodeList = root.getAt("dependencies").getAt("dependency").getAt("scope") - for (node in nodes as List) { - node.setValue("compile") - //println("node=$node setValue=compile") - } - } - } - } - } - } - - - } - - // Signing - if (sonatypeProps.globalSignatories != null) { - signing { - sign(publishing.publications) - this.signatories = sonatypeProps.globalSignatories - } - } - - //println(KotlinCompilerVersion.VERSION) -} - -open class CachedInMemoryPgpSignatoryProvider(signingKey: String?, signingPassword: String?) : InMemoryPgpSignatoryProvider(signingKey, signingPassword) { - var cachedPhpSignatory: PgpSignatory? = null - override fun getDefaultSignatory(project: Project): PgpSignatory? { - //project.rootProject - //println("getDefaultSignatory:$project") - if (cachedPhpSignatory == null) { - cachedPhpSignatory = super.getDefaultSignatory(project) - } - return cachedPhpSignatory - } -} - - -open class Sonatype( - val user: String, - val pass: String, - val BASE: String = DEFAULT_BASE -) { - companion object { - val DEFAULT_BASE = "https://oss.sonatype.org/service/local/staging" - private val BASE = DEFAULT_BASE - - //fun fromGlobalConfig(): Sonatype { - // val props = Properties().also { it.load(File(System.getProperty("user.home") + "/.gradle/gradle.properties").readText().reader()) } - // return Sonatype(props["sonatypeUsername"].toString(), props["sonatypePassword"].toString(), DEFAULT_BASE) - //} - - //fun fromProject(project: Project): Sonatype { - // return Sonatype(project.sonatypePublishUser, project.sonatypePublishPassword) - //} - - //@JvmStatic - //fun main(args: Array) { - // val sonatype = fromGlobalConfig() - // sonatype.releaseGroupId("korlibs") - //} - } - - fun releaseGroupId(groupId: String = "korlibs"): Boolean { - println("Trying to release groupId=$groupId") - val profileId = findProfileIdByGroupId(groupId) - println("Determined profileId=$profileId") - val repositoryIds = findProfileRepositories(profileId) - if (repositoryIds.isEmpty()) { - println("Can't find any repositories for profileId=$profileId for groupId=$groupId. Artifacts weren't upload?") - return false - } - return releaseRepositoryIDs(repositoryIds) - } - - fun releaseRepositoryID(repositoryId: String?): Boolean { - val repositoryIds = listOfNotNull(repositoryId) - if (repositoryIds.isEmpty()) return false - return releaseRepositoryIDs(repositoryIds) - } - - fun releaseRepositoryIDs(repositoryIds: List): Boolean { - val repositoryIds = repositoryIds.toMutableList() - val totalRepositories = repositoryIds.size - var promoted = 0 - var stepCount = 0 - var retryCount = 0 - process@while (true) { - stepCount++ - if (stepCount > 200) { - error("Too much steps. stepCount=$stepCount") - } - repo@for (repositoryId in repositoryIds.toList()) { - val state = try { - getRepositoryState(repositoryId) - } catch (e: SimpleHttpException) { - when (e.responseCode) { - 404 -> { - println("Can't find $repositoryId anymore. Probably released. Stopping") - repositoryIds.remove(repositoryId) - continue@repo - } - else -> throw e - } - } - when { - state.transitioning -> { - println("Waiting transition $state") - } - // Even if open, if there are notifications we should drop it - state.notifications > 0 -> { - println("Dropping release because of error state.notifications=$state") - println(" - activity: " + getRepositoryActivity(repositoryId)) - repositoryDrop(repositoryId) - repositoryIds.remove(repositoryId) - } - state.isOpen -> { - println("Closing open repository $state") - println(" - activity: " + getRepositoryActivity(repositoryId)) - repositoryClose(repositoryId) - } - else -> { - println("Promoting repository $state") - println(" - activity: " + getRepositoryActivity(repositoryId)) - repositoryPromote(repositoryId) - promoted++ - } + extensions.configure { + if (project.hasSigningCredentials()) { + publishToMavenCentral() + signAllPublications() + } + + coordinates(project.group.toString(), project.name, project.version.toString()) + + pom { + val defaultGitUrl = "https://github.com/korlibs/korlibs" + name.set(project.name) + description.set(project.description ?: project.name) + url.set(defaultGitUrl) + licenses { + license { + name.set("MIT") + url.set("https://raw.githubusercontent.com/korlibs/korge/refs/heads/main/LICENSE") } } - if (repositoryIds.isEmpty()) { - println("Completed promoted=$promoted, totalRepositories=$totalRepositories, retryCount=$retryCount") - break@process - } - Thread.sleep(30_000L) - } - - return promoted == totalRepositories - } - - private val client get() = SimpleHttpClient(user, pass) - - fun getRepositoryState(repositoryId: String): RepoState { - val info = client.requestWithRetry("${BASE}/repository/$repositoryId") - //println("info: ${info.toStringPretty()}") - return RepoState( - repositoryId = repositoryId, - type = info["type"].asString, - notifications = info["notifications"].asInt, - transitioning = info["transitioning"].asBoolean, - ) - } - - fun getRepositoryActivity(repositoryId: String): String { - val info = client.requestWithRetry("${BASE}/repository/$repositoryId/activity") - //println("info: ${info.toStringPretty()}") - return info.toStringPretty() - } - - data class RepoState( - val repositoryId: String, - // "open" or "closed" - val type: String, - val notifications: Int, - val transitioning: Boolean - ) { - val isOpen get() = type == "open" - } - - private fun getDataMapForRepository(repositoryId: String): Map> { - return mapOf( - "data" to mapOf( - "stagedRepositoryIds" to listOf(repositoryId), - "description" to "", - "autoDropAfterRelease" to true, - ) - ) - } - - fun repositoryClose(repositoryId: String) { - client.requestWithRetry("${BASE}/bulk/close", getDataMapForRepository(repositoryId)) - } - - fun repositoryPromote(repositoryId: String) { - client.requestWithRetry("${BASE}/bulk/promote", getDataMapForRepository(repositoryId)) - } - - fun repositoryDrop(repositoryId: String) { - client.requestWithRetry("${BASE}/bulk/drop", getDataMapForRepository(repositoryId)) - } - - fun findProfileRepositories(profileId: String): List { - return client.requestWithRetry("${BASE}/profile_repositories")["data"].list - .filter { it["profileId"].asString == profileId } - .map { it["repositoryId"].asString } - } - - fun findProfileIdByGroupId(groupId: String): String { - val profiles = client.requestWithRetry("$BASE/profiles")["data"].list - return profiles - .filter { groupId.startsWith(it["name"].asString) } - .map { it["id"].asString } - .firstOrNull() ?: error("Can't find profile with group id '$groupId'") - } - - fun startStagedRepository(profileId: String): String { - return client.requestWithRetry("${BASE}/profiles/$profileId/start", mapOf( - "data" to mapOf("description" to "Explicitly created by easy-kotlin-mpp-gradle-plugin") - ))["data"]["stagedRepositoryId"].asString - } - - operator fun JsonElement.get(key: String): JsonElement = asJsonObject.get(key) - val JsonElement.list: JsonArray get() = asJsonArray - fun JsonElement.toStringPretty() = GsonBuilder().setPrettyPrinting().create().toJson(this) -} - -open class SimpleHttpClient( - val user: String? = null, - val pass: String? = null -) { - open fun requestWithRetry(url: String, body: Any? = null, nretries: Int = 15): JsonElement { - var retryCount = 0 - while (true) { - try { - return request(url, body) - } catch (e: SimpleHttpException) { - when (e.responseCode) { - in 500..599 -> { // Sometimes HTTP Error 502 Bad Gateway - e.printStackTrace() - retryCount++ - if (retryCount >= nretries) throw RuntimeException("Couldn't access $url after $nretries retries :: ${e.responseCode} : ${e.message}", e) - println("Retrying... retryCount=$retryCount/$nretries") - Thread.sleep(15_000L + (retryCount * 5_000L)) - continue - } - else -> { - throw e - } + developers { + developer { + id.set("korge") + name.set("Korge Team") + email.set("info@korge.org") } } - } - } - - open fun request(url: String, body: Any? = null): JsonElement { - val post = (URL(url).openConnection()) as HttpURLConnection - post.connectTimeout = 300 * 1000 // 300 seconds // 5 minutes - post.readTimeout = 300 * 1000 // 300 seconds // 5 minutes - post.requestMethod = (if (body != null) "POST" else "GET") - if (user != null && pass != null) { - val authBasic = Base64.getEncoder().encodeToString("${user}:${pass}".toByteArray(Charsets.UTF_8)) - post.setRequestProperty("Authorization", "Basic $authBasic") - } - post.setRequestProperty("Accept", "application/json") - if (body != null) { - post.doOutput = true - post.setRequestProperty("Content-Type", "application/json") - val bodyText = if (body is String) body.toString() else JsonOutput.toJson(body) - //println(bodyText) - post.outputStream.write(bodyText.toByteArray(Charsets.UTF_8)) - } - val postRC = post.responseCode - val postMessage = post.responseMessage - //println(postRC) - if (postRC < 400) { - return JsonParser.parseString(post.inputStream.reader(Charsets.UTF_8).readText()) - } else { - val errorString = try { - post.errorStream?.reader(Charsets.UTF_8)?.readText() - } catch (e: CancellationException) { - throw e - } catch (e: Throwable) { - null + scm { + url.set(defaultGitUrl) } - throw SimpleHttpException(postRC, postMessage, url, errorString) } } -} - -class SimpleHttpException(val responseCode: Int, val responseMessage: String, val url: String, val errorString: String?) : - RuntimeException("HTTP Error $responseCode $responseMessage - $url - $errorString") -object GithubCI { - fun setOutput(name: String, value: String) { - val GITHUB_OUTPUT = System.getenv("GITHUB_OUTPUT") - if (GITHUB_OUTPUT != null) { - File(GITHUB_OUTPUT).appendText("$name=$value\n") - } else { - println("::set-output name=$name::$value") - } - } + //println(KotlinCompilerVersion.VERSION) } /* @@ -991,6 +599,7 @@ class MicroAmper(val project: Project) { } } + @OptIn(org.jetbrains.kotlin.gradle.ExperimentalWasmDsl::class) fun applyTo() = with(project) { project.kotlin.sourceSets { ssDependsOn("native", "common") @@ -1009,7 +618,6 @@ class MicroAmper(val project: Project) { val isNative = platform.contains("X86") || platform.contains("X64") || platform.contains("Arm") val isApple = isMacos || isIos || isTvos || isWatchos val isLinux = platform.startsWith("linux") - val isWindows = platform.startsWith("mingw") val isPosix = isLinux || isApple val basePlatform = getKotlinBasePlatform(platform) if (isIos || isTvos) ssDependsOn(basePlatform, "appleIosTvos") @@ -1032,6 +640,7 @@ class MicroAmper(val project: Project) { browser() } "wasm" -> { + @OptIn(org.jetbrains.kotlin.gradle.ExperimentalWasmDsl::class) kotlin.wasmJs { } kotlin.sourceSets { @@ -1117,22 +726,12 @@ class MicroAmper(val project: Project) { } allprojects { - afterEvaluate { - afterEvaluate { - afterEvaluate { - tasks.withType(org.gradle.api.tasks.testing.Test::class) { - //println("TEST-TASK: $this") - if (JDK_VERSION.majorVersion.toInt() >= 9) { - jvmArgs( - "-XX:+IgnoreUnrecognizedVMOptions", - "--add-opens", "java.base/java.nio=ALL-UNNAMED", - //"--add-opens", "java.base/jdk.incubator.foreign=ALL-UNNAMED", - "--add-opens", "java.base/sun.nio.ch=ALL-UNNAMED", - ) - } - } - } - } + tasks.withType(Test::class).configureEach { + jvmArgs( + "-XX:+IgnoreUnrecognizedVMOptions", + "--add-opens", "java.base/java.nio=ALL-UNNAMED", + "--add-opens", "java.base/sun.nio.ch=ALL-UNNAMED", + ) } } @@ -1141,13 +740,6 @@ subprojects { plugins.apply("org.jetbrains.kotlinx.kover") } -allprojects { - tasks.withType(AbstractDokkaTask::class.java).configureEach { - //println("DOKKA=$it") - offlineMode.set(true) - } -} - apiValidation { ignoredProjects.addAll(listOf(rootProject.name)) } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 9355b41..aaaabb3 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.10-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.4-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/korlibs-image-core/api/android/korlibs-image-core.api b/korlibs-image-core/api/android/korlibs-image-core.api index be245da..22a9703 100644 --- a/korlibs-image-core/api/android/korlibs-image-core.api +++ b/korlibs-image-core/api/android/korlibs-image-core.api @@ -104,8 +104,9 @@ public abstract interface class korlibs/image/core/CoreImageFormatProvider { public static final field Companion Lkorlibs/image/core/CoreImageFormatProvider$Companion; public abstract fun decode ([BLkotlin/coroutines/Continuation;)Ljava/lang/Object; public abstract fun encode-jUZaLX8 (Lkorlibs/image/core/CoreImage;Ljava/lang/String;DLkotlin/coroutines/Continuation;)Ljava/lang/Object; - public abstract fun info ([BLkotlin/coroutines/Continuation;)Ljava/lang/Object; - public abstract fun isSupported ()Z + public static synthetic fun encode-jUZaLX8$default (Lkorlibs/image/core/CoreImageFormatProvider;Lkorlibs/image/core/CoreImage;Ljava/lang/String;DLkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object; + public fun info ([BLkotlin/coroutines/Continuation;)Ljava/lang/Object; + public fun isSupported ()Z } public final class korlibs/image/core/CoreImageFormatProvider$Companion { diff --git a/korlibs-image-core/api/jvm/korlibs-image-core.api b/korlibs-image-core/api/jvm/korlibs-image-core.api index 45428d3..9f7f409 100644 --- a/korlibs-image-core/api/jvm/korlibs-image-core.api +++ b/korlibs-image-core/api/jvm/korlibs-image-core.api @@ -193,8 +193,9 @@ public abstract interface class korlibs/image/core/CoreImageFormatProvider { public static final field Companion Lkorlibs/image/core/CoreImageFormatProvider$Companion; public abstract fun decode ([BLkotlin/coroutines/Continuation;)Ljava/lang/Object; public abstract fun encode-jUZaLX8 (Lkorlibs/image/core/CoreImage;Ljava/lang/String;DLkotlin/coroutines/Continuation;)Ljava/lang/Object; - public abstract fun info ([BLkotlin/coroutines/Continuation;)Ljava/lang/Object; - public abstract fun isSupported ()Z + public static synthetic fun encode-jUZaLX8$default (Lkorlibs/image/core/CoreImageFormatProvider;Lkorlibs/image/core/CoreImage;Ljava/lang/String;DLkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object; + public fun info ([BLkotlin/coroutines/Continuation;)Ljava/lang/Object; + public fun isSupported ()Z } public final class korlibs/image/core/CoreImageFormatProvider$Companion { diff --git a/korlibs-image-core/module.yaml b/korlibs-image-core/module.yaml index b1f8c16..b27ff90 100644 --- a/korlibs-image-core/module.yaml +++ b/korlibs-image-core/module.yaml @@ -8,18 +8,20 @@ aliases: - appleIosTvos: [tvosArm64, tvosX64, tvosSimulatorArm64, iosArm64, iosSimulatorArm64, iosX64] dependencies: - - com.soywiz:korlibs-annotations:6.0.0 - - org.jetbrains.kotlinx:kotlinx-coroutines-core:1.9.0-RC - - org.jetbrains.kotlinx:atomicfu:0.24.0: exported + - org.korge:korlibs-annotations:6.1.0 + - org.jetbrains.kotlinx:kotlinx-coroutines-core:1.10.2 + - org.jetbrains.kotlinx:atomicfu:0.32.1: exported dependencies@jvm: - - net.java.dev.jna:jna:5.14.0: exported - - net.java.dev.jna:jna-platform:5.14.0: exported - #- ../korlibs-ffi + - net.java.dev.jna:jna:5.18.1: exported + - net.java.dev.jna:jna-platform:5.18.1: exported dependencies@js: - - com.soywiz:korlibs-wasm:6.0.0 - - com.soywiz:korlibs-compression:6.0.0 + - org.korge:korlibs-wasm:6.1.0 + - org.korge:korlibs-compression:6.1.0 + +dependencies@wasm: + - org.jetbrains.kotlinx:kotlinx-browser-wasm-js:0.5.0 test-dependencies: - - org.jetbrains.kotlinx:kotlinx-coroutines-test:1.9.0-RC + - org.jetbrains.kotlinx:kotlinx-coroutines-test:1.10.2