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
92 changes: 92 additions & 0 deletions content/blog/2026-03-23-kotlin-support.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
---
title: "Kotlin Language Support"
date: 2026-03-23
description: "DevRail now supports Kotlin with ktlint, detekt, and Gradle -- covering both server-side and Android Kotlin development."
---

DevRail now supports Kotlin as its tenth language ecosystem. Whether you are building server-side Kotlin services or Android applications, DevRail provides consistent linting, static analysis, testing, and security scanning through the same Makefile targets and CI pipelines used by every other supported language.

## What's Included

The dev-toolchain container ships JDK 21, the Kotlin compiler, Gradle, and dedicated analysis tools:

- **ktlint** -- Kotlin linter and formatter that enforces the official Kotlin coding conventions, serving as a dual-purpose tool for both style checking and auto-formatting
- **detekt** -- configurable static code analysis for Kotlin, covering complexity, potential bugs, and code smells
- **Gradle** -- the standard Kotlin build tool, used for running tests and dependency analysis
- **OWASP dependency-check** -- Gradle plugin for scanning dependencies against the National Vulnerability Database
- **trivy** -- universal dependency scanning for Gradle projects

JDK 21 (Eclipse Temurin) is included in the container alongside the Kotlin compiler and Gradle distribution.

## Configuration

Add `kotlin` to your `.devrail.yml`:

```yaml
languages:
- kotlin
```

ktlint reads `.editorconfig` at the repository root -- no separate config file needed. detekt reads `detekt.yml` for static analysis rules. Both are scaffolded by `devrail init` when Kotlin is declared.

## Makefile Targets

The standard targets work out of the box:

```bash
make lint # ktlint + detekt (if detekt.yml exists)
make format # ktlint --format --dry-run
make fix # ktlint --format
make test # gradle test (if build.gradle.kts or build.gradle exists)
make security # gradle dependencyCheckAnalyze (OWASP)
make check # all of the above
```

## Android Projects

The container handles ktlint, detekt, and Gradle test for all Kotlin projects. Android-specific checks (Android Lint) require the Android SDK, which is not included in the container. For Android projects, configure a separate CI job:

```yaml
# GitHub Actions example -- Android Lint job
- name: Run Android Lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-java@v4
with:
distribution: temurin
java-version: 21
- name: Setup Android SDK
uses: android-actions/setup-android@v3
- run: ./gradlew lint
```

Server-side Kotlin projects (Spring Boot, Ktor, etc.) work entirely inside the container with no additional setup.

## Pre-Commit Hooks

ktlint runs as a local pre-commit hook (under 30 seconds):

```yaml
repos:
- repo: https://github.com/JetBrains/ktlint-pre-commit-hook
rev: v1.5.0
hooks:
- id: ktlint
```

## Getting Started

Pull the latest container and add Kotlin to your project:

```bash
docker pull ghcr.io/devrail-dev/dev-toolchain:v1
```

Or use `devrail init` to set up a new Kotlin project:

```bash
curl -fsSL https://devrail.dev/init.sh | bash -s -- --languages kotlin --ci github --all
```

See the [Kotlin Standards](/docs/standards/kotlin/) page for the full configuration reference.
85 changes: 85 additions & 0 deletions content/blog/2026-03-23-swift-support.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
---
title: "Swift Language Support"
date: 2026-03-23
description: "DevRail now supports Swift with SwiftLint, swift-format, and swift test -- bringing Apple-platform development into the standards-driven workflow."
---

DevRail now supports Swift as its ninth language ecosystem. Swift projects get the same standards-driven workflow as every other DevRail-supported language: linting, formatting, testing, and security scanning through consistent Makefile targets and CI pipelines.

## What's Included

The dev-toolchain container ships the full Swift toolchain alongside dedicated linting and formatting tools:

- **SwiftLint** -- the de facto standard Swift linter, enforcing style and convention rules with extensive opt-in rule coverage
- **swift-format** -- Apple's official code formatter, handling all whitespace, indentation, and line-breaking decisions
- **swift test** -- Swift Package Manager's built-in test runner for SPM-based projects
- **trivy** -- universal dependency scanning via `Package.resolved`

The full Swift toolchain (swiftc, swift build, swift test, Swift Package Manager) is included in the container, COPY'd from the official `swift:6.1-slim-bookworm` image.

## Configuration

