Some checks failed
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 14s
CI / Detect changes (pull_request) Successful in 40s
E2E API Smoke Test / detect-changes (pull_request) Successful in 46s
Lint curl status-code capture / Scan workflows for curl status-capture pollution (pull_request) Successful in 13s
E2E Staging Canvas (Playwright) / detect-changes (pull_request) Successful in 45s
Handlers Postgres Integration / detect-changes (pull_request) Successful in 37s
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 16s
qa-review / approved (pull_request) Failing after 19s
CI / Platform (Go) (pull_request) Successful in 8s
Runtime PR-Built Compatibility / detect-changes (pull_request) Successful in 39s
security-review / approved (pull_request) Failing after 17s
gate-check-v3 / gate-check (pull_request) Successful in 28s
CI / Shellcheck (E2E scripts) (pull_request) Successful in 6s
CI / Canvas (Next.js) (pull_request) Successful in 8s
sop-tier-check / tier-check (pull_request) Successful in 20s
CI / Python Lint & Test (pull_request) Successful in 8s
CI / Canvas Deploy Reminder (pull_request) Has been skipped
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Successful in 8s
E2E API Smoke Test / E2E API Smoke Test (pull_request) Successful in 10s
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Successful in 6s
Runtime PR-Built Compatibility / PR-built wheel + import smoke (pull_request) Successful in 6s
CI / all-required (pull_request) Successful in 3s
audit-force-merge / audit (pull_request) Successful in 19s
Adds DEFAULT_TIMEOUT=15 to gate_check.py and passes it to all urlopen()
calls (api_get, comment POST, comment PATCH).
Adds socket.setdefaulttimeout(15) to the inline Python in the workflow's
cron step, catching the PR-polling loop too.
Defence-in-depth: the real fix is provisioning SOP_TIER_CHECK_TOKEN
in Gitea; this caps worst-case wall-clock at ~15 s per call when the
token is missing or Gitea is unreachable.
Fixes issue #603. Note: PR #603 (da1487ad) has the same changes but
is missing `import socket` in the inline Python — that version would
NameError at runtime. This branch carries the complete fix.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
98 lines
4.1 KiB
YAML
98 lines
4.1 KiB
YAML
# gate-check-v3 — automated PR gate detector
|
|
#
|
|
# Runs on every open PR (push/synchronize) and hourly via cron.
|
|
# Posts a structured [gate-check-v3] STATUS: comment on the PR.
|
|
#
|
|
# Inputs:
|
|
# PR_NUMBER — set via ${{ github.event.pull_request.number }} from the trigger
|
|
# POST_COMMENT — "true" to post/update comment on PR
|
|
#
|
|
# Gating logic (MVP signals 1,2,3,6):
|
|
# 1. Author-aware agent-tag comment scan
|
|
# 2. REQUEST_CHANGES reviews state machine
|
|
# 3. Staleness detection (SOP-12: review.commit_id != PR.head_sha + >1 working day)
|
|
# 6. CI required-checks awareness
|
|
#
|
|
# Exit code: 0=CLEAR, 1=BLOCKED, 2=ERROR
|
|
|
|
name: gate-check-v3
|
|
|
|
on:
|
|
pull_request_target:
|
|
types: [opened, edited, synchronize, reopened]
|
|
schedule:
|
|
# Hourly: refresh all open PRs
|
|
- cron: '8 * * * *'
|
|
# NOTE: `workflow_dispatch.inputs` block intentionally omitted.
|
|
# Gitea 1.22.6 parser rejects `workflow_dispatch.inputs.X` with
|
|
# "unknown on type" — it mis-treats the inputs sub-keys as top-level
|
|
# `on:` event types. Dropping the inputs block restores parsing.
|
|
# Manual dispatch from the Gitea UI works without the inputs schema
|
|
# (github.event.inputs.X returns empty); the script falls back to
|
|
# iterating all open PRs when PR_NUMBER is empty.
|
|
workflow_dispatch:
|
|
|
|
env:
|
|
GITHUB_SERVER_URL: https://git.moleculesai.app
|
|
|
|
jobs:
|
|
gate-check:
|
|
runs-on: ubuntu-latest
|
|
continue-on-error: true # Never block on our own detector failing
|
|
steps:
|
|
- name: Check out BASE ref (never PR-head under pull_request_target)
|
|
# pull_request_target runs with repo secrets-context, so checking out
|
|
# the PR HEAD would execute PR-branch gate_check.py with secrets.
|
|
# Fix: always load gate_check.py from the trusted base/default ref.
|
|
# Bug-1 (self-loop exclusion) + Bug-3 (403→exit0) from #547 are
|
|
# kept; only this checkout-ref regresses to pre-#547 behavior.
|
|
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
|
with:
|
|
ref: ${{ github.event.pull_request.base.sha || github.ref_name }}
|
|
|
|
- name: Run gate-check-v3 (single PR mode)
|
|
if: github.event_name == 'pull_request_target' || github.event.inputs.pr_number != ''
|
|
env:
|
|
GITEA_TOKEN: ${{ secrets.SOP_TIER_CHECK_TOKEN || secrets.GITHUB_TOKEN }}
|
|
PR_NUMBER: ${{ github.event.pull_request.number || github.event.inputs.pr_number }}
|
|
POST_COMMENT: ${{ github.event.inputs.post_comment || 'true' }}
|
|
run: |
|
|
set -euo pipefail
|
|
python3 tools/gate-check-v3/gate_check.py \
|
|
--repo "${{ github.repository }}" \
|
|
--pr "$PR_NUMBER" \
|
|
$([ "$POST_COMMENT" = "true" ] && echo "--post-comment")
|
|
echo "verdict=$?" >> "$GITHUB_OUTPUT"
|
|
|
|
- name: Run gate-check-v3 (all open PRs — cron mode)
|
|
if: github.event_name == 'schedule'
|
|
env:
|
|
GITEA_TOKEN: ${{ secrets.SOP_TIER_CHECK_TOKEN || secrets.GITHUB_TOKEN }}
|
|
run: |
|
|
set -euo pipefail
|
|
# Fetch all open PRs and run gate-check on each
|
|
# socket.setdefaulttimeout(15): defence-in-depth for missing SOP_TIER_CHECK_TOKEN.
|
|
# gate_check.py uses timeout=15 on every urlopen call; this catches the
|
|
# inline Python polling loop too (issue #603).
|
|
pr_numbers=$(python3 -c "
|
|
import socket, urllib.request, json, os
|
|
socket.setdefaulttimeout(15)
|
|
token = os.environ['GITEA_TOKEN']
|
|
req = urllib.request.Request(
|
|
'https://git.moleculesai.app/api/v1/repos/${{ github.repository }}/pulls?state=open&limit=100',
|
|
headers={'Authorization': f'token {token}', 'Accept': 'application/json'}
|
|
)
|
|
with urllib.request.urlopen(req) as r:
|
|
prs = json.loads(r.read())
|
|
for pr in prs:
|
|
print(pr['number'])
|
|
")
|
|
for pr in $pr_numbers; do
|
|
echo "Checking PR #$pr..."
|
|
python3 tools/gate-check-v3/gate_check.py \
|
|
--repo "${{ github.repository }}" \
|
|
--pr "$pr" \
|
|
--post-comment \
|
|
|| true
|
|
done
|