Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/claude.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/publish.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand Down
10 changes: 5 additions & 5 deletions .github/workflows/pull-request.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand All @@ -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
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down
19 changes: 6 additions & 13 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -52,17 +46,16 @@ 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.

### 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
2. [github-workflows](https://github.com/monta-app/github-workflows) - Shared workflow templates
49 changes: 16 additions & 33 deletions build.gradle.kts
Original file line number Diff line number Diff line change
@@ -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"
}

Expand All @@ -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"
Expand All @@ -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)
}
}
}
}

Expand All @@ -89,14 +72,14 @@ kotlin.targets.withType<org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarge
}
}

val hostOs = System.getProperty("os.name")
val hostOs: String = System.getProperty("os.name")
val isLinux = hostOs == "Linux"

// Task to build both x64 and ARM64 binaries on Linux
if (isLinux) {
tasks.register("buildAllLinuxBinaries") {
group = "build"
description = "Build binaries for both Linux x64 and ARM64"
dependsOn("linkReleaseExecutableCommon", "linkReleaseExecutableLinuxArm64")
dependsOn("linkReleaseExecutableHost", "linkReleaseExecutableLinuxArm64")
}
}