Skip to content
Draft
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
35 changes: 35 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

## Commands

```bash
make build # docker buildx build -t hexletbasics/base-image .
make push # docker push hexletbasics/base-image
```

Validation (used by derived images via `common/common.mk`):

```bash
make check # runs all checks: description-lint, schema-validate, test
make description-lint # yamllint on module description YAML files
make schema-validate # ajv-cli validates spec/language/module/lesson YAML against JSON schemas
make test # runs tests in all module Makefiles
```

## Architecture

This is a Docker base image for HexletBasics's coding exercise platform. Derived images extend it with language-specific runtimes (Python, Ruby, Java, etc.).

**Base image** (`Dockerfile`): built from `node:25-slim`, includes pnpm, python3, git, jq, yamllint, yq, ajv-cli. Published to DockerHub as `hexletbasics/base-image:latest`.

**Multi-arch strategy**: amd64 is built and pushed on every push to `main` (GitHub Actions). arm64 is built nightly on an ARM64 runner. A combined multi-arch manifest is created and pushed as `:latest` after the nightly arm64 build.

**`common/` directory**: copied into derived images at `/opt/basics/common`. Contains:
- JSON schemas (`spec.json`, `module.json`, `language.json`, `lesson.json`) for validating course content YAML
- Validation shell scripts in `common/bin/` that call `ajv-cli`
- `common.mk` — a shared Makefile included by derived image repos to run the full validation chain
- `yamllint.yml` — shared yamllint config (line-length checks disabled)

Derived image repos include `common.mk` via `include /opt/basics/common/common.mk` and rely on this image being available on DockerHub.
4 changes: 3 additions & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ ENV LANG=C.UTF-8
ENV LC_ALL=C.UTF-8
ENV DEBIAN_FRONTEND=noninteractive
ENV PNPM_HOME="/pnpm"
ENV PATH="$PNPM_HOME:$PATH"
ENV PATH="$PNPM_HOME/bin:$PNPM_HOME:$PATH"

RUN rm -f /etc/apt/apt.conf.d/docker-clean \
&& echo 'Binary::apt::APT::Keep-Downloaded-Packages "true";' > /etc/apt/apt.conf.d/keep-cache
Expand All @@ -22,4 +22,6 @@ RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \

RUN pnpm install -g ajv-cli

RUN pip install rumdl --break-system-packages

COPY ./common /opt/basics/common
3 changes: 3 additions & 0 deletions common/.rumdl.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# TODO: move to base image
[global]
disable = ["MD013", "MD041", "MD033"]
9 changes: 7 additions & 2 deletions common/common.mk
Original file line number Diff line number Diff line change
@@ -1,14 +1,19 @@
COMMON_DIR := /opt/basics/common

check: description-lint code-lint schema-validate test
check: description-lint code-lint schema-validate markdown-lint test

description-lint:
yamllint modules -c $(COMMON_DIR)/yamllint.yml

test:
@(for i in $$(find modules/** -type f -name Makefile); do make test -C $$(dirname $$i) || exit 1; done)

# TODO: add markdown linter and spellckeck (languagetool)
markdown-lint:
rumdl check --config $(COMMON_DIR)/.rumdl.toml modules

markdown-lint-fix:
rumdl fmt --config $(COMMON_DIR)/.rumdl.toml modules

schema-validate:
@$(COMMON_DIR)/bin/validate-spec.sh
@$(COMMON_DIR)/bin/validate-language.sh
Expand Down
Loading