# Test, Go. Push and pull request to development. Never on main. # # The gates are the ones the justfile's `gates` recipe runs, minus race: the shared # runner box cannot afford the race detector on every push, so it lives in race.yml, # dispatched by hand. The box is small and sits beside Gitea, so parallelism is bounded # on purpose and everything runs in one job; extra jobs would duplicate the checkout, # the Go setup and the dependency download without buying any parallelism. # # Every step is one command, so the step that fails is the gate that failed, and no shell # option has to be trusted for the run to stop. The scripted steps are Perl, not shell and # not Python: Perl behaves the same on both runner images, there is no bashism to trip over # on ash, and it is one language instead of two. The Perl uses builtins only, because # nothing beyond `perl` itself may be assumed present. # # Project facts the template had to bend for: the portable build runs at the toolchain # default with nothing pinned, the oracle digests are recorded per platform there, and # the package pattern is the logic packages of the project's justfile `packages`, # which keeps the main-program examples out of the suite. The benchmark smoke that # once rode along here is retired outright: the minimum degree battery's 3-D mesh # scan alone runs for minutes on one core and allocates terabytes cumulatively, so # no form of it fits the shared box, and benchmarking is deliberate work on a # developer machine, where the battery is survivable and the numbers are the point. name: Test on: push: branches: [development] pull_request: branches: [development] env: # One core: parallelism buys no speed here and costs memory the box does not have. GOFLAGS: -p=1 GOMAXPROCS: "2" # A superseded run of the same ref is cancelled instead of queueing behind one that # no longer matters. Verified on Gitea 1.27.1 on 2026-09-17: a queued run whose ref # moved on is cancelled before it ever reaches the runner, while a run already # dispatched there runs to completion. concurrency: group: ${{ gitea.workflow }}-${{ gitea.ref }} cancel-in-progress: true jobs: test: runs-on: fedora timeout-minutes: 10 steps: - name: Install git and Perl # The runner images are minimal: checkout needs git and the scripted steps # below are Perl. Both installs are no-ops where the package already exists. run: dnf install -y git perl - uses: actions/checkout@v7 - uses: actions/setup-go@v6 with: # The module is the source of truth for the version, so it cannot drift. go-version-file: go.mod cache: true # The steps follow the `gates` order of the justfile contract: build, format, # vet, test. The vet gate is go vet and go fix -diff, two steps here. - name: Build # The examples are main programs; the build is what compiles them. run: go build ./... - name: Format run: | perl -e ' open(my $g, q{-|}, q{gofmt}, q{-l}, q{.}) or die qq{gofmt: $!}; my @bad = <$g>; close($g); print @bad; exit(@bad ? 1 : 0); ' - name: Vet run: go vet ./... - name: Modernise # Exits non-zero when it has something to rewrite, so it needs no output capture. run: go fix -diff ./... - name: Tests # Equal to `packages` in the project's justfile, so the floor is the same # number the local gate reports. The inner timeout matches the job's, so a # hanging test reports its own goroutine dump rather than a silent job kill. # The local `just test` allows 30 minutes for a warm 32-core box; this # runner is one shared core, where the suite stays well inside the ten # minutes its budget has always allowed. run: go test -count=1 -timeout 10m -coverprofile=coverage.out . ./internal/... ./grad/... ./integrate/... ./io/... ./linalg/... ./optim/... ./signal/... ./spmd/... ./stats/... - name: Coverage floor run: | perl -e ' open(my $c, q{-|}, q{go}, q{tool}, q{cover}, q{-func=coverage.out}) or die qq{cover: $!}; my $total; while (my $l = <$c>) { $total = $1 if $l =~ m{^total:\s+\S+\s+([0-9.]+)%} } close($c); die qq{no total line in coverage.out\n} unless defined $total; printf qq{Total coverage: %s%%\n}, $total; exit($total < 80 ? 1 : 0); ' - name: Oracle digests for this platform # TestOracle verifies the pinned digest block for GOOS/GOARCH and skips # loudly with instructions when the platform has none yet. run: go test -run TestOracle -v .