Skip to content

Merge pull request #497 from rossoctl/feat/summarizer-per-thread #1191

Merge pull request #497 from rossoctl/feat/summarizer-per-thread

Merge pull request #497 from rossoctl/feat/summarizer-per-thread #1191

Workflow file for this run

name: CI
on:
push:
branches: [main]
paths-ignore: &non-go-paths
# Markdown and the hand-written docs site. NOT examples/** — unlike docs.yaml's own
# filter, this workflow's `go test ./...` genuinely exercises that directory
# (github.com/rossoctl/context-guru/examples/llm-d-service/client shows up in its own
# coverage output), so excluding it here would skip real Go code (#369).
- "**/*.md"
- docs/**
- theme/**
- mkdocs.yml
- requirements-docs.txt
- context-guru-plugin/skills/**/*.md
- LICENSE
pull_request:
paths-ignore: *non-go-paths
permissions:
contents: read
jobs:
build-test:
runs-on: ubuntu-latest
env:
CGO_ENABLED: "1"
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
# go.mod is the single source of truth for the toolchain. Pinning a literal here is
# what let CI validate on 1.25 while go.mod declared 1.26.4 and releases built on
# 1.26 (#152) — three numbers that have to agree and no mechanism making them.
go-version-file: go.mod
- name: Lint
run: make lint
- name: Test & coverage
run: |
make cover
# Accurate cross-package total (statement-weighted) → PR/run job summary + log.
total=$(go tool cover -func=coverage.out | awk '/^total:/ {print $3}')
echo "### Test coverage: ${total} (cross-package, statement-weighted)" >> "$GITHUB_STEP_SUMMARY"
echo "Total coverage: ${total}"
- name: Per-package coverage (log)
# Derived from the coverage.out that `make cover` above already wrote, not a second
# test run: this used to be `go test -cover ./...`, re-running the entire suite a
# second time (without -race) purely to print these numbers — 5m29s of pure
# duplication on a green run (#366).
#
# Not a byte-for-byte match for the old numbers, and that's a real semantic
# difference, not a bug: `make cover` runs with -coverpkg=./..., so coverage.out
# already has one entry per source block PER PACKAGE TESTED (~30x duplication for
# a block in a widely-imported package), each recording whether THAT package's own
# test run hit it. Deduping by block and summing hits across those duplicates gives
# "was this line hit by anything in the whole suite" — cross-package coverage, not
# each package's isolated self-coverage. For a package nothing else imports (e.g.
# dash) the two are close (measured: 85.3% here vs 84.6% self-coverage). For one
# widely imported (store, schema) this one is a few points higher, because other
# packages' tests genuinely do exercise some of its code too — which is a more
# honest "is this code covered" number, not a less accurate one.
run: |
awk 'NR==1{next} {
n=split($1,a,":")
key=$1
cnt[key]+=$3
nstmt[key]=$2
path[key]=a[1]
}
END {
for (k in cnt) {
p=path[k]
sub(/\/[^\/]*$/, "", p)
total[p]+=nstmt[k]
if (cnt[k]>0) covered[p]+=nstmt[k]
}
for (p in total) {
pct = (total[p]>0) ? covered[p]/total[p]*100 : 0
printf "%s\t%.1f%% of statements\n", p, pct
}
}' coverage.out | sort
- name: Build
run: make build
# The binary needs no C toolchain — asserted, not asserted-in-a-comment.
#
# Our own docs told every evaluator to install one (`docs/setup.md` even named bifrost's
# tokenizer as a cgo dependency, which it never was). The only cgo dependency is tree-sitter,
# behind the `cg_skeleton` build tag. Nothing checked that, and the `build-test` job above runs
# exclusively with CGO_ENABLED=1 because `go test -race` requires it — so the configuration a
# user would actually build was never exercised.
#
# CGO_ENABLED=0 is what does the work: with cgo off the toolchain never consults CC at all, so a
# dependency that needs it fails to BUILD here rather than in a stranger's terminal. CC is pointed
# at a nonexistent path anyway, as a tripwire for the day somebody sets CGO_ENABLED=1 in this job
# and expects it to still be testing the same thing.
purego:
runs-on: ubuntu-latest
env:
CGO_ENABLED: "0"
CC: /nonexistent-c-compiler
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
# go.mod is the single source of truth for the toolchain. Pinning a literal here is
# what let CI validate on 1.25 while go.mod declared 1.26.4 and releases built on
# 1.26 (#152) — three numbers that have to agree and no mechanism making them.
go-version-file: go.mod
- name: Build with no C compiler available
run: |
go build -o /tmp/cg-purego ./cmd/context-guru-proxy
file /tmp/cg-purego | tee /dev/stderr | grep -q "statically linked"
- name: It has to start, not just link
run: |
LISTEN_ADDR=127.0.0.1:4471 CONTEXT_GURU_KEEPALIVE=off /tmp/cg-purego &
for _ in $(seq 1 40); do
sleep 0.25
curl -fsS http://127.0.0.1:4471/healthz && break
done
curl -fsS http://127.0.0.1:4471/healthz | grep -q ok
# And the guard that matters most to a CGO-free build: a preset naming a component which is
# not registered without cgo starts the proxy and then fails at pipeline build. That is the
# `preset: coding` / `unknown component "skeleton"` breakage, and TestEveryPresetBuilds
# covers it — but it had never run in this configuration.
# -p 1: run one package binary at a time.
#
# A CI runner has 2 cores, and `go test` otherwise starts up to GOMAXPROCS package binaries
# in parallel. Adding this job therefore added a SECOND heavily-parallel run of the proxy
# package per PR, and under that contention a timing-sensitive control-plane test
# (TestCtlGetCampaignAggregatesPredictedAndRealPerTenant — rossoctl/context-guru#163) failed
# twice on unrelated PRs, then passed on re-run and passes 3/3 locally on main and on the
# branch. That flake is not this job's business to hunt, but it IS this job's business not to
# provoke it: serialising costs about a minute and removes the contention this job added.
- name: Test the packages whose behaviour depends on which components compile in
run: go test -p 1 ./config/... ./components/... ./apply/... ./proxy/... ./store/...
trivy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Trivy filesystem scan
uses: aquasecurity/trivy-action@v0.36.0
with:
scan-type: fs
ignore-unfixed: true
severity: CRITICAL,HIGH
exit-code: '1'