diff --git a/.github/codecov.yml b/.github/codecov.yml index d27eaa4ee..046d86e02 100644 --- a/.github/codecov.yml +++ b/.github/codecov.yml @@ -1,7 +1,7 @@ --- # Coverage target for this repository. # -# `target: 99.9%` is declared again as JUST_COVERAGE_TARGET in this repository's +# `target: 99.9%` is declared again as `go_coverage_target` in this repository's # justfile, which overrides the org-wide default of 100 from the shared go # module. osapi has 9 uncovered statements across 7 functions (99.9359%); raise # both to 100 once they are covered. Neither system can read the other's config, @@ -9,12 +9,12 @@ # # The threshold absorbs rounding, not regression. With precision 2 and round # down, a change in statement count can shift the reported figure and fail the -# status on an artifact. `just go::unit-cov-check` is the exact check; this +# status on an artifact. `just go-unit-cov-check` is the exact check; this # tolerance exists so Codecov's own rounding does not report a failure the # coverage does not have. # # There is deliberately no `ignore:` list. Exclusions are defined once in -# .coverignore and applied by `just go::unit-cov` before the profile is +# .coverignore and applied by `just go-unit-cov` before the profile is # uploaded, so excluded files never reach Codecov. A second list here would be # free to drift from that one. coverage: diff --git a/.github/workflows/go-int.yml b/.github/workflows/go-int.yml index 970eb8c57..f2cf38bae 100644 --- a/.github/workflows/go-int.yml +++ b/.github/workflows/go-int.yml @@ -28,11 +28,11 @@ jobs: run: just fetch - name: Deps run: | - just go::deps + just go-deps just react-deps - name: Build UI run: just react-build - name: Linux tuning run: just linux-tune - name: Integration - run: just go::unit-int + run: just go-unit-int diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index 2a1666731..3ea30922e 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -28,8 +28,8 @@ jobs: run: just fetch - name: Deps run: | - just go::deps - just go::mod + just go-deps + just go-mod just react-deps - name: Test run: just test diff --git a/.github/workflows/just-lint.yml b/.github/workflows/just-lint.yml index 74a2ee343..f8f043c72 100644 --- a/.github/workflows/just-lint.yml +++ b/.github/workflows/just-lint.yml @@ -16,5 +16,7 @@ jobs: uses: extractions/setup-just@v4 - name: Fetch justfiles run: just fetch + - name: Record just version + run: just --version - name: Lint justfiles run: just just::fmt-check diff --git a/.mise.toml b/.mise.toml index 53aecf161..738fa1d27 100644 --- a/.mise.toml +++ b/.mise.toml @@ -1,4 +1,5 @@ [tools] go = "1.25" +just = "latest" node = "22" bun = "latest" diff --git a/CLAUDE.md b/CLAUDE.md index 3fdb54417..aeea9d6b7 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -26,10 +26,10 @@ Quick reference for common commands: just deps # Install all dependencies just build # Build production binary (React UI + Go) just test # Run all tests (lint + unit + coverage) -just go::unit # Run unit tests only -just go::unit-int # Run integration tests (requires running osapi) -just go::vet # Run golangci-lint -just go::fmt # Auto-format (gofumpt + golines) +just go-unit # Run unit tests only +just go-unit-int # Run integration tests (requires running osapi) +just go-vet # Run golangci-lint +just go-fmt # Auto-format (gofumpt + golines) go test -run TestName -v ./internal/job/... # Run a single test just react-dev # Start UI dev server (http://localhost:5173) @@ -772,8 +772,8 @@ service. Follow the same principles as the orchestrator examples: ```bash just generate # regenerate specs + code go build ./... # compiles -just go::unit # tests pass -just go::vet # lint passes +just go-unit # tests pass +just go-vet # lint passes ``` ## Code Standards (MANDATORY) @@ -793,12 +793,12 @@ func FunctionName( Three test layers: - **Unit tests** (`*_test.go`, `*_public_test.go`) — fast, mocked - dependencies, run with `just go::unit`. Includes `TestXxxHTTP` / + dependencies, run with `just go-unit`. Includes `TestXxxHTTP` / `TestXxxRBACHTTP` methods that send raw HTTP through real Echo middleware with mocked backends. - **Integration tests** (`test/integration/`) — build and start a real `osapi` binary, exercise CLI commands end-to-end. Guarded by - `//go:build integration` tag, run with `just go::unit-int`. New API + `//go:build integration` tag, run with `just go-unit-int`. New API domains should include a `{domain}_test.go` smoke suite. Write tests (mutations) must be guarded by `skipWrite(s.T())` so CI can run read-only tests by default (`OSAPI_INTEGRATION_WRITES=1` enables diff --git a/docs/docs/sidebar/development/development.md b/docs/docs/sidebar/development/development.md index b6a5aa926..a289da270 100644 --- a/docs/docs/sidebar/development/development.md +++ b/docs/docs/sidebar/development/development.md @@ -58,9 +58,9 @@ Go code should be formatted by [`gofumpt`][gofumpt] and linted using formatted and linted by [Prettier][]. This style is enforced by CI. ```bash -just go::fmt-check # Check formatting -just go::fmt # Auto-fix formatting -just go::vet # Run linter +just go-fmt-check # Check formatting +just go-fmt # Auto-fix formatting +just go-vet # Run linter ``` ## Running your changes @@ -106,15 +106,15 @@ recipes. ```bash just test # Run all tests (lint + unit + coverage) -just go::unit # Run unit tests only -just go::unit-int # Run integration tests (requires running osapi) +just go-unit # Run unit tests only +just go-unit-int # Run integration tests (requires running osapi) ``` Coverage is gated at 99.9%. `just test` fails if total coverage drops below it, so a change that adds untested code fails locally and in CI: ```bash -just go::unit-cov-check # Report coverage and fail below the target +just go-unit-cov-check # Report coverage and fail below the target ``` The target is declared in `.github/codecov.yml` and in the shared `go` justfile diff --git a/docs/docs/sidebar/development/testing.md b/docs/docs/sidebar/development/testing.md index c81a09267..a1e97b7b8 100644 --- a/docs/docs/sidebar/development/testing.md +++ b/docs/docs/sidebar/development/testing.md @@ -15,8 +15,8 @@ $ just deps Unit tests run with mocked dependencies and require no external services: ```bash -$ just go::unit # Run unit tests -$ just go::unit-cov # Run with coverage report +$ just go-unit # Run unit tests +$ just go-unit-cov # Run with coverage report $ just test # Run all checks (lint + unit + coverage) ``` @@ -33,7 +33,7 @@ API server, agent), and exercise CLI commands end-to-end. They are guarded by a `//go:build integration` tag and located in `test/integration/`: ```bash -$ just go::unit-int # Run integration tests +$ just go-unit-int # Run integration tests ``` The test harness allocates random ports, generates a JWT, and starts the server @@ -45,7 +45,7 @@ commands with `--json` output. Auto format code: ```bash -$ just go::fmt +$ just go-fmt ``` ## Listing Recipes diff --git a/docs/docs/sidebar/development/ui-development.md b/docs/docs/sidebar/development/ui-development.md index f8627092f..ce7f6c481 100644 --- a/docs/docs/sidebar/development/ui-development.md +++ b/docs/docs/sidebar/development/ui-development.md @@ -70,7 +70,7 @@ just build ``` This is the top-level build recipe. It runs `just react-build` first (to -populate `ui/dist/` with static assets), then `just go::build` to produce the Go +populate `ui/dist/` with static assets), then `just go-build` to produce the Go binary with the assets embedded via the `//go:embed` directive in `ui/embed.go`. The controller API serves these assets at runtime from the embedded filesystem — no separate web server is required. diff --git a/justfile b/justfile index e53e7f32c..199872176 100644 --- a/justfile +++ b/justfile @@ -1,18 +1,21 @@ +set allow-duplicate-variables + # Optional modules: mod? allows `just fetch` to work before .just/remote/ exists. # Recipes below use `just` subcommands instead of dependency syntax because just - # validates dependencies at parse time, which would fail when modules aren't loaded. -# Coverage target. Below the org-wide 100% because osapi has 9 uncovered -# statements across 7 functions (99.9359%). Raise to 100 once they are covered; -# this holds the current level so it cannot decay in the meantime. Mirrored in -# .github/codecov.yml — change both together. -export JUST_COVERAGE_TARGET := "99.9" - -# The React application lives in ui/, not at the repository root. The flat -# react module requires the importing justfile to declare it. +# The React application lives in ui/, not at the repository root, so the react +# module's default of "." is reassigned above the import. + react_dir := "ui" -mod? go '.just/remote/go.mod.just' +# Minimum total coverage. Below the org-wide 100% because nine statements are +# unreachable guards that cannot execute. Declared again in .github/codecov.yml +# — change both together. + +go_coverage_target := "99.9" + +import? '.just/remote/go.just' + mod? docs '.just/remote/docs.mod.just' mod? just '.just/remote/just.mod.just' mod? docker '.just/remote/docker.mod.just' @@ -24,8 +27,7 @@ import? '.just/remote/react.just' # Fetch shared justfiles from osapi-justfiles fetch: mkdir -p .just/remote - curl -sSfL https://raw.githubusercontent.com/osapi-io/osapi-justfiles/refs/heads/main/go.mod.just -o .just/remote/go.mod.just - curl -sSfL https://raw.githubusercontent.com/osapi-io/osapi-justfiles/refs/heads/main/go.just -o .just/remote/go.just + curl -sSfL https://raw.githubusercontent.com/osapi-io/osapi-justfiles/refs/heads/main/go/go.just -o .just/remote/go.just curl -sSfL https://raw.githubusercontent.com/osapi-io/osapi-justfiles/refs/heads/main/docs.mod.just -o .just/remote/docs.mod.just curl -sSfL https://raw.githubusercontent.com/osapi-io/osapi-justfiles/refs/heads/main/docs.just -o .just/remote/docs.just curl -sSfL https://raw.githubusercontent.com/osapi-io/osapi-justfiles/refs/heads/main/just.mod.just -o .just/remote/just.mod.just @@ -38,8 +40,8 @@ fetch: # Install all dependencies deps: - just go::deps - just go::mod + just go-deps + just go-mod just docs::deps just react-deps @@ -52,12 +54,12 @@ build: test: linux-tune just just::fmt-check just react-build - just go::test + just go-test # Generate code generate: redocly join --prefix-tags-with-info-prop title -o internal/controller/api/gen/api.yaml internal/controller/api/*/gen/api.yaml internal/controller/api/node/*/gen/api.yaml - just go::generate + just go-generate just docs::generate cp internal/controller/api/gen/api.yaml ui/src/sdk/gen/api.yaml just react-generate @@ -67,8 +69,8 @@ ready: just generate just just::fmt just docs::fmt - just go::fmt - just go::vet + just go-fmt + just go-vet just react-fmt just react-lint just react-build diff --git a/ui/justfile b/ui/justfile index ef9507c88..98c252fea 100644 --- a/ui/justfile +++ b/ui/justfile @@ -1,4 +1,5 @@ # The React application is this directory. + react_dir := "." # Optional modules: mod? allows `just fetch` to work before .just/remote/ exists.