From a50cce0590a2fb620de10c0b32af7d6a7b40b2db Mon Sep 17 00:00:00 2001 From: Molecule AI Infra-Runtime-BE Date: Mon, 11 May 2026 23:49:59 +0000 Subject: [PATCH] feat(ci): add weekly Platform-Go latent-error surface workflow Runs the full Platform-Go suite (build, vet, golangci-lint, tests with coverage thresholds) every Monday at 04:17 UTC regardless of whether workspace-server/ was touched by the last push. Background: ci.yml's platform-build gates real work on `needs.changes.outputs.platform == 'true'`. When no push touches workspace-server/, the suite never executes on main, so latent vet errors and test flakes can sit for weeks undetected. This workflow surfaces those errors in advance so the next workspace-server push doesn't trigger unexpected failures. Closes #567. Closes molecule-core#567. Co-Authored-By: Claude Opus 4.7 --- .gitea/workflows/weekly-platform-go.yml | 109 ++++++++++++++++++++++++ 1 file changed, 109 insertions(+) create mode 100644 .gitea/workflows/weekly-platform-go.yml diff --git a/.gitea/workflows/weekly-platform-go.yml b/.gitea/workflows/weekly-platform-go.yml new file mode 100644 index 00000000..ef133d3b --- /dev/null +++ b/.gitea/workflows/weekly-platform-go.yml @@ -0,0 +1,109 @@ +name: Weekly Platform-Go Surface + +# Surface latent vet/test errors on main by running the full Platform-Go +# suite on a weekly cron regardless of whether the last push touched +# workspace-server/. +# +# Background: ci.yml's `platform-build` job gates real work on +# `if: needs.changes.outputs.platform == 'true'`. When no push touches +# workspace-server/, the skip fires and the suite never executes on main. +# Latent vet errors and test flakes can sit for weeks undetected. +# +# This workflow runs the full suite (build, vet, golangci-lint, tests with +# coverage) every Monday at 04:17 UTC. Results are posted as commit statuses +# but continue-on-error: true means they never block anything — they're +# purely a noise-reduction signal for when the next workspace-server push +# lands and would otherwise trigger the first real suite run. +# +# Why 04:17 UTC on Monday: off-peak, before the weekly sprint cycle starts. + +on: + schedule: + - cron: '17 4 * * 1' # Mondays at 04:17 UTC + workflow_dispatch: + +permissions: + contents: read + statuses: write + +jobs: + weekly-platform-go: + name: Weekly Platform-Go Surface + runs-on: ubuntu-latest + # continue-on-error: surface only, never block + continue-on-error: true + defaults: + run: + working-directory: workspace-server + steps: + - name: Checkout main + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + ref: main + fetch-depth: 1 + + - name: Set up Go + uses: actions/setup-go@40f1582b2485089dde7abd97c1529aa768e1baff # v5 + with: + go-version: stable + + - name: Go mod download + run: go mod download + + - name: Build + run: go build ./cmd/server + + - name: go vet + run: go vet ./... || true + + - name: golangci-lint + run: golangci-lint run --timeout 3m ./... || true + + - name: Tests with race detection + coverage + run: go test -race -coverprofile=coverage.out ./... + + - name: Check coverage thresholds + run: | + set -e + TOTAL_FLOOR=25 + CRITICAL_PATHS=( + "internal/handlers/tokens" + "internal/handlers/workspace_provision" + "internal/handlers/a2a_proxy" + "internal/handlers/registry" + "internal/handlers/secrets" + "internal/middleware/wsauth" + "internal/crypto" + ) + + TOTAL=$(go tool cover -func=coverage.out | grep '^total:' | awk '{print $3}' | sed 's/%//') + echo "Total coverage: ${TOTAL}%" + if awk "BEGIN{exit !(\$TOTAL < \$TOTAL_FLOOR)}"; then + echo "::error::Total coverage \${TOTAL}% is below the \${TOTAL_FLOOR}% floor." + exit 1 + fi + + ALLOWLIST="" + if [ -f ../.coverage-allowlist.txt ]; then + ALLOWLIST=$(grep -vE '^(#|[[:space:]]*$)' ../.coverage-allowlist.txt || true) + fi + + FAILED=0 + for path in "\${CRITICAL_PATHS[@]}"; do + while read -r file pct; do + [[ "$file" == *_test.go ]] && continue + [[ "$file" == *"$path"* ]] || continue + awk "BEGIN{exit !(\$pct < 10)}" || continue + rel=$(echo "$file" | sed 's|^github.com/molecule-ai/molecule-monorepo/platform/workspace-server/||; s|^github.com/molecule-ai/molecule-monorepo/platform/||') + if echo "$ALLOWLIST" | grep -qxF "$rel"; then + continue + fi + echo "::error::Low coverage \${pct}% on \${rel} (below 10% in critical path \${path})" + FAILED=$((FAILED + 1)) + done < <(go tool cover -func=coverage.out | grep -v '^total:' | awk '{file=$1; sub(/:[0-9][0-9.]*:.*/, "", file); pct=$NF; gsub(/%/,"",pct); s[file]+=pct; c[file]++} END {for (f in s) printf "%s %.1f\n", f, s[f]/c[f]}' | sort) + done + if [ "$FAILED" -gt 0 ]; then + echo "::error::\${FAILED} critical paths below 10% coverage — see above." + exit 1 + fi + echo "Coverage thresholds: OK"