diff --git a/.github/workflows/claude.yml b/.github/workflows/claude.yml index 1681040..4e1dcdb 100644 --- a/.github/workflows/claude.yml +++ b/.github/workflows/claude.yml @@ -17,7 +17,7 @@ jobs: (github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '@claude')) || (github.event_name == 'pull_request_review' && contains(github.event.review.body, '@claude')) || (github.event_name == 'issues' && (contains(github.event.issue.body, '@claude') || contains(github.event.issue.title, '@claude'))) - runs-on: ubuntu-latest + runs-on: linux-arm64 permissions: contents: read pull-requests: write diff --git a/.github/workflows/publish.yaml b/.github/workflows/publish.yaml index 8c7351c..daa2841 100644 --- a/.github/workflows/publish.yaml +++ b/.github/workflows/publish.yaml @@ -26,7 +26,7 @@ permissions: jobs: create-tag-and-build: - runs-on: linux-x64 + runs-on: linux-arm64 outputs: new_version: ${{ steps.create_tag.outputs.new_version }} steps: @@ -70,7 +70,7 @@ jobs: - name: Set up JDK uses: actions/setup-java@v5 with: - java-version: '21' + java-version: '25' distribution: 'corretto' cache: 'gradle' - uses: actions/cache@v5 @@ -85,7 +85,7 @@ jobs: run: ./gradlew buildAllLinuxBinaries - name: Prepare release binaries run: | - cp build/bin/common/releaseExecutable/slack-notifier-cli.kexe ./slack-notifier-cli-X64 + cp build/bin/host/releaseExecutable/slack-notifier-cli.kexe ./slack-notifier-cli-X64 cp build/bin/linuxArm64/releaseExecutable/slack-notifier-cli.kexe ./slack-notifier-cli-ARM64 chmod +x ./slack-notifier-cli-X64 ./slack-notifier-cli-ARM64 - name: Upload x64 executable diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml index 5570886..9785545 100644 --- a/.github/workflows/pull-request.yml +++ b/.github/workflows/pull-request.yml @@ -4,14 +4,14 @@ on: [ pull_request ] jobs: build: - runs-on: ubuntu-latest + runs-on: linux-arm64 steps: - uses: actions/checkout@v6 - name: Set up JDK uses: actions/setup-java@v5 with: - java-version: '17' - distribution: 'adopt' + java-version: '25' + distribution: 'corretto' cache: 'gradle' - uses: actions/cache@v5 with: @@ -22,10 +22,10 @@ jobs: sudo apt update sudo apt install libcurl4-openssl-dev - name: Build with Gradle - run: ./gradlew allTests + run: ./gradlew buildAllLinuxBinaries static-code-analysis: name: Static Code Analysis - runs-on: ubuntu-latest + runs-on: linux-arm64 timeout-minutes: 30 steps: - name: Run detekt diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 14db736..3941649 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -10,13 +10,13 @@ permissions: jobs: build: - runs-on: linux-x64 + runs-on: linux-arm64 steps: - uses: actions/checkout@v6 - name: Set up JDK uses: actions/setup-java@v5 with: - java-version: '21' + java-version: '25' distribution: 'corretto' cache: 'gradle' - uses: actions/cache@v5 @@ -31,7 +31,7 @@ jobs: run: ./gradlew buildAllLinuxBinaries - name: Prepare binaries run: | - cp build/bin/common/releaseExecutable/slack-notifier-cli.kexe ./slack-notifier-cli-X64 + cp build/bin/host/releaseExecutable/slack-notifier-cli.kexe ./slack-notifier-cli-X64 cp build/bin/linuxArm64/releaseExecutable/slack-notifier-cli.kexe ./slack-notifier-cli-ARM64 chmod +x ./slack-notifier-cli-X64 ./slack-notifier-cli-ARM64 - name: Upload x64 executable diff --git a/CLAUDE.md b/CLAUDE.md index ed9a40d..0a2f5d1 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -9,18 +9,12 @@ This is a Kotlin Multiplatform CLI application for sending Slack notifications, ## Key Commands ### Building and Development -- `./gradlew build` - Full build including compilation and tests -- `./gradlew commonBinaries` - Build native executables (default task) -- `./gradlew linkReleaseExecutableCommon` - Build release executable -- `./gradlew linkDebugExecutableCommon` - Build debug executable +- `./gradlew hostBinaries` - Build native executables for current host (default task) +- `./gradlew buildAllLinuxBinaries` - Build release executable ### Running -- `./gradlew runDebugExecutableCommon` - Run debug executable -- `./gradlew runReleaseExecutableCommon` - Run release executable - -### Testing -- `./gradlew commonTest` - Run tests for common target -- `./gradlew allTests` - Run all tests with aggregated report +- `./gradlew runDebugExecutableHost` - Run debug executable +- `./gradlew runReleaseExecutableHost` - Run release executable ### Code Quality - `./gradlew ktlintCheck` - Run linting @@ -52,12 +46,11 @@ This is a Kotlin Multiplatform CLI application for sending Slack notifications, - **Ktor**: HTTP client for Slack API calls - **kotlinx-serialization**: JSON parsing for GitHub events - **kotlinx-datetime**: Date/time handling -- **Kotest**: Testing framework ## Development Notes ### Platform Targeting -The project uses cross-compilation with a single "common" target that maps to the host platform. The native target selection happens at build time based on OS detection. +The project uses cross-compilation with a single "host" target that maps to the current build machine's platform. The native target selection happens at build time based on OS detection. ### GitHub Integration The CLI is designed to run in GitHub Actions and expects specific environment variables (GITHUB_EVENT_PATH, GITHUB_REPOSITORY, etc.). Event parsing handles multiple GitHub webhook formats through dedicated serializers. @@ -65,4 +58,4 @@ The CLI is designed to run in GitHub Actions and expects specific environment va ### Usage Context This tool is typically used indirectly through: 1. [slack-notifier-cli-action](https://github.com/monta-app/slack-notifier-cli-action) - GitHub Action wrapper -2. [github-workflows](https://github.com/monta-app/github-workflows) - Shared workflow templates \ No newline at end of file +2. [github-workflows](https://github.com/monta-app/github-workflows) - Shared workflow templates diff --git a/build.gradle.kts b/build.gradle.kts index e2f8b76..8d90af4 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,7 +1,6 @@ plugins { - kotlin("multiplatform") version "2.1.21" - kotlin("plugin.serialization") version "2.1.21" - id("io.kotest.multiplatform") version "5.9.1" + kotlin("multiplatform") version "2.3.20" + kotlin("plugin.serialization") version "2.3.20" id("org.jlleitschuh.gradle.ktlint") version "12.3.0" } @@ -12,21 +11,21 @@ repositories { mavenCentral() } -defaultTasks("commonBinaries") +defaultTasks("hostBinaries") kotlin { val hostOs = System.getProperty("os.name") // Host target (always matches the build machine) - val commonTarget = when { - hostOs == "Mac OS X" -> macosArm64("common") - hostOs == "Linux" -> linuxX64("common") - hostOs.startsWith("Windows") -> mingwX64("common") + val hostTarget = when { + hostOs == "Mac OS X" -> macosArm64("host") + hostOs == "Linux" -> linuxX64("host") + hostOs.startsWith("Windows") -> mingwX64("host") else -> throw GradleException("Host OS is not supported in Kotlin/Native.") } - commonTarget.apply { + hostTarget.apply { binaries { executable { entryPoint = "com.monta.slack.notifier.main" @@ -46,40 +45,24 @@ kotlin { } sourceSets { - val commonMain by getting { + commonMain { dependencies { // CLI - implementation("com.github.ajalt.clikt:clikt:5.0.3") + implementation("com.github.ajalt.clikt:clikt:5.1.0") // Date Time Support - implementation("org.jetbrains.kotlinx:kotlinx-datetime:0.6.2") + implementation("org.jetbrains.kotlinx:kotlinx-datetime:0.7.1-0.6.x-compat") // Serialization - implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.8.1") + implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.11.0") // Atomic - implementation("org.jetbrains.kotlinx:atomicfu:0.28.0") + implementation("org.jetbrains.kotlinx:atomicfu:0.32.1") // Http Client - val ktorVersion = "3.2.0" + val ktorVersion = "3.4.2" implementation("io.ktor:ktor-client-core:$ktorVersion") implementation("io.ktor:ktor-client-curl:$ktorVersion") implementation("io.ktor:ktor-client-content-negotiation:$ktorVersion") implementation("io.ktor:ktor-serialization-kotlinx-json:$ktorVersion") } } - val commonTest by getting { - dependencies { - val kotestVersion = "5.9.1" - implementation(kotlin("test-common")) - implementation(kotlin("test-annotations-common")) - implementation("io.kotest:kotest-framework-engine:$kotestVersion") - implementation("io.kotest:kotest-assertions-core:$kotestVersion") - } - } - - // Configure linuxArm64 to share the same source set - if (hostOs == "Linux") { - val linuxArm64Main by getting { - dependsOn(commonMain) - } - } } } @@ -89,7 +72,7 @@ kotlin.targets.withType