Tantangan Skala pada Evaluasi Submission PR

Menangani ratusan pull request (PR) dalam kompetisi koding atau hackathon terbuka sering memicu bottleneck pada tahap review awal. Penguji manusia menghabiskan waktu berharga untuk memeriksa kelengkapan administratif: apakah checklist deskripsi terisi, apakah direktori artifact diletakkan di path yang tepat, dan apakah kode submission memenuhi format dasar. Masalah ini dapat diselesaikan dengan memindahkan validasi tahap pertama ke pipeline otomatis deterministik sebelum masuk ke review kualitatif.

Arsitektur Triage Deterministik dan Evaluasi Berbantu AI

Pipeline triage yang baik memisahkan aturan baku (rule-based) dari evaluasi heuristik berbasis LLM. Aturan kaku seperti keberadaan file submission, checklist markdown PR, dan format JSON/YAML wajib diperiksa via shell script atau GitHub CLI (gh). Evaluasi berbantu Copilot CLI atau model headless hanya digunakan untuk verifikasi semantik, seperti validasi relevansi deskripsi terhadap tugas challenge.

Pemisahan ini menjaga konsumsi API token tetap hemat, mencegah limitasi rate-limit GitHub API, dan memastikan submission invalid ditolak seawal mungkin tanpa eksekusi AI yang mahal.

Workflow GitHub Actions untuk Triage Otomatis

Contoh implementasi workflow berikut berjalan pada event pull_request_target dengan scope terbatas untuk keamanan token, memvalidasi checklist via script, dan mengeksekusi Copilot CLI secara headless:

name: PR Challenge Triage

on:
  pull_request_target:
    types: [opened, synchronize, reopened]
    paths:
      - 'submissions/**'

permissions:
  pull-requests: write
  contents: read

jobs:
  triage:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout Code
        uses: actions/checkout@v4
        with:
          ref: ${{ github.event.pull_request.head.sha }}

      - name: Validate PR Checklist & Artifacts
        id: validate_pr
        env:
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          PR_BODY: ${{ github.event.pull_request.body }}
          PR_NUMBER: ${{ github.event.pull_request.number }}
        run: |
          # 1. Cek Checklist Markdown
          if echo "$PR_BODY" | grep -q '\[ \]'; then
            echo "status=incomplete_checklist" >> "$GITHUB_OUTPUT"
            gh pr comment "$PR_NUMBER" --body "Error: Harap centang semua checklist pada deskripsi PR."
            exit 0
          fi

          # 2. Cek Direktori Submisi
          SUBMISSION_DIR="submissions/${{ github.event.pull_request.user.login }}"
          if [ ! -d "$SUBMISSION_DIR" ]; then
            echo "status=invalid_path" >> "$GITHUB_OUTPUT"
            gh pr comment "$PR_NUMBER" --body "Error: Submisi harus berada di dalam direktori: $SUBMISSION_DIR"
            exit 0
          fi

          echo "status=passed" >> "$GITHUB_OUTPUT"

      - name: Run Copilot CLI Semantic Triage
        if: steps.validate_pr.outputs.status == 'passed'
        env:
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          COPILOT_TOKEN: ${{ secrets.COPILOT_API_TOKEN }}
        run: |
          # Simulasi eksekusi headless review menggunakan gh copilot / AI inference
          SUMMARY=$(gh pr diff ${{ github.event.pull_request.number }} | head -n 100)
          
          RESULT=$(echo "$SUMMARY" | gh copilot explain - 2>/dev/null || echo "Automated pass")
          echo "Copilot analysis ready." >> $GITHUB_STEP_SUMMARY

      - name: Idempotent PR Labeling
        if: always()
        env:
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          PR_NUMBER: ${{ github.event.pull_request.number }}
          STATUS: ${{ steps.validate_pr.outputs.status }}
        run: |
          # Hapus label status lama sebelum assign label baru agar idempotensi terjaga
          gh pr edit "$PR_NUMBER" --remove-label "status:passed,status:rejected,status:action-required" 2>/dev/null || true
          
          if [ "$STATUS" = "passed" ]; then
            gh pr edit "$PR_NUMBER" --add-label "status:passed"
          else
            gh pr edit "$PR_NUMBER" --add-label "status:action-required"
          fi

Idempotensi dan Penanganan Rate Limit

Idempotensi penting agar pipeline dapat dijalankan berulang kali (setiap push commit baru) tanpa menyebabkan duplikasi komentar bot atau penumpukan label yang bertentangan. Selalu gunakan pola hapus-dan-tambahkan (remove-label disusul add-label) untuk state label PR.

Untuk mitigasi limitasi token:

  • Gunakan GITHUB_TOKEN bawaan runner untuk interaksi GitHub CLI reguler (labeling, commenting) yang memiliki kuota 1,000 request per jam per repositori (atau hingga 15,000 untuk enterprise).
  • Batasi input context LLM/Copilot hanya pada git diff yang relevan (misal dibatasi 100-200 baris diff) alih-alih mengirim seluruh codebase submission.

Strategi Mitigasi False-Positive

Model AI dan regex shell memiliki potensi menandai submission valid sebagai gagal (false-positive). Untuk mencegah eliminasi yang tidak adil bagi peserta:

  1. Label Non-Blocking: Jangan langsung melakukan penutupan PR (gh pr close) otomatis. Gunakan label status netral seperti status:action-required atau needs-maintainer-review.
  2. Bypass Flag: Sediakan escape hatch via label maintainer (misal: override-triage) yang dihormati oleh pipeline untuk melewati validasi otomatis jika peserta menghadapi edge-case yang valid.
  3. Log Terperinci: Tulis kegagalan validasi secara spesifik ke dalam $GITHUB_STEP_SUMMARY dan PR comment agar peserta memahami koreksi yang dibutuhkan tanpa perlu membuka ticket bantuan manual.