diff --git a/.gitea/workflows/ci.yml b/.gitea/workflows/ci.yml new file mode 100644 index 0000000..d8ca26a --- /dev/null +++ b/.gitea/workflows/ci.yml @@ -0,0 +1,58 @@ +name: CI + +on: + push: + branches: [main] + tags: ["v*"] + pull_request: + branches: [main] + +jobs: + # ── 1. Quality gate ───────────────────────────────────────────────────────── + check: + name: Lint / Test / Vet + runs-on: self-hosted + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-go@v5 + with: + go-version-file: go.mod + cache: false # self-hosted: Go cache persists on disk between runs + + - name: Verify toolchain + run: | + go version + task --version + govulncheck -version 2>&1 || true + + - name: Install golangci-lint + run: | + curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/HEAD/install.sh \ + | sh -s -- -b "$(go env GOPATH)/bin" v2.11.4 + golangci-lint --version + + - name: Run checks + run: task check + + # ── 2. Mirror to GitHub ───────────────────────────────────────────────────── + mirror: + name: Mirror to GitHub + needs: check + runs-on: self-hosted + if: github.ref == 'refs/heads/main' && github.event_name == 'push' + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Push to GitHub + run: | + mkdir -p ~/.ssh + echo '${{ secrets.GH_DEPLOY_KEY }}' > ~/.ssh/id_rsa_gh_mirror + chmod 600 ~/.ssh/id_rsa_gh_mirror + ssh-keyscan github.com >> ~/.ssh/known_hosts 2>/dev/null + GIT_SSH_COMMAND="ssh -i ~/.ssh/id_rsa_gh_mirror -o IdentitiesOnly=yes" \ + git push git@github.com:mathiasb/hyperguild.git HEAD:main --tags + rm ~/.ssh/id_rsa_gh_mirror + echo "✓ Mirrored to GitHub" diff --git a/Taskfile.yml b/Taskfile.yml index 9caf4e3..0e2e571 100644 --- a/Taskfile.yml +++ b/Taskfile.yml @@ -1,7 +1,11 @@ version: '3' vars: - PROJECT_NAME: '{{.PROJECT_NAME | default "myproject"}}' + PROJECT_NAME: hyperguild + VERSION: + sh: git describe --tags --always --dirty 2>/dev/null || echo "dev" + SHORT_SHA: + sh: git rev-parse --short HEAD tasks: context:sync: @@ -19,65 +23,7 @@ tasks: context:sync:cursor: cmds: [bash scripts/context-sync.sh cursor] - dev: - desc: Start development server - cmds: - - go run ./cmd/server - - build: - desc: Build the binary - cmds: - - go build -o bin/{{.PROJECT_NAME}} ./cmd/server - - check: - desc: Run all checks (lint + test + vet) - cmds: - - task: lint - - task: test - - task: vet - - lint: - cmds: [golangci-lint run ./...] - test: - cmds: [go test -race -count=1 ./...] - vet: - cmds: - - go vet ./... - - govulncheck ./... || true - - up: - desc: Start containers - cmds: [docker compose up -d] - down: - cmds: [docker compose down] - - init: - desc: Initialize a new project from this template - cmds: - - bash scripts/init.sh - - supervisor:dev: - desc: Run supervisor MCP server (development) - cmds: - - go run ./cmd/supervisor - - supervisor:build: - desc: Build supervisor binary - cmds: - - go build -o bin/supervisor ./cmd/supervisor - - bridge:build: - desc: Build stdio↔HTTP bridge for Claude Code MCP integration - cmds: - - go build -o bin/supervisor-bridge ./cmd/bridge - - supervisor:test:smoke: - desc: Smoke test supervisor via MCP (requires supervisor:dev running) - cmds: - - | - curl -s -X POST http://localhost:${SUPERVISOR_PORT:-3200}/mcp \ - -H "Content-Type: application/json" \ - -d '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}' | jq . + # ── Development ──────────────────────────────────────────────────────────── start: desc: Start ingestion + supervisor (requires goreman — go install github.com/mattn/goreman@latest) @@ -91,23 +37,95 @@ tasks: - lsof -ti:3200 | xargs kill -9 2>/dev/null || true - echo "hyperguild stopped" - ingestion:build: - desc: Build ingestion server binary + supervisor:dev: + desc: Run supervisor MCP server (development) cmds: - - go build -o bin/ingestion-server ./cmd/server - dir: ingestion + - go run ./cmd/supervisor ingestion:dev: desc: Run ingestion server in development mode + dir: ingestion env: INGEST_BRAIN_DIR: "{{.ROOT_DIR}}/brain" INGEST_PORT: "3300" cmds: - go run ./cmd/server - dir: ingestion - ingestion:test: - desc: Run ingestion tests + # ── Build ────────────────────────────────────────────────────────────────── + + build: + desc: Build all binaries cmds: - - go test ./... -v + - task: supervisor:build + - task: bridge:build + - task: ingestion:build + + supervisor:build: + desc: Build supervisor binary + cmds: + - go build -trimpath -ldflags="-s -w -X main.version={{.VERSION}}" -o bin/supervisor ./cmd/supervisor + + bridge:build: + desc: Build stdio↔HTTP bridge for Claude Code MCP integration + cmds: + - go build -trimpath -ldflags="-s -w" -o bin/supervisor-bridge ./cmd/bridge + + ingestion:build: + desc: Build ingestion server binary dir: ingestion + cmds: + - go build -trimpath -ldflags="-s -w" -o ../bin/ingestion-server ./cmd/server + + # ── Quality ──────────────────────────────────────────────────────────────── + + check: + desc: Run all checks (lint + test + vet) across all modules + cmds: + - task: lint + - task: test + - task: vet + + lint: + cmds: + - golangci-lint run ./... + - cd ingestion && golangci-lint run ./... + + test: + cmds: + - go test -race -count=1 ./... + - cd ingestion && go test -race -count=1 ./... + + vet: + cmds: + - go vet ./... + - govulncheck ./... || true + - cd ingestion && go vet ./... + + supervisor:test:smoke: + desc: Smoke test supervisor via MCP (requires start running) + cmds: + - | + curl -s -X POST http://localhost:${SUPERVISOR_PORT:-3200}/mcp \ + -H "Content-Type: application/json" \ + -d '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}' | jq . + + # ── Git / Release ────────────────────────────────────────────────────────── + + tag: + desc: Create and push a semver tag (usage — task tag version=v1.2.3) + preconditions: + - sh: '[[ "{{.version}}" =~ ^v[0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9.]+)?$ ]]' + msg: "version must be semver, e.g. v1.2.3 or v1.2.3-rc.1" + - sh: "git diff --quiet && git diff --cached --quiet" + msg: "working tree must be clean before tagging" + cmds: + - git tag -a {{.version}} -m "Release {{.version}}" + - git push origin {{.version}} + + push: + desc: Push current branch and tags to origin + vars: + BRANCH: + sh: git rev-parse --abbrev-ref HEAD + cmds: + - git push origin {{.BRANCH}} --tags