Add `swift` to your `.devrail.yml`:

```yaml
languages:
- swift
```

SwiftLint reads `.swiftlint.yml` at the repository root. swift-format reads `.swift-format` (JSON). Both config files are scaffolded by `devrail init` when Swift is declared.

## Makefile Targets

The standard targets work out of the box:

```bash
make lint # swiftlint lint --strict
make format # swift-format lint --strict -r .
make fix # swift-format format -i -r .
make test # swift test (if Package.swift exists)
make check # all of the above
```

## Xcode Projects

The container runs on Linux, so `xcodebuild` is not available inside it. For Xcode-based projects (iOS, macOS apps), the container handles linting and formatting. Testing requires a separate macOS CI runner:

```yaml
# GitHub Actions example -- macOS job for xcodebuild
- name: Run Xcode tests
runs-on: macos-latest
steps:
- uses: actions/checkout@v4
- run: xcodebuild test -scheme MyApp -destination 'platform=iOS Simulator,name=iPhone 16'
```

SPM-based projects (those with `Package.swift`) run `swift test` inside the container with no additional setup.

## Pre-Commit Hooks

SwiftLint runs as a local pre-commit hook (under 30 seconds):

```yaml
repos:
- repo: https://github.com/realm/SwiftLint
rev: 0.58.0
hooks:
- id: swiftlint
args: ["lint", "--strict"]
```

## Getting Started

Pull the latest container and add Swift to your project:

```bash
docker pull ghcr.io/devrail-dev/dev-toolchain:v1
```

Or use `devrail init` to set up a new Swift project:

```bash
curl -fsSL https://devrail.dev/init.sh | bash -s -- --languages swift --ci github --all
```

See the [Swift Standards](/docs/standards/swift/) page for the full configuration reference.
32 changes: 17 additions & 15 deletions content/docs/standards/_index.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
title: "Standards"
linkTitle: "Standards"
weight: 20
description: "Per-language tooling standards for Python, Bash, Terraform, Ansible, Ruby, Go, JavaScript/TypeScript, Rust, and universal security tools."
description: "Per-language tooling standards for Python, Bash, Terraform, Ansible, Ruby, Go, JavaScript/TypeScript, Rust, Swift, Kotlin, and universal security tools."
---

DevRail defines opinionated tooling standards for each supported language ecosystem. Every tool is pre-installed in the dev-toolchain container and invoked through consistent Makefile targets.
Expand All @@ -11,15 +11,15 @@ DevRail defines opinionated tooling standards for each supported language ecosys

The following table shows the default tool for each concern per language. These tools are pre-installed in the `dev-toolchain` container.

| Concern | Python | Bash | Terraform | Ansible | Ruby | Go | JavaScript | Rust |
|---|---|---|---|---|---|---|---|---|
| Linter | ruff | shellcheck | tflint | ansible-lint | rubocop, reek | golangci-lint | eslint | clippy |
| Formatter | ruff format | shfmt | terraform fmt, terragrunt hclfmt | -- | rubocop | gofumpt | prettier | rustfmt |
| Security | bandit, semgrep | -- | tfsec, checkov | -- | brakeman, bundler-audit | govulncheck | npm audit | cargo-audit, cargo-deny |
| Tests | pytest | bats | terratest | molecule | rspec | go test | vitest | cargo test |
| Type Check | mypy | -- | -- | -- | sorbet | -- | tsc | -- |
| Docs | -- | -- | terraform-docs | -- | -- | -- | -- | -- |
| Universal | trivy, gitleaks, git-cliff | trivy, gitleaks, git-cliff | trivy, gitleaks, git-cliff | trivy, gitleaks, git-cliff | trivy, gitleaks, git-cliff | trivy, gitleaks, git-cliff | trivy, gitleaks, git-cliff | trivy, gitleaks, git-cliff |
| Concern | Python | Bash | Terraform | Ansible | Ruby | Go | JavaScript | Rust | Swift | Kotlin |
|---|---|---|---|---|---|---|---|---|---|---|
| Linter | ruff | shellcheck | tflint | ansible-lint | rubocop, reek | golangci-lint | eslint | clippy | SwiftLint | ktlint, detekt |
| Formatter | ruff format | shfmt | terraform fmt, terragrunt hclfmt | -- | rubocop | gofumpt | prettier | rustfmt | swift-format | ktlint |
| Security | bandit, semgrep | -- | tfsec, checkov | -- | brakeman, bundler-audit | govulncheck | npm audit | cargo-audit, cargo-deny | -- | OWASP dependency-check |
| Tests | pytest | bats | terratest | molecule | rspec | go test | vitest | cargo test | swift test | gradle test |
| Type Check | mypy | -- | -- | -- | sorbet | -- | tsc | -- | -- | -- |
| Docs | -- | -- | terraform-docs | -- | -- | -- | -- | -- | -- | -- |
| Universal | trivy, gitleaks, git-cliff | trivy, gitleaks, git-cliff | trivy, gitleaks, git-cliff | trivy, gitleaks, git-cliff | trivy, gitleaks, git-cliff | trivy, gitleaks, git-cliff | trivy, gitleaks, git-cliff | trivy, gitleaks, git-cliff | trivy, gitleaks, git-cliff | trivy, gitleaks, git-cliff |

