name: CI on: push: branches: [main] pull_request: branches: [main] jobs: platform-build: name: Platform (Go) runs-on: ubuntu-latest defaults: run: working-directory: platform steps: - uses: actions/checkout@v4 - uses: actions/setup-go@v5 with: go-version: 'stable' - run: go mod download - run: go build ./cmd/server - run: go build -o molecli ./cmd/cli - run: go vet ./... - name: Run golangci-lint uses: golangci/golangci-lint-action@v4 with: version: latest working-directory: platform args: --timeout 3m continue-on-error: true # Warn but don't block until codebase is clean - name: Run tests with race detection and coverage run: go test -race -coverprofile=coverage.out ./... - name: Check coverage baseline run: | COVERAGE=$(go tool cover -func=coverage.out | grep total | awk '{print $3}' | sed 's/%//') echo "Total coverage: ${COVERAGE}%" THRESHOLD=25 awk "BEGIN{if ($COVERAGE < $THRESHOLD) exit 1}" || { echo "::error::Coverage ${COVERAGE}% is below the ${THRESHOLD}% threshold" exit 1 } canvas-build: name: Canvas (Next.js) runs-on: ubuntu-latest defaults: run: working-directory: canvas steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version: '22' - run: rm -f package-lock.json && npm install - run: npm run build - name: Run tests run: npx vitest run mcp-server-build: name: MCP Server (Node.js) runs-on: ubuntu-latest defaults: run: working-directory: mcp-server steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version: '22' cache: npm cache-dependency-path: mcp-server/package-lock.json - run: npm ci - run: npm run build python-lint: name: Python Lint & Test runs-on: ubuntu-latest defaults: run: working-directory: workspace-template steps: - uses: actions/checkout@v4 - uses: actions/setup-python@v5 with: python-version: '3.11' cache: pip cache-dependency-path: workspace-template/requirements.txt - run: pip install -r requirements.txt pytest pytest-asyncio pytest-cov - run: python -m pytest --tb=short -q --cov=. --cov-report=term-missing # Lint first-party plugins. The validator checks each plugin # against the format it declares — currently agentskills.io for all # of ours, but the same command covers any future shape that lands # under a sibling adapter (MCP, DeepAgents sub-agent, etc.). - name: Install molecule-plugin SDK working-directory: sdk/python run: pip install -e . - name: Lint first-party plugins working-directory: ${{ github.workspace }} run: python -m molecule_plugin validate plugins/molecule-dev plugins/superpowers plugins/ecc - name: Run SDK tests working-directory: sdk/python run: python -m pytest --tb=short -q