From 3d0c84fa6e6e8f111cc7a6cc36668b927c3879cc Mon Sep 17 00:00:00 2001 From: Rodin Date: Sat, 16 May 2026 01:39:21 +0000 Subject: [PATCH] ci: correct triggers and add self-review gate with TTL; gate review job --- .gitea/workflows/ci.yml | 194 +++++++++++++++++++--------------------- 1 file changed, 91 insertions(+), 103 deletions(-) diff --git a/.gitea/workflows/ci.yml b/.gitea/workflows/ci.yml index f80fe76..254d829 100644 --- a/.gitea/workflows/ci.yml +++ b/.gitea/workflows/ci.yml @@ -1,71 +1,26 @@ name: CI -true: + +on: push: - branches: - - main + branches: [main] pull_request: - types: - - opened - - synchronize + types: [opened, synchronize] + +env: + SELF_REVIEW_TTL_MIN: '45' + jobs: test: runs-on: ubuntu-24.04 steps: - - uses: actions/checkout@v4 - - uses: actions/setup-go@v5 - with: - go-version: '1.26' - - run: go test ./... - - run: go vet ./... - - run: go build -o review-bot ./cmd/review-bot - review: - runs-on: ubuntu-24.04 - if: github.event_name == 'pull_request' && needs.review-gate.outputs.allow_review - == 'true' - needs: - - test - - review-gate - strategy: - matrix: - include: - - name: sonnet - token_secret: SONNET_REVIEW_TOKEN - model: anthropic--claude-4.6-sonnet - - name: gpt - token_secret: GPT_REVIEW_TOKEN - model: gpt-5 - - name: security - token_secret: SECURITY_REVIEW_TOKEN - model: gpt-5 - patterns_repo: rodin/security-patterns - patterns_files: . - system_prompt_file: SECURITY_REVIEW.md - steps: - - uses: actions/checkout@v4 - - uses: actions/setup-go@v5 - with: - go-version: '1.26' - - run: go build -o review-bot ./cmd/review-bot - - name: Run ${{ matrix.name }} review - env: - VCS_URL: ${{ github.server_url }} - GITEA_REPO: ${{ github.repository }} - PR_NUMBER: ${{ github.event.pull_request.number }} - REVIEWER_TOKEN: ${{ secrets[matrix.token_secret] }} - REVIEWER_NAME: ${{ matrix.name }} - LLM_PROVIDER: aicore - LLM_MODEL: ${{ matrix.model }} - AICORE_CLIENT_ID: ${{ secrets.AICORE_CLIENT_ID }} - AICORE_CLIENT_SECRET: ${{ secrets.AICORE_CLIENT_SECRET }} - AICORE_AUTH_URL: ${{ secrets.AICORE_AUTH_URL }} - AICORE_API_URL: ${{ secrets.AICORE_API_URL }} - AICORE_RESOURCE_GROUP: ${{ secrets.AICORE_RESOURCE_GROUP }} - CONVENTIONS_FILE: CONVENTIONS.md - PATTERNS_REPO: ${{ matrix.patterns_repo || 'rodin/go-patterns' }} - PATTERNS_FILES: ${{ matrix.patterns_files || 'README.md,patterns/' }} - LLM_TIMEOUT: '600' - SYSTEM_PROMPT_FILE: ${{ matrix.system_prompt_file }} - run: ./review-bot + - uses: actions/checkout@v4 + - uses: actions/setup-go@v5 + with: + go-version: '1.26' + - run: go test ./... + - run: go vet ./... + - run: go build -o review-bot ./cmd/review-bot + review-gate: runs-on: ubuntu-24.04 if: github.event_name == 'pull_request' @@ -73,50 +28,83 @@ jobs: allow_review: ${{ steps.gate.outputs.allow_review }} reason: ${{ steps.gate.outputs.reason }} steps: - - name: Check self-review gate - id: gate - env: - GITEA_TOKEN: ${{ secrets.RODIN_TOKEN }} - run: 'REPO=${{ github.repository }} + - name: Check self-review gate + id: gate + env: + GITEA_TOKEN: ${{ secrets.RODIN_TOKEN }} + run: | + set -e + REPO=${{ github.repository }} + PR=${{ github.event.pull_request.number }} + SHA=${{ github.event.pull_request.head.sha }} + TTL_MIN=${SELF_REVIEW_TTL_MIN} + API="${{ github.server_url }}/api/v1" - PR=${{ github.event.pull_request.number }} + PR_JSON=$(curl -sS -H "Authorization: token $GITEA_TOKEN" "$API/repos/$REPO/pulls/$PR") + UPDATED_AT=$(echo "$PR_JSON" | jq -r .updated_at) + NOW=$(date -u +%s) + PR_TS=$(date -u -d "$UPDATED_AT" +%s) + AGE_MIN=$(( (NOW - PR_TS) / 60 )) - SHA=${{ github.event.pull_request.head.sha }} + COMMENTS=$(curl -sS -H "Authorization: token $GITEA_TOKEN" "$API/repos/$REPO/issues/$PR/comments?limit=200") + HAS_SR=$(echo "$COMMENTS" | jq -r --arg sha "$SHA" '[.[] | select(.user.login=="rodin") | select(.body|contains("Self-review against "+$sha)) | select(.body|test("(?im)^###\\s+Doc consistency\\b"))] | length') - TTL_MIN=${SELF_REVIEW_TTL_MIN} + if [ "$HAS_SR" -gt 0 ]; then + ALLOW=true + REASON=self-review + elif [ "$AGE_MIN" -ge "$TTL_MIN" ]; then + ALLOW=true + REASON=ttl + else + ALLOW=false + REASON=missing + fi - API="${{ github.server_url }}/api/v1" + echo "allow_review=$ALLOW" >> $GITHUB_OUTPUT + echo "reason=$REASON" >> $GITHUB_OUTPUT - PR_JSON=$(curl -sS -H "Authorization: token $GITEA_TOKEN" "$API/repos/$REPO/pulls/$PR") - - UPDATED_AT=$(echo "$PR_JSON" | jq -r .updated_at) - - NOW=$(date -u +%s) - - PR_TS=$(date -u -d "$UPDATED_AT" +%s) - - AGE_MIN=$(( (NOW - PR_TS) / 60 )) - - COMMENTS=$(curl -sS -H "Authorization: token $GITEA_TOKEN" "$API/repos/$REPO/issues/$PR/comments?limit=200") - - HAS_SR=$(echo "$COMMENTS" | jq -r --arg sha "$SHA" "[.[] | select(.user.login=="rodin") - | select(.body|contains("Self-review against "+\$sha)) | select(.body|test("(?im)^### - \\s+Doc consistency\\b"))] | length") - - if [ "$HAS_SR" -gt 0 ]; then ALLOW=true; REASON=self-review; elif [ "$AGE_MIN" - -ge "$TTL_MIN" ]; then ALLOW=true; REASON=ttl; else ALLOW=false; REASON=missing; - fi - - echo "allow_review=$ALLOW" >> $GITHUB_OUTPUT - - echo "reason=$REASON" >> $GITHUB_OUTPUT' -env: - SELF_REVIEW_TTL_MIN: '45' -'on': - pull_request: - types: - - opened - - synchronize - push: - branches: - - main + review: + runs-on: ubuntu-24.04 + if: github.event_name == 'pull_request' && needs.review-gate.outputs.allow_review == 'true' + needs: [test, review-gate] + strategy: + matrix: + include: + - name: sonnet + token_secret: SONNET_REVIEW_TOKEN + model: anthropic--claude-4.6-sonnet + - name: gpt + token_secret: GPT_REVIEW_TOKEN + model: gpt-5 + - name: security + token_secret: SECURITY_REVIEW_TOKEN + model: gpt-5 + patterns_repo: rodin/security-patterns + patterns_files: '.' + system_prompt_file: SECURITY_REVIEW.md + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-go@v5 + with: + go-version: '1.26' + - run: go build -o review-bot ./cmd/review-bot + - name: Run ${{ matrix.name }} review + env: + VCS_URL: ${{ github.server_url }} + GITEA_REPO: ${{ github.repository }} + PR_NUMBER: ${{ github.event.pull_request.number }} + REVIEWER_TOKEN: ${{ secrets[matrix.token_secret] }} + REVIEWER_NAME: ${{ matrix.name }} + LLM_PROVIDER: aicore + LLM_MODEL: ${{ matrix.model }} + AICORE_CLIENT_ID: ${{ secrets.AICORE_CLIENT_ID }} + AICORE_CLIENT_SECRET: ${{ secrets.AICORE_CLIENT_SECRET }} + AICORE_AUTH_URL: ${{ secrets.AICORE_AUTH_URL }} + AICORE_API_URL: ${{ secrets.AICORE_API_URL }} + AICORE_RESOURCE_GROUP: ${{ secrets.AICORE_RESOURCE_GROUP }} + CONVENTIONS_FILE: 'CONVENTIONS.md' + PATTERNS_REPO: ${{ matrix.patterns_repo || 'rodin/go-patterns' }} + PATTERNS_FILES: ${{ matrix.patterns_files || 'README.md,patterns/' }} + LLM_TIMEOUT: '600' + SYSTEM_PROMPT_FILE: ${{ matrix.system_prompt_file }} + run: ./review-bot