name: executus CI # Go library CI: build, vet, race-tested, tidy-clean, plus the executus # invariant that the CORE module never pulls a host/DB dependency. Mirrors # majordomo's gates; private-module access (the private majordomo dependency) # uses the same Gitea credentials gadfly's CI uses. # # Required repo secrets: # REGISTRY_USER / REGISTRY_PASSWORD Gitea creds with read access to the # private majordomo module. on: push: branches: [main] tags: ["v*"] # Docs/example/meta-only changes don't affect the build — skip the run. # (Path filters are not applied to tag pushes, so v* releases always run.) paths-ignore: - "**.md" - "LICENSE" - ".gitignore" - ".dockerignore" - "examples/**" - "docs/**" pull_request: types: [opened, synchronize, reopened] paths-ignore: - "**.md" - "LICENSE" - ".gitignore" - ".dockerignore" - "examples/**" - "docs/**" workflow_dispatch: {} concurrency: group: executus-${{ github.ref }} cancel-in-progress: true jobs: test: runs-on: ubuntu-latest timeout-minutes: 15 steps: - name: Checkout run: | REPO_URL="https://token:${{ github.token }}@gitea.stevedudenhoeffer.com/${{ github.repository }}.git" if [ "${{ github.event_name }}" = "pull_request" ]; then git clone --depth=1 --branch "${{ github.head_ref }}" "$REPO_URL" . else git clone --depth=1 --branch "${{ github.ref_name }}" "$REPO_URL" . fi - name: Set up Go run: | GO_VERSION=$(grep '^go ' go.mod | awk '{print $2}') curl -sL "https://go.dev/dl/go${GO_VERSION}.linux-amd64.tar.gz" | tar -C /usr/local -xzf - echo "/usr/local/go/bin" >> $GITHUB_PATH echo "GOPATH=${HOME}/go" >> $GITHUB_ENV echo "${HOME}/go/bin" >> $GITHUB_PATH - name: Configure private module access env: REGISTRY_USER: ${{ secrets.REGISTRY_USER }} REGISTRY_PASSWORD: ${{ secrets.REGISTRY_PASSWORD }} run: | git config --global url."https://${REGISTRY_USER}:${REGISTRY_PASSWORD}@gitea.stevedudenhoeffer.com/".insteadOf "https://gitea.stevedudenhoeffer.com/" echo "GOFLAGS=-mod=mod" >> $GITHUB_ENV echo "GONOSUMCHECK=gitea.stevedudenhoeffer.com/*" >> $GITHUB_ENV echo "GONOSUMDB=gitea.stevedudenhoeffer.com/*" >> $GITHUB_ENV echo "GOPRIVATE=gitea.stevedudenhoeffer.com/*" >> $GITHUB_ENV - name: Build run: go build ./... - name: Vet run: go vet ./... - name: Test (race) run: go test -race -count=1 -timeout 5m ./... - name: go mod tidy is clean run: | go mod tidy # go.sum may not exist yet (no external deps), so don't name it as a # diff path (git errors on a missing path). git status flags both a # modified go.mod and a freshly-created untracked go.sum. CHANGES=$(git status --porcelain -- go.mod go.sum) if [ -n "$CHANGES" ]; then echo "go.mod/go.sum not tidy:"; echo "$CHANGES"; git diff -- go.mod; exit 1 fi echo "OK: go.mod/go.sum tidy." - name: Core stays majordomo+stdlib only run: | # The core module must never pull a host/DB dependency. If any of these # appear in go.sum, a battery leaked into the core import graph. [ -f go.sum ] || { echo "OK: no external dependencies yet."; exit 0; } FORBIDDEN='gorm.io|go-redis|redis/go-redis|bwmarrin/discordgo|modernc.org/sqlite|mattn/go-sqlite3|gin-gonic/gin' if grep -qE "$FORBIDDEN" go.sum; then echo "ERROR: forbidden dependency in core go.sum:" grep -E "$FORBIDDEN" go.sum exit 1 fi echo "OK: core go.sum is free of host/DB dependencies." - name: Light-tier canary imports no battery run: | # examples/reviewer is gadfly's shape on the CORE only. If it ever # pulls in a battery (audit/budget/persona/skill/critic/schedule/ # checkpoint/contrib), the light path has regressed. LEAK=$(go list -deps ./examples/reviewer/... | grep -E 'executus/(audit|budget|persona|skill|critic|schedule|checkpoint|contrib)' || true) if [ -n "$LEAK" ]; then echo "ERROR: light-tier canary pulled in a battery:"; echo "$LEAK"; exit 1 fi echo "OK: examples/reviewer is core-only." - name: contrib/store (nested SQLite module — isolated from core) run: | # contrib/store is a SEPARATE module carrying modernc.org/sqlite; the # core's `go test ./...` doesn't reach it. Build + test it on its own, # and confirm it DOES carry the driver the core forbids (proof the # split works: persistence lives here, not in the core go.sum). cd contrib/store go build ./... go test -race -count=1 -timeout 5m ./... grep -qE 'modernc.org/sqlite' go.sum || { echo "ERROR: contrib/store should carry the sqlite driver"; exit 1; } echo "OK: contrib/store builds, tests pass, and owns the SQLite dep."