name: Foundry Go checks on: [push, pull_request] jobs: check: runs-on: ces-control # Cold toolchain installation can exceed ten minutes on the existing runner. timeout-minutes: 30 steps: - uses: actions/checkout@v4 - uses: actions/setup-go@v5 with: go-version-file: go.mod cache: false - name: Check formatting, test and build run: | set -eu test -z "$(gofmt -l cmd internal)" go test -mod=readonly ./... go build -mod=readonly -o bin/foundry ./cmd/foundry - name: Check Slack OAuth configuration and endpoint if: gitea.event_name == 'push' env: SLACK_CLIENT_ID: ${{ secrets.SLACK_CLIENT_ID }} SLACK_CLIENT_SECRET: ${{ secrets.SLACK_CLIENT_SECRET }} run: | python3 - <<'PYSLACK' import json, os, secrets, sys, urllib.parse, urllib.request client = os.environ.get("SLACK_CLIENT_ID", "") secret = os.environ.get("SLACK_CLIENT_SECRET", "") if not client and not secret: print("Slack client verification skipped because credentials are not configured") sys.exit(0) if not client or not secret: sys.exit("Both Slack client secrets must be configured") class NoRedirect(urllib.request.HTTPRedirectHandler): def redirect_request(self, *args, **kwargs): return None opener = urllib.request.build_opener(NoRedirect) code = "foundry-invalid-preflight-" + secrets.token_hex(16) def probe(password): body = urllib.parse.urlencode({ "client_id": client, "client_secret": password, "code": code, "grant_type": "authorization_code", "redirect_uri": "https://api.foundry.entroia.com/auth/slack/callback" }).encode() request = urllib.request.Request( "https://slack.com/api/openid.connect.token", data=body, headers={"Content-Type": "application/x-www-form-urlencoded"}) with opener.open(request, timeout=20) as response: result = json.load(response) return result.get("error", "") try: actual = probe(secret) control = probe(secrets.token_hex(32)) except Exception as error: sys.exit("Slack preflight request failed (" + type(error).__name__ + ")") if actual in ("invalid_code", "invalid_grant") and control in ("bad_client_secret", "invalid_client"): print("Slack client credentials accepted; invalid-secret negative control rejected") print("A real user authorization is still required to verify the complete login") elif actual in ("invalid_code", "invalid_grant") and control in ("invalid_code", "invalid_grant"): print("Both Slack Actions secrets are available and the OAuth endpoint is reachable") print("Slack rejected the placeholder code before validating the client secret") print("Client-secret validity requires a real user authorization; this is not a complete login test") else: known = {"invalid_client_id", "bad_client_secret", "invalid_client", "invalid_code", "invalid_grant", "bad_redirect_uri", "accesslimited", "ratelimited"} print("Configured credential result:", actual if actual in known else "unclassified") print("Negative control result:", control if control in known else "unclassified") sys.exit("Slack client preflight could not verify the configured credentials") PYSLACK - name: Fetch pinned headless HTTP integration client env: HEADLESS_CLIENT_REVISION: 3a71c9ac57b775524686feb20f2165587d535050 run: | set -eu mkdir -p .headless-client curl --fail --silent --show-error --location \ "https://gitea.entroia.com/Zayden-Jung/Endoleap/archive/$HEADLESS_CLIENT_REVISION.tar.gz" \ | tar -xz --strip-components=1 -C .headless-client test -f .headless-client/tests/headless/foundry.integration.mjs printf 'Pinned Endoleap client: %s\n' "$HEADLESS_CLIENT_REVISION" - name: Verify schema migration and real headless HTTP client in an isolated database run: HEADLESS_CLIENT_SOURCE="$PWD/.headless-client" bash deploy/check-schema.sh - name: Smoke test HTTP routes env: PUBLIC_ORIGIN: https://api.example.com DATABASE_URL: postgres://foundry:fixture@127.0.0.1:5432/foundry FOUNDRY_RESEARCH_DATABASE_URL: '' GOOGLE_CLIENT_ID: fixture GOOGLE_CLIENT_SECRET: fixture FOUNDRY_PROJECTS: '{"notes":"http://localhost:3000/auth/callback"}' PORT: '18080' run: | set -eu ./bin/foundry & server_pid=$! trap 'kill "$server_pid" 2>/dev/null || true' EXIT curl --silent --show-error --fail --retry 5 --retry-connrefused http://127.0.0.1:18080/healthz status=$(curl --silent --show-error -o /dev/null -w '%{http_code}' http://127.0.0.1:18080/projects/notes/auth/me) test "$status" = 401