diff --git a/content/blog/2026-03-23-kotlin-support.md b/content/blog/2026-03-23-kotlin-support.md new file mode 100644 index 0000000..5d082eb --- /dev/null +++ b/content/blog/2026-03-23-kotlin-support.md @@ -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. diff --git a/content/blog/2026-03-23-swift-support.md b/content/blog/2026-03-23-swift-support.md new file mode 100644 index 0000000..dee68be --- /dev/null +++ b/content/blog/2026-03-23-swift-support.md @@ -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. diff --git a/content/docs/standards/_index.md b/content/docs/standards/_index.md index 3db0554..d25cd50 100644 --- a/content/docs/standards/_index.md +++ b/content/docs/standards/_index.md @@ -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. @@ -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. @@ -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) | @@ -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 diff --git a/content/docs/standards/kotlin.md b/content/docs/standards/kotlin.md new file mode 100644 index 0000000..9c6af1d --- /dev/null +++ b/content/docs/standards/kotlin.md @@ -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/). diff --git a/content/docs/standards/swift.md b/content/docs/standards/swift.md new file mode 100644 index 0000000..bddc68e --- /dev/null +++ b/content/docs/standards/swift.md @@ -0,0 +1,121 @@ +--- +title: "Swift" +linkTitle: "Swift" +weight: 45 +description: "Swift tooling standards: SwiftLint, swift-format, swift test, and xcodebuild." +--- + +Swift projects use SwiftLint for linting, swift-format for formatting, swift test for SPM-based testing, and xcodebuild for Xcode project testing on macOS CI runners. + +## Tools + +| Category | Tool | Purpose | +|---|---|---| +| Linter | SwiftLint | Style and convention enforcement | +| Formatter | swift-format | Apple's official code formatter | +| Tests (SPM) | swift test | Swift Package Manager test runner | +| Tests (Xcode) | xcodebuild | Xcode project test runner (macOS only) | + +All tools except xcodebuild are pre-installed in the dev-toolchain container. Do not install them on the host. + +## Configuration + +### SwiftLint + +Config file: `.swiftlint.yml` at repository root. + +```yaml +# .swiftlint.yml -- DevRail Swift lint configuration +# See: https://realm.github.io/SwiftLint/rule-directory.html + +opt_in_rules: + - closure_body_length + - collection_alignment + - contains_over_filter_count + - discouraged_optional_boolean + - empty_collection_literal + - empty_count + - empty_string + - force_unwrapping + - implicitly_unwrapped_optional + - multiline_arguments + - overridden_super_call + - sorted_first_last + - toggle_bool + +excluded: + - .build + - Packages + - DerivedData + +line_length: + warning: 120 + error: 200 + +type_body_length: + warning: 300 + error: 500 +``` + +SwiftLint is invoked with `--strict` to treat all warnings as errors. + +### swift-format + +Config file: `.swift-format` (JSON) at repository root. + +```json +{ + "version": 1, + "lineLength": 120, + "indentation": { + "spaces": 4 + }, + "maximumBlankLines": 1, + "respectsExistingLineBreaks": true, + "lineBreakBeforeControlFlowKeywords": false, + "lineBreakBeforeEachArgument": true +} +``` + +swift-format is Apple's official Swift formatter. It is authoritative for all code style decisions. + +## Makefile Targets + +| Target | Command | Description | +|---|---|---| +| `make lint` | `swiftlint lint --strict` | Lint all Swift files | +| `make format` | `swift-format lint --strict -r .` | Check formatting (diff mode) | +| `make fix` | `swift-format format -i -r .` | Apply formatting fixes | +| `make test` | `swift test` | Run SPM test suite (if `Package.swift` exists) | + +## Pre-Commit Hooks + +### Local Hooks (run on every commit, under 30 seconds) + +SwiftLint runs on every commit to catch lint issues: + +```yaml +# .pre-commit-config.yaml -- Swift hooks +repos: + - repo: https://github.com/realm/SwiftLint + rev: 0.58.0 + hooks: + - id: swiftlint + args: ["lint", "--strict"] +``` + +### CI-Only (too slow for local hooks) + +- `swift test` -- SPM test suite +- `xcodebuild test` -- Xcode project tests (macOS runners only, outside container) + +## Notes + +- **SwiftLint is the single linting tool.** It is the most widely adopted Swift linter with extensive rule coverage. It runs on both macOS and Linux. +- **swift-format is the single formatting tool inside the container.** Apple's official formatter handles all code style decisions. +- **The Swift toolchain is included in the container.** The full toolchain (swiftc, swift build, swift test, Swift Package Manager) is COPY'd from the `swift:6.1-slim-bookworm` builder stage. +- **`Package.swift` presence gates SPM testing.** If no `Package.swift` exists, `swift test` is skipped. Xcode-only projects must configure `xcodebuild test` in their CI pipeline directly. +- **`xcodebuild` does not run inside the container.** It requires macOS and Xcode. Configure a separate macOS CI job for Xcode project testing. +- **Security scanning uses trivy.** Trivy scans `Package.resolved` for known vulnerabilities in Swift package dependencies. +- **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/).