Files
executus/.gitea/workflows/ci.yml
T
steve c8559676ed
executus CI / test (push) Has been cancelled
P4b: skill noun + contrib/store (SQLite for budget/persona/skill/audit)
Merges the skill half of the persona/skill pair plus the second nested module.
(Squashed onto main from phase-4b-skill; the audit/budget/persona batteries it
was stacked on already landed via the P4 merge.)

- skill/: clean-redesign Skill noun + LEAN SkillStore (lifecycle/versions/
  schedule only) + ToRunnable + Memory default.
- contrib/store/: separate go.mod carrying modernc.org/sqlite, so the driver
  never enters the core go.sum. db.Budget()/Personas()/Skills()/Audit() back
  all four store seams (JSON-blob + indexed columns; round-trip tested).
  Includes the verified gadfly #5 fixes (AppendVersion tx+UNIQUE+error,
  Mark*ScheduledRun atomic json_set, busy_timeout, NaN guard).
- CI: builds + tests the nested module and asserts it owns the sqlite driver.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-27 00:15:00 -04:00

118 lines
4.5 KiB
YAML

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: 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."