Dated TODO sweep #2
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
| name: Dated TODO sweep | |
| on: | |
| schedule: | |
| - cron: "23 6 * * 1" | |
| workflow_dispatch: | |
| inputs: | |
| dry_run: | |
| description: Log the fresh report without creating or updating the tracking issue. | |
| required: false | |
| default: false | |
| type: boolean | |
| permissions: | |
| contents: read | |
| concurrency: | |
| group: dated-todo-sweep | |
| cancel-in-progress: false | |
| env: | |
| FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: "true" | |
| jobs: | |
| analyze: | |
| # Manual runs may select a ref; secrets are available only when that ref is | |
| # the trusted default branch. Scheduled runs already target that branch. | |
| if: github.event_name != 'workflow_dispatch' || github.ref == format('refs/heads/{0}', github.event.repository.default_branch) | |
| outputs: | |
| sweep-date: ${{ steps.sweep-date.outputs.date }} | |
| runs-on: ubuntu-24.04 | |
| timeout-minutes: 20 | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 | |
| with: | |
| ref: ${{ github.sha }} | |
| persist-credentials: false | |
| - name: Setup Node environment | |
| uses: ./.github/actions/setup-node-env | |
| with: | |
| node-version: "24.x" | |
| install-bun: "false" | |
| - name: Collect dated TODO candidates | |
| run: node scripts/dated-todo-scan.mjs | |
| - name: Capture sweep date | |
| id: sweep-date | |
| run: echo "date=$(date -u +%F)" >> "$GITHUB_OUTPUT" | |
| - name: Run Codex dated TODO sweep | |
| uses: openai/codex-action@52fe01ec70a42f454c9d2ebd47598f9fd6893d56 | |
| env: | |
| DATED_TODO_SWEEP_DATE: ${{ steps.sweep-date.outputs.date }} | |
| with: | |
| openai-api-key: ${{ secrets.OPENAI_API_KEY }} | |
| prompt-file: .github/codex/prompts/dated-todo-sweep.md | |
| model: ${{ vars.OPENCLAW_CI_OPENAI_MODEL_BARE }} | |
| effort: medium | |
| sandbox: workspace-write | |
| safety-strategy: drop-sudo | |
| # Only the report crosses into the privileged job. The app token is minted | |
| # on a fresh runner and checkout, never beside Codex or its child processes. | |
| - name: Upload dated TODO report | |
| uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 | |
| with: | |
| name: dated-todo-report | |
| path: .artifacts/dated-todo-report.md | |
| if-no-files-found: error | |
| include-hidden-files: true | |
| retention-days: 7 | |
| upsert: | |
| if: github.event_name != 'workflow_dispatch' || github.ref == format('refs/heads/{0}', github.event.repository.default_branch) | |
| needs: analyze | |
| runs-on: ubuntu-24.04 | |
| timeout-minutes: 10 | |
| steps: | |
| - name: Checkout trusted workflow code | |
| uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 | |
| with: | |
| ref: ${{ github.sha }} | |
| persist-credentials: false | |
| - name: Download dated TODO report | |
| uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8 | |
| with: | |
| name: dated-todo-report | |
| path: .artifacts | |
| - name: Validate dated TODO report | |
| env: | |
| DATED_TODO_SWEEP_DATE: ${{ needs.analyze.outputs.sweep-date }} | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| node --input-type=module <<'NODE' | |
| import fs from "node:fs"; | |
| import { pathToFileURL } from "node:url"; | |
| const reportPath = ".artifacts/dated-todo-report.md"; | |
| const report = fs.readFileSync(reportPath, "utf8"); | |
| const moduleUrl = pathToFileURL( | |
| `${process.env.GITHUB_WORKSPACE}/scripts/github/dated-todo-upsert.mjs`, | |
| ); | |
| const { validateDatedTodoReport } = await import(moduleUrl.href); | |
| validateDatedTodoReport(report, { | |
| expectedDate: process.env.DATED_TODO_SWEEP_DATE, | |
| repoRoot: process.env.GITHUB_WORKSPACE, | |
| }); | |
| NODE | |
| - name: Log dry-run report | |
| if: github.event_name == 'workflow_dispatch' && inputs.dry_run | |
| run: cat .artifacts/dated-todo-report.md | |
| # No permission-* subset here: requesting a permission the installation | |
| # does not grant fails token minting outright. No inputs uses the app's | |
| # full granted set, matching the proven Barnacle fallback workflow. | |
| - name: Create Barnacle app token | |
| if: github.event_name != 'workflow_dispatch' || !inputs.dry_run | |
| uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # zizmor: ignore[github-app] v3 | |
| id: app-token | |
| continue-on-error: true | |
| with: | |
| app-id: "2729701" | |
| private-key: ${{ secrets.GH_APP_PRIVATE_KEY }} | |
| - name: Create fallback Barnacle app token | |
| uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # zizmor: ignore[github-app] v3 | |
| id: app-token-fallback | |
| if: (github.event_name != 'workflow_dispatch' || !inputs.dry_run) && steps.app-token.outcome == 'failure' | |
| with: | |
| app-id: "2971289" | |
| private-key: ${{ secrets.GH_APP_PRIVATE_KEY_FALLBACK }} | |
| - name: Upsert dated TODO tracking issue | |
| if: github.event_name != 'workflow_dispatch' || !inputs.dry_run | |
| uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9 | |
| with: | |
| github-token: ${{ steps.app-token.outputs.token || steps.app-token-fallback.outputs.token }} | |
| script: | | |
| const { pathToFileURL } = require("node:url"); | |
| const moduleUrl = pathToFileURL( | |
| `${process.env.GITHUB_WORKSPACE}/scripts/github/dated-todo-upsert.mjs`, | |
| ); | |
| const { runDatedTodoUpsert } = await import(moduleUrl.href); | |
| await runDatedTodoUpsert({ | |
| github, | |
| context, | |
| core, | |
| }); |