Repository navigation
feat(cursor-review): accept pull_request_target, pin PR checkout refs… #429
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: Test cursor-review scripts | |
| # Runs the Python unit tests for the cursor-review helper scripts, especially | |
| # the stdio MCP output contract used by reviewers and the judge. These scripts | |
| # drive panel consolidation for every consumer repo, so they are cheap to | |
| # guard with a unit run on change. | |
| # Inputs/secrets: none. Triggers: path-filtered pull requests and pushes to main. | |
| # Also runs the .github/cursor-approve/ suite (axis prompts, verdict aggregator | |
| # and the read-only context proxy). | |
| # Caller pattern: none; this is repository-local CI, not a reusable workflow. | |
| # | |
| # cursor-review.yml itself is in the path filter because two suites read it: | |
| # catalog-drift.py reads the model pins OUT of it (BE-4819), and | |
| # test_workflow_job_isolation.py pins the credential split (no job both checks | |
| # out PR code and holds the bot key / pull-requests: write). Both assertions are | |
| # only worth anything if they run when the file they parse changes. | |
| # | |
| # The declared-vs-documented input drift check no longer lives here: it folded | |
| # into the table-driven harness at | |
| # .github/workflow-pins/tests/test_inputs_docs_drift.py, which reads BOTH | |
| # docs/callers/cursor-review.md and .github/cursor-review/README.md. Both paths | |
| # are in test-workflow-pins.yml's filters, and a docs-only PR that deletes the | |
| # `blocking` row (the #31 scenario) still fires the alarm, over there. | |
| # | |
| # docs/callers/cursor-approve.md and docs/callers/cursor-review.md ARE listed | |
| # below anyway, because a suite here reads them too: test_caller_doc_pattern.py | |
| # pins the `if:` guards on the cursor-approve caller snippet and on | |
| # cursor-review's `next:` approve_gate example. A copied caller is only as good | |
| # as the snippet, and dropping `!cancelled()` from it silently withholds every | |
| # approval (see that file's docstring). | |
| on: | |
| pull_request: | |
| paths: | |
| - '.github/cursor-review/**' | |
| - '.github/cursor-approve/**' | |
| - '.github/workflows/cursor-review.yml' | |
| - '.github/workflows/cursor-review-catalog-drift.yml' | |
| # The cursor-approve suite asserts properties of these workflows too | |
| # (secret isolation, the guard byte-copy, the CLI pin). | |
| - '.github/workflows/cursor-approve.yml' | |
| - '.github/workflows/cursor-axis-base.yml' | |
| - '.github/workflows/axis-*.yml' | |
| # test_caller_doc_pattern.py reads the caller snippets out of these | |
| # pages and pins their `if:` guards; the regression it guards is a | |
| # docs-only edit — dropping `!cancelled()` from a snippet a caller copies. | |
| - 'docs/callers/cursor-approve.md' | |
| - 'docs/callers/cursor-review.md' | |
| - '.github/workflows/test-cursor-review-scripts.yml' | |
| push: | |
| branches: [main] | |
| paths: | |
| - '.github/cursor-review/**' | |
| - '.github/cursor-approve/**' | |
| - '.github/workflows/cursor-review.yml' | |
| - '.github/workflows/cursor-review-catalog-drift.yml' | |
| # The cursor-approve suite asserts properties of these workflows too | |
| # (secret isolation, the guard byte-copy, the CLI pin). | |
| - '.github/workflows/cursor-approve.yml' | |
| - '.github/workflows/cursor-axis-base.yml' | |
| - '.github/workflows/axis-*.yml' | |
| # test_caller_doc_pattern.py reads the caller snippets out of these | |
| # pages and pins their `if:` guards; the regression it guards is a | |
| # docs-only edit — dropping `!cancelled()` from a snippet a caller copies. | |
| - 'docs/callers/cursor-approve.md' | |
| - 'docs/callers/cursor-review.md' | |
| - '.github/workflows/test-cursor-review-scripts.yml' | |
| permissions: | |
| contents: read | |
| jobs: | |
| test: | |
| name: unittest + shellcheck | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| with: | |
| persist-credentials: false | |
| - name: ShellCheck the cursor-review shell scripts | |
| # These run inside the review jobs with no unit tests behind them, so | |
| # shellcheck is the only automated guard on install-cursor-cli.sh (the | |
| # sha256-pinned CLI installer) and slack-notify.sh. | |
| run: shellcheck -x .github/cursor-review/install-cursor-cli.sh .github/cursor-review/slack-notify.sh | |
| - name: Set up Python | |
| uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 | |
| with: | |
| python-version: '3.12' | |
| - name: Run cursor-review script tests | |
| run: python3 -m unittest discover -s .github/cursor-review/tests -p 'test_*.py' -v | |
| - name: Run cursor-approve script tests | |
| # The axis prompts and verdict aggregator behind cursor-approve, plus | |
| # context-proxy.py, the read-only Linear/Notion/Slack MCP proxy the axes | |
| # query (every network call in its suite is mocked). That workflow's | |
| # decide job reuses cursor-review's auto-approve.py, so the suites share | |
| # this job. | |
| run: python3 -m unittest discover -s .github/cursor-approve/tests -p 'test_*.py' -v |