PR Discovery #38
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # .github/workflows/pr-discovery.yml | |
| name: PR Discovery | |
| on: | |
| schedule: | |
| - cron: "17 4 * * *" | |
| workflow_dispatch: | |
| concurrency: | |
| group: pr-discovery | |
| cancel-in-progress: false | |
| permissions: | |
| contents: read | |
| pull-requests: read | |
| env: | |
| IF_REPO_ROOT: ${{ github.workspace }} | |
| jobs: | |
| gate: | |
| name: Autonomy gate | |
| uses: ./.github/workflows/autonomy-check.yml | |
| with: | |
| requested_action: discovery-scan | |
| discover: | |
| name: Discover upstream PRs | |
| needs: gate | |
| if: needs.gate.outputs.proceed == 'true' | |
| runs-on: ubuntu-latest | |
| environment: bot-credentials | |
| outputs: | |
| batch_count: ${{ steps.run.outputs.batch_count }} | |
| steps: | |
| - name: Generate GH App token | |
| id: app-token | |
| uses: tibdex/github-app-token@v2 | |
| with: | |
| app_id: ${{ secrets.GH_APP_ID }} | |
| private_key: ${{ secrets.GH_APP_PRIVATE_KEY }} | |
| - uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| token: ${{ steps.app-token.outputs.token }} | |
| - name: Set up Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: "3.12" | |
| # NOTE: The actual Claude action wiring (anthropics/claude-code-action) is implemented | |
| # in a separate bead. This step is a placeholder that calls the action in the same form | |
| # as the rest of the pipeline; CI will skip/fail gracefully until the action is wired. | |
| - name: Load pr-discovery prompt | |
| id: load-prompt | |
| shell: bash | |
| run: | | |
| { | |
| echo 'prompt<<__EOF_PROMPT__' | |
| cat .if-fork/prompts/pr-discovery.md | |
| echo | |
| echo '__EOF_PROMPT__' | |
| } >> "$GITHUB_OUTPUT" | |
| - name: Run discovery (Claude Haiku) | |
| id: run | |
| uses: anthropics/claude-code-action@v1 | |
| with: | |
| anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }} | |
| prompt: ${{ steps.load-prompt.outputs.prompt }} | |
| claude_args: >- | |
| --max-turns 8 | |
| --model claude-haiku-4-5 | |
| --allowedTools Bash,Read,Grep,mcp__github__list_pull_requests,mcp__github__search_pull_requests,mcp__github__issue_write | |
| --disallowedTools Edit,Write | |
| github_token: ${{ steps.app-token.outputs.token }} | |
| env: | |
| CONFIG_PATH: .if-fork/config.yaml | |
| LEDGER_PATH: .if-fork/patch-ledger.jsonl | |
| STATE_PATH: .if-fork/patch-state.json | |
| BATCH_ISSUE_PATH: /tmp/batch-issue.md | |
| - name: Upload discovered PRs artifact | |
| if: always() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: discovered-prs-${{ github.run_id }} | |
| path: /tmp/discovered-batch.json | |
| retention-days: 30 | |
| if-no-files-found: ignore | |
| record: | |
| name: Record discovered events in ledger | |
| needs: [gate, discover] | |
| if: needs.discover.result == 'success' | |
| runs-on: ubuntu-latest | |
| environment: bot-credentials | |
| steps: | |
| - name: Generate GH App token | |
| id: app-token | |
| uses: tibdex/github-app-token@v2 | |
| with: | |
| app_id: ${{ secrets.GH_APP_ID }} | |
| private_key: ${{ secrets.GH_APP_PRIVATE_KEY }} | |
| - uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| token: ${{ steps.app-token.outputs.token }} | |
| - name: Set up Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: "3.12" | |
| - name: Download discovered PRs artifact | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: discovered-prs-${{ github.run_id }} | |
| path: /tmp/ | |
| continue-on-error: true | |
| - name: Import bot GPG key | |
| uses: ./.github/actions/import-bot-gpg | |
| with: | |
| gpg-private-key: ${{ secrets.GH_BOT_GPG_KEY }} | |
| gpg-key-id: ${{ secrets.GH_BOT_GPG_KEY_ID }} | |
| gpg-fingerprint: ${{ secrets.GH_BOT_GPG_FINGERPRINT }} | |
| - name: Emit ledger events for discovered PRs | |
| run: | | |
| if [ -f /tmp/discovered-batch.json ]; then | |
| python tools/ledger-event.py \ | |
| --event discovered \ | |
| --pr-number 0 \ | |
| --head-sha "${{ github.sha }}" \ | |
| --actor pr-discovery \ | |
| --details-json "{\"batch_date\": \"$(date -u +%Y-%m-%d)\", \"run_url\": \"${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}\"}" \ | |
| --push | |
| else | |
| echo "::notice::No discovered-batch.json artifact; nothing to record." | |
| fi | |
| env: | |
| GIT_AUTHOR_NAME: "Claude (Initial Force WPF Bot)" | |
| GIT_AUTHOR_EMAIL: "wpf-bot@initialforce.com" | |
| GH_TOKEN: ${{ steps.app-token.outputs.token }} | |
| - name: Trigger review for discovered PRs if new batch found | |
| if: fromJSON(needs.discover.outputs.batch_count || '0') > 0 | |
| run: | | |
| gh api repos/${{ github.repository }}/dispatches \ | |
| --field event_type=pr-discovered \ | |
| --field "client_payload[batch_date]=$(date -u +%Y-%m-%d)" | |
| env: | |
| GH_TOKEN: ${{ steps.app-token.outputs.token }} |