A `--` entry means the concern does not apply to that language. Universal tools run for all projects regardless of declared languages.

Expand All @@ -29,11 +29,11 @@ Each Makefile target runs the relevant tools for all languages declared in `.dev

| Target | What It Runs |
|---|---|
| `make lint` | ruff check, shellcheck, tflint, ansible-lint, mypy, rubocop, reek, golangci-lint, eslint, tsc, clippy |
| `make format` | ruff format --check, shfmt -d, terraform fmt -check, terragrunt hclfmt --terragrunt-check, rubocop --check, gofumpt -d, prettier --check, cargo fmt --check |
| `make fix` | ruff format, shfmt -w, terraform fmt, terragrunt hclfmt, rubocop -a, gofumpt -w, prettier --write, cargo fmt |
| `make test` | pytest, bats, terratest, molecule, rspec, go test, vitest, cargo test |
| `make security` | bandit, semgrep, tfsec, checkov, brakeman, bundler-audit, govulncheck, npm audit, cargo-audit, cargo-deny |
| `make lint` | ruff check, shellcheck, tflint, ansible-lint, mypy, rubocop, reek, golangci-lint, eslint, tsc, clippy, SwiftLint, ktlint, detekt |
| `make format` | ruff format --check, shfmt -d, terraform fmt -check, terragrunt hclfmt --terragrunt-check, rubocop --check, gofumpt -d, prettier --check, cargo fmt --check, swift-format lint, ktlint --format --dry-run |
| `make fix` | ruff format, shfmt -w, terraform fmt, terragrunt hclfmt, rubocop -a, gofumpt -w, prettier --write, cargo fmt, swift-format format, ktlint --format |
| `make test` | pytest, bats, terratest, molecule, rspec, go test, vitest, cargo test, swift test, gradle test |
| `make security` | bandit, semgrep, tfsec, checkov, brakeman, bundler-audit, govulncheck, npm audit, cargo-audit, cargo-deny, OWASP dependency-check |
| `make scan` | trivy, gitleaks (universal -- all projects) |
| `make docs` | terraform-docs |
| `make changelog` | git-cliff (generate CHANGELOG.md from conventional commits) |
Expand All @@ -50,6 +50,8 @@ Each Makefile target runs the relevant tools for all languages declared in `.dev
- [Go Standards](/docs/standards/go/) -- golangci-lint, gofumpt, govulncheck, go test
- [JavaScript Standards](/docs/standards/javascript/) -- eslint, prettier, npm audit, vitest, tsc
- [Rust Standards](/docs/standards/rust/) -- clippy, rustfmt, cargo-audit, cargo-deny, cargo test
- [Swift Standards](/docs/standards/swift/) -- SwiftLint, swift-format, swift test, xcodebuild
- [Kotlin Standards](/docs/standards/kotlin/) -- ktlint, detekt, Gradle, Android Lint
- [Universal Security](/docs/standards/universal/) -- trivy, gitleaks, git-cliff

## Consistent Page Structure
Expand Down
129 changes: 129 additions & 0 deletions content/docs/standards/kotlin.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
---
title: "Kotlin"
linkTitle: "Kotlin"
weight: 50
description: "Kotlin tooling standards: ktlint, detekt, Gradle, and Android Lint."
---

Kotlin projects use ktlint for linting and formatting, detekt for static analysis, Gradle for building and testing, and Android Lint for Android-specific checks on CI.

## Tools

| Category | Tool | Purpose |
|---|---|---|
| Linter / Formatter | ktlint | Kotlin linter and formatter (official coding conventions) |
| Static Analysis | detekt | Configurable static code analysis |
| Build / Tests | Gradle | Build tool and test runner (`gradle test`) |
| Security | OWASP dependency-check | Dependency vulnerability scanning (Gradle plugin) |
| Android Lint | Android Lint | Android-specific checks (requires Android SDK, CI-only) |

All tools except Android Lint are pre-installed in the dev-toolchain container. Do not install them on the host.

## Configuration

### ktlint

Config file: `.editorconfig` at repository root (ktlint respects EditorConfig).

```ini
# .editorconfig -- ktlint configuration
[*.{kt,kts}]
indent_size = 4
max_line_length = 120
ktlint_code_style = ktlint_official
```

ktlint enforces the official Kotlin coding conventions. No separate config file is needed beyond `.editorconfig`.

### detekt

Config file: `detekt.yml` at repository root.

```yaml
# detekt.yml -- DevRail Kotlin static analysis configuration
build:
maxIssues: 0

complexity:
LongMethod:
threshold: 50
LongParameterList:
functionThreshold: 7
ComplexMethod:
threshold: 15

style:
MagicNumber:
active: true
ignoreNumbers: ["-1", "0", "1", "2"]
MaxLineLength:
maxLineLength: 120
WildcardImport:
active: true

potential-bugs:
UnsafeCast:
active: true
```

Setting `maxIssues: 0` causes any finding to fail the build.

### Gradle (OWASP dependency-check)

Add the plugin to `build.gradle.kts`:

```kotlin
plugins {
id("org.owasp.dependencycheck") version "11.1.1"
}

dependencyCheck {
failBuildOnCVSS = 7.0f
formats = listOf("HTML", "JSON")
}
```

## Makefile Targets

| Target | Command | Description |
|---|---|---|
| `make lint` | `ktlint` | Lint all Kotlin files |
| `make lint` | `detekt --build-upon-default-config --config detekt.yml` | Static analysis (if `detekt.yml` exists) |
| `make format` | `ktlint --format --dry-run` | Check formatting |
| `make fix` | `ktlint --format` | Apply formatting fixes |
| `make security` | `gradle dependencyCheckAnalyze` | OWASP dependency scanning |
| `make test` | `gradle test` | Run test suite |

## Pre-Commit Hooks

### Local Hooks (run on every commit, under 30 seconds)

ktlint runs on every commit to catch lint and formatting issues:

```yaml
# .pre-commit-config.yaml -- Kotlin hooks
repos:
- repo: https://github.com/JetBrains/ktlint-pre-commit-hook
rev: v1.5.0
hooks:
- id: ktlint
```

### CI-Only (too slow for local hooks)

- `detekt` -- static code analysis (requires full project context)
- `gradle test` -- full test suite
- `gradle dependencyCheckAnalyze` -- OWASP dependency vulnerability scanning
- `gradle lint` -- Android Lint (Android projects only, requires Android SDK)

## Notes

- **ktlint is dual-purpose: linter and formatter.** It checks and enforces the official Kotlin coding conventions. Run `ktlint` to check and `ktlint --format` to fix.
- **detekt complements ktlint.** While ktlint focuses on style and formatting, detekt provides deeper static analysis (complexity, potential bugs, code smells). Both run in CI.
- **Gradle is the standard build tool.** Both `gradle test` and dependency checking require Gradle. The container ships Gradle and JDK 21 so projects do not need the Gradle wrapper, though `gradlew` is supported if present.
- **Android Lint requires the Android SDK.** For Android projects, configure a separate CI job with the Android SDK. The container handles ktlint, detekt, and Gradle test for all Kotlin projects.
- **JDK 21 is included in the container.** Eclipse Temurin JDK 21 is COPY'd from a builder stage.
- **`build.gradle.kts` or `build.gradle` presence gates testing.** If neither file exists, Gradle commands are skipped.
- **ktlint uses `.editorconfig` for configuration.** Consistent with DevRail's `.editorconfig`-first approach.
- **All tools are pre-installed in the dev-toolchain container.** Do not install them on the host.
- For cross-cutting coding practices and git workflow standards that apply to all languages, see [Coding Practices](/docs/standards/practices/).
Loading
Loading