Skip to content
Open
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
18 changes: 15 additions & 3 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,6 @@ updates:
day: "monday"
open-pull-requests-limit: 5
groups:
kotlin:
patterns:
- "org.jetbrains.kotlin*"
ktor:
patterns:
- "io.ktor*"
Expand All @@ -24,6 +21,21 @@ updates:
exposed:
patterns:
- "org.jetbrains.exposed*"
detekt:
patterns:
- "io.gitlab.arturbosch.detekt*"
- "com.github.marc0der*"
ktlint:
patterns:
- "com.pinterest.ktlint*"
jib:
patterns:
- "com.google.cloud.tools*"
release-plugin:
patterns:
- "org.eclipse.jgit*"
- "org.bouncycastle*"
- "org.slf4j*"

# GitHub Actions
- package-ecosystem: "github-actions"
Expand Down
22 changes: 9 additions & 13 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,23 +10,19 @@ jobs:
build:
runs-on: ubuntu-latest

env:
KOTLIN_CLI_NO_WELCOME_BANNER: "1"

steps:
- uses: actions/checkout@v6
with:
fetch-depth: 0 # Needed for Axion-release to determine version correctly

- name: Set up JDK 21
uses: actions/setup-java@v5
with:
java-version: '21'
distribution: 'temurin'
cache: gradle

- name: Grant execute permission for gradlew
run: chmod +x gradlew
fetch-depth: 0 # Needed for the release plugin to determine the version from git tags

- name: Build with Gradle
run: ./gradlew build --scan --info
- name: Build with Kotlin Toolchain
run: |
./kotlin build
./kotlin check
./kotlin do package

- name: Upload build artifacts
uses: actions/upload-artifact@v7
Expand Down
26 changes: 10 additions & 16 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ on:
- main

# Only release the latest commit; cancel superseded runs so back-to-back
# merges don't fail axion's aheadOfRemote check by racing each other.
# merges don't fail the release plugin's aheadOfRemote check by racing each other.
concurrency:
group: release-main
cancel-in-progress: true
Expand All @@ -19,6 +19,8 @@ jobs:
build:
name: "Release"
runs-on: ubuntu-latest
env:
KOTLIN_CLI_NO_WELCOME_BANNER: "1"
steps:
- name: Install doctl
uses: digitalocean/action-doctl@v2
Expand All @@ -33,29 +35,21 @@ jobs:
with:
fetch-depth: 0

- name: Set up JDK 21
uses: actions/setup-java@v5
with:
java-version: '21'
distribution: 'temurin'
cache: gradle

- name: Gradle check
run: ./gradlew clean check
- name: Verify
run: ./kotlin check

- name: Gradle release
run: ./gradlew release
- name: Tag release
run: ./kotlin do release

- name: Propagate current release version
- name: Resolve current release version
id: tag_version
run: |
current_version=$(./gradlew currentVersion -q | grep "Project version" | awk '{print $3}')
current_version=$(./kotlin do currentVersion | awk '/currentVersion@release/ { v = $NF } END { print v }')
echo "Version set to: $current_version"
echo "version=$current_version" >> $GITHUB_OUTPUT

- name: Build and publish Docker image
run: |
version="${{ steps.tag_version.outputs.version }}"
commit_hash=$(git rev-parse --short=8 HEAD)
./gradlew build jib -Djib.to.tags=$commit_hash,$version,latest

JIB_TARGET_IMAGE_TAGS="$version,$commit_hash,latest" ./kotlin do jib
5 changes: 1 addition & 4 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
# Gradle
.gradle/
# Kotlin Toolchain
build/
gradle-app.setting
!gradle-wrapper.jar

# IDE files
.idea/
Expand Down
12 changes: 0 additions & 12 deletions .mcp.json

This file was deleted.

1 change: 1 addition & 0 deletions .sdkmanrc
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# Enable auto-env through the sdkman_auto_env config
# Add key=value pairs of SDKs to use below
java=21.0.7-tem
kotlintoolchain=0.11.0
29 changes: 20 additions & 9 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,25 +8,36 @@ SDKMAN Broker is a Kotlin-based Ktor application that brokers SDKMAN candidate a

## Build & Run

- **Run service:** `./gradlew run` (starts Ktor on port 8080; requires MongoDB and PostgreSQL — see Database Setup below)
Built with the Kotlin Toolchain (Amper engine). The `./kotlin` wrapper auto-provisions both the JDK and the toolchain; no `setup-java` or local install required.

Built-in toolchain commands (`build`, `check`, `test`, `run`, `clean`) are invoked directly as `./kotlin <command>`. Commands contributed by the local plugins under `plugins/` (e.g. `currentVersion`, `release`, `jib`, `ktlintFormat`) are invoked as `./kotlin do <command>`.

- **Run service:** `./kotlin run` (starts Ktor on port 8080; requires MongoDB and PostgreSQL — see Database Setup below)

## Validation

Run after every implementation to get immediate feedback:

- **Clean build** `./gradlew clean`
- **Full check:** `./gradlew clean check` (clean -> compile → detekt → ktlintCheck → test)
- **Tests only:** `./gradlew test`
- **Lint only:** `./gradlew ktlintCheck`
- **Lint auto-fix:** `./gradlew ktlintFormat`
- **Static analysis:** `./gradlew detekt` (config in `detekt.yml`)
- **Build Docker image:** `./gradlew jib` (or `jibDockerBuild` for local)
- **Clean build:** `./kotlin clean`
- **Full check:** `./kotlin clean && ./kotlin check` (compile → detekt → ktlint → test)
- **Tests only:** `./kotlin test`
- **Lint auto-fix:** `./kotlin do ktlintFormat`
- **Static analysis:** detekt runs as part of `./kotlin check` (config in `detekt.yml`, plugin in `plugins/detekt/`)
- **Build Docker image:** `./kotlin do jib` (pushes to the registry in `module.yaml`; use `./kotlin do jibDockerBuild` for a local Docker daemon load)
- **Current version:** `./kotlin do currentVersion` (derived from git tags by the local release plugin)

Tests spin up MongoDB and PostgreSQL via Testcontainers — no manual database setup is required to run the test suite.

## Build Configuration

- **`module.yaml`** — root module config (dependencies, settings, plugin config). Layout is `maven-like` (`src/main/kotlin`, `src/test/kotlin`, etc.).
- **`project.yaml`** — registers all modules and local plugins.
- **`gradle/libs.versions.toml`** — Gradle-format version catalog reused as the `$libs.*` catalog (the directory name is historical; the file is consumed natively by the Kotlin Toolchain).
- **`plugins/{release,jib,detekt,ktlint}/`** — local plugins replacing the Gradle plugins of the same name. Reimplement behavior here rather than reaching for Gradle plugins.

## Database Setup (Dev Server Only)

The dev server (`./gradlew run`) connects to MongoDB and PostgreSQL on localhost. Start them in Docker:
The dev server (`./kotlin run`) connects to MongoDB and PostgreSQL on localhost. Start them in Docker:

```bash
docker run -d --restart=always -p=27017:27017 --name mongo mongo:3.2
Expand Down
31 changes: 22 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,31 +14,44 @@ This application implements a health check endpoint that performs a deep health

### Prerequisites

- JDK 21 (Temurin recommended)
- MongoDB (or use Docker)
- Postgres (or use Docker)
- Gradle
- The Kotlin Toolchain (formerly Amper) — auto-provisioned by the bundled `./kotlin` wrapper. Installing it globally is optional.

### SDKMAN Setup

This project uses SDKMAN to manage the JDK version:
This project uses SDKMAN to manage the JDK and the Kotlin Toolchain CLI:

```
sdk env
```

That installs the JDK declared in `.sdkmanrc` and the Kotlin Toolchain CLI. Alternatively, the `./kotlin` wrapper checked into the project root auto-provisions both on first use.

### Building and Testing

Build the project:

```
./gradlew build
./kotlin build
```

Run tests:

```
./gradlew check
./kotlin test
```

Run all verification checks (detekt + ktlint):

```
./kotlin check
```

Auto-format Kotlin sources:

```
./kotlin do ktlintFormat
```

### Running Locally
Expand Down Expand Up @@ -78,7 +91,7 @@ mongosh --eval 'db.getSiblingDB("sdkman").application.insertOne({ alive: "OK", s
Run the application:

```
./gradlew run
./kotlin run
```

## API Endpoints
Expand Down Expand Up @@ -138,14 +151,14 @@ This project uses GitHub Actions for CI/CD:
- Builds a Docker image and pushes it to Digital Ocean Container Registry
- The image is tagged with the version number, commit hash, and "latest"

The version is managed by the Axion Release Plugin based on Git tags.
The version is managed by the local `release` Kotlin Toolchain plugin (`plugins/release/`), which derives the version from Git tags.

### Checking the Current Version

To check the current version of the application, run:

```
./gradlew currentVersion
./kotlin do currentVersion
```

This will display the current version as determined by the Axion Release Plugin.
This will display the current version as determined by the local release plugin.
Loading