Skip to content

Repository files navigation

ReadingBat Site

CI Kotlin JDK Ktor Gradle License GitHub release Docker Pulls Docker Image Size Last commit

The deployable content host for readingbat.com. This repo is intentionally thin: the web server, routing, persistence, and challenge runtime all live in readingbat-core, which is consumed here as a binary dependency. What lives in this repo is the content composition and the deployment plumbing around it.

Site Content

Code Content Repos

Requirements

  • JDK 25 (the Gradle toolchain will resolve one via foojay if you don't already have it)
  • Docker + buildx (only needed for releases)

All other versions — Gradle, Kotlin, Ktor, plugins — are pinned in gradle/libs.versions.toml.

Build and run

./gradlew run                # run the app locally
./gradlew build -x test      # build without tests
./gradlew buildFatJar        # produce build/libs/server.jar
java -jar build/libs/server.jar

The app listens on 8080 (HTTP) by default, with additional ports for JMX and metrics — see the Dockerfile for the full list.

Test

./gradlew check              # full verification (tests + lint)
./gradlew test               # tests only

Tests use Kotest StringSpec. Test sources live under src/test/kotlin/com/readingbat/.

Continuous integration

.github/workflows/ci.yml runs on every push and pull request against master. It builds, tests, and lints on JDK 25 (Temurin) with a single ./gradlew builddetekt and lintKotlin both attach to check, so that one command is the same verification you get locally.

Lint and format

./gradlew lintKotlin detekt  # static analysis + style check
./gradlew formatKotlin       # apply ktlint fixes

Project formatting rules are in .editorconfig. Line endings are normalized by .gitattributes: text files are stored and checked out with LF (*.bat is the sole CRLF exception), so gradlew and the machines/ shell scripts stay runnable on Linux and in Docker regardless of your core.autocrlf setting.

Makefile shortcuts

Most common workflows have a make target. Run make help for the full list:

make build                   # clean and build (no tests)
make tests                   # full test suite
make lint                    # lintKotlin + detekt
make format                  # apply formatting
make uberjar                 # build the fat jar
make run-uber                # run the fat jar
make release                 # build + push multi-arch Docker image
make deploy                  # deploy via secrets/deploy-app.sh
make upgrade-wrapper         # bump the Gradle wrapper to the catalog-pinned version

Docker

The image is built from eclipse-temurin:25-jdk-alpine, runs as a non-root readingbat user, and declares a HEALTHCHECK on /ping. make release publishes a multi-arch (linux/amd64,linux/arm64) image to pambrose/readingbat:{latest,$VERSION}.

A multi-instance local composition is provided in docker-compose.yml.

Releasing and deploying

  1. Bump version= in gradle.properties.
  2. Bump the pinned image tags in docker-compose.yml and machines/content/run.sh to the new version.
  3. Move [Unreleased] entries in CHANGELOG.md under the new version and add a highlights entry to RELEASE_NOTES.md.
  4. make release to build and push the Docker image.
  5. Follow the runbook in docs/release_notes.md to roll the deployment on Digital Ocean.
  6. Cut a GitHub release: tag X.Y.Z (no v prefix), title vX.Y.Z.

Project conventions

See CLAUDE.md for repo conventions (version-catalog discipline, configuration-cache safety, shadowJar duplicate handling, and the gotchas that the code alone won't teach you) — useful for both humans and AI coding agents.

License

Apache License 2.0 — see LICENSE.txt.

About

ReadingBat Website

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Contributors

Languages