diff --git a/README.md b/README.md index 2144454..215862d 100644 --- a/README.md +++ b/README.md @@ -177,8 +177,20 @@ npx --yes github:AgentsKit-io/code-review-cli --provider claude-cli \ echo 'const x = a.b' | npx --yes github:AgentsKit-io/code-review-cli \ --provider ollama --model llama3 \ --base-url http://localhost:11434 --stdin --lang ts --sarif out.sarif + +# After fetching the PR base and installing reviewdog, reuse its annotation transport +REPORT_FILE="$(mktemp)" +trap 'rm -f "${REPORT_FILE}"' EXIT +npx --yes github:AgentsKit-io/code-review-cli#3dfd7427640148281454d52846d369e5ddf85b11 \ + --provider openai --model gpt-4o \ + --base "origin/${BASE_REF}" --sarif "${REPORT_FILE}" --no-fail && +reviewdog -f=sarif -name=agentskit-review \ + -reporter=github-pr-review -filter-mode=added -fail-level=error \ + < "${REPORT_FILE}" ``` +The reviewdog recipe needs no custom converter: Code Review emits SARIF 2.1.0 and reviewdog consumes SARIF natively. See the [complete GitHub Actions job](docs/OPERATIONS.md#route-findings-through-reviewdog) for pinned installation, base-branch checkout, permissions, severity mapping, and CI ownership of the failure threshold. + ## CLI reference ### Providers diff --git a/docs/OPERATIONS.md b/docs/OPERATIONS.md index 6f2bd24..afd57df 100644 --- a/docs/OPERATIONS.md +++ b/docs/OPERATIONS.md @@ -75,6 +75,50 @@ Start advisory with a small file budget, measure provider usage, and raise depth SARIF can contain source paths and model-generated explanations. Apply the same retention and access policy as CI logs. +### Route findings through reviewdog + +[reviewdog](https://github.com/reviewdog/reviewdog) accepts SARIF directly, so no AgentsKit-specific reporter or converter is required. This complete pull-request job installs reviewdog, fetches the base history, generates the report in advisory mode, and lets reviewdog own diff filtering, annotations, and the final CI threshold: + +```yaml +name: AgentsKit reviewdog +on: pull_request + +permissions: + contents: read + pull-requests: write + +jobs: + review: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + fetch-depth: 0 + - uses: reviewdog/action-setup@d8edfce3dd5e1ec6978745e801f9c50b5ef80252 # v1.4.0 + with: + reviewdog_version: v0.21.0 + - name: Review changed code + env: + BASE_REF: ${{ github.base_ref }} + LLM_API_KEY: ${{ secrets.LLM_API_KEY }} + REVIEWDOG_GITHUB_API_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + REPORT_FILE="$(mktemp)" + trap 'rm -f "${REPORT_FILE}"' EXIT + npx --yes github:AgentsKit-io/code-review-cli#3dfd7427640148281454d52846d369e5ddf85b11 \ + --provider openai --model gpt-4o --base "origin/${BASE_REF}" \ + --sarif "${REPORT_FILE}" --no-fail && + reviewdog -f=sarif -name=agentskit-review \ + -reporter=github-pr-review -filter-mode=added -fail-level=error \ + < "${REPORT_FILE}" +``` + +The hosted-runner example uses an API provider because local CLI providers require their executable and an existing authenticated session. Replace the provider and model with your approved adapter. The base comes from the pull-request event rather than assuming `main`, and `fetch-depth: 0` makes its remote-tracking ref available to `git diff`. Pass the provider secret through `LLM_API_KEY`, pass the workflow token through `REVIEWDOG_GITHUB_API_TOKEN`, and grant only `contents: read` plus `pull-requests: write`. + +The temporary report and `&&` prevent reviewdog from reading stale output when the producer fails. Keep `--no-fail` on the producer so reviewdog receives the complete report when review succeeds; `-fail-level=error` then makes SARIF `error` findings fail the reviewdog step. AgentsKit maps blocker and high findings to SARIF `error`, medium to `warning`, and nit to `note`. + +The default `added` filter limits inline feedback to changed lines. Choose a broader reviewdog filter deliberately; broader modes can move findings outside the PR diff into checks, annotations, or console output depending on the reporter. Pin both Code Review and reviewdog to reviewed immutable versions in enforcement workflows. + ## Failure scenarios - **Unknown provider or missing model:** validate with `--list-providers`; API/local-server adapters require `--model`. diff --git a/llms-full.txt b/llms-full.txt index 39be2ff..25db74a 100644 --- a/llms-full.txt +++ b/llms-full.txt @@ -195,8 +195,20 @@ npx --yes github:AgentsKit-io/code-review-cli --provider claude-cli \ echo 'const x = a.b' | npx --yes github:AgentsKit-io/code-review-cli \ --provider ollama --model llama3 \ --base-url http://localhost:11434 --stdin --lang ts --sarif out.sarif + +# After fetching the PR base and installing reviewdog, reuse its annotation transport +REPORT_FILE="$(mktemp)" +trap 'rm -f "${REPORT_FILE}"' EXIT +npx --yes github:AgentsKit-io/code-review-cli#3dfd7427640148281454d52846d369e5ddf85b11 \ + --provider openai --model gpt-4o \ + --base "origin/${BASE_REF}" --sarif "${REPORT_FILE}" --no-fail && +reviewdog -f=sarif -name=agentskit-review \ + -reporter=github-pr-review -filter-mode=added -fail-level=error \ + < "${REPORT_FILE}" ``` +The reviewdog recipe needs no custom converter: Code Review emits SARIF 2.1.0 and reviewdog consumes SARIF natively. See the [complete GitHub Actions job](https://github.com/AgentsKit-io/code-review-cli/blob/main/docs/OPERATIONS.md#route-findings-through-reviewdog) for pinned installation, base-branch checkout, permissions, severity mapping, and CI ownership of the failure threshold. + ## CLI reference ### Providers @@ -386,6 +398,50 @@ Start advisory with a small file budget, measure provider usage, and raise depth SARIF can contain source paths and model-generated explanations. Apply the same retention and access policy as CI logs. +### Route findings through reviewdog + +[reviewdog](https://github.com/reviewdog/reviewdog) accepts SARIF directly, so no AgentsKit-specific reporter or converter is required. This complete pull-request job installs reviewdog, fetches the base history, generates the report in advisory mode, and lets reviewdog own diff filtering, annotations, and the final CI threshold: + +```yaml +name: AgentsKit reviewdog +on: pull_request + +permissions: + contents: read + pull-requests: write + +jobs: + review: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + fetch-depth: 0 + - uses: reviewdog/action-setup@d8edfce3dd5e1ec6978745e801f9c50b5ef80252 # v1.4.0 + with: + reviewdog_version: v0.21.0 + - name: Review changed code + env: + BASE_REF: ${{ github.base_ref }} + LLM_API_KEY: ${{ secrets.LLM_API_KEY }} + REVIEWDOG_GITHUB_API_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + REPORT_FILE="$(mktemp)" + trap 'rm -f "${REPORT_FILE}"' EXIT + npx --yes github:AgentsKit-io/code-review-cli#3dfd7427640148281454d52846d369e5ddf85b11 \ + --provider openai --model gpt-4o --base "origin/${BASE_REF}" \ + --sarif "${REPORT_FILE}" --no-fail && + reviewdog -f=sarif -name=agentskit-review \ + -reporter=github-pr-review -filter-mode=added -fail-level=error \ + < "${REPORT_FILE}" +``` + +The hosted-runner example uses an API provider because local CLI providers require their executable and an existing authenticated session. Replace the provider and model with your approved adapter. The base comes from the pull-request event rather than assuming `main`, and `fetch-depth: 0` makes its remote-tracking ref available to `git diff`. Pass the provider secret through `LLM_API_KEY`, pass the workflow token through `REVIEWDOG_GITHUB_API_TOKEN`, and grant only `contents: read` plus `pull-requests: write`. + +The temporary report and `&&` prevent reviewdog from reading stale output when the producer fails. Keep `--no-fail` on the producer so reviewdog receives the complete report when review succeeds; `-fail-level=error` then makes SARIF `error` findings fail the reviewdog step. AgentsKit maps blocker and high findings to SARIF `error`, medium to `warning`, and nit to `note`. + +The default `added` filter limits inline feedback to changed lines. Choose a broader reviewdog filter deliberately; broader modes can move findings outside the PR diff into checks, annotations, or console output depending on the reporter. Pin both Code Review and reviewdog to reviewed immutable versions in enforcement workflows. + ## Failure scenarios - **Unknown provider or missing model:** validate with `--list-providers`; API/local-server adapters require `--model`. diff --git a/readme-standard-v1.json b/readme-standard-v1.json index f6ce50e..1741147 100644 --- a/readme-standard-v1.json +++ b/readme-standard-v1.json @@ -221,7 +221,7 @@ "docs/OPERATIONS.md", "test/cli-smoke.test.mjs" ], - "sourceHash": "sha256:a5e91e2e53b23297102dfd01e9c203028873abce0fd84c17cb92206204f0df49" + "sourceHash": "sha256:4a7ffc75eccbba43eeaa970d9067d4f28d0eed0073f716c5360ecfc67dec45c0" }, "exceptions": [] } diff --git a/test/documentation.test.mjs b/test/documentation.test.mjs index 5853308..ef44664 100644 --- a/test/documentation.test.mjs +++ b/test/documentation.test.mjs @@ -45,6 +45,31 @@ test('pre-commit hook is manual, provider-neutral, and reviews the repository di assert.doesNotMatch(hook, /api[_-]?key/i) }) +test('reviewdog interoperability stays converter-free and explicit about policy ownership', () => { + const readme = read('README.md') + const operations = read('docs/OPERATIONS.md') + const reviewdogSection = operations.split('### Route findings through reviewdog')[1].split('## Failure scenarios')[0] + for (const marker of ['reviewdog -f=sarif', '-filter-mode=added', '-fail-level=error', 'REPORT_FILE="$(mktemp)"']) { + assert.ok(readme.includes(marker), `README reviewdog recipe missing ${marker}`) + assert.ok(operations.includes(marker), `operations reviewdog recipe missing ${marker}`) + } + assert.match(operations, /no AgentsKit-specific reporter or converter is required/i) + assert.match(operations, /REVIEWDOG_GITHUB_API_TOKEN/) + assert.match(operations, /blocker and high findings to SARIF `error`/) + assert.match(operations, /actions\/checkout@[0-9a-f]{40}/) + assert.match(operations, /reviewdog\/action-setup@[0-9a-f]{40}/) + assert.match(operations, /reviewdog_version: v0\.21\.0/) + assert.match(operations, /fetch-depth: 0/) + assert.match(operations, /BASE_REF: \$\{\{ github\.base_ref \}\}/) + assert.match(operations, /LLM_API_KEY: \$\{\{ secrets\.LLM_API_KEY \}\}/) + assert.match(operations, /--provider openai --model gpt-4o/) + assert.match(operations, /--no-fail &&/) + assert.match(operations, /trap 'rm -f/) + assert.match(reviewdogSection, /github:AgentsKit-io\/code-review-cli#[0-9a-f]{40}/) + assert.doesNotMatch(reviewdogSection, /--base origin\/main/) + assert.doesNotMatch(reviewdogSection, /--provider codex-cli/) +}) + test('the Action stays least-privilege, secret-safe, and advisory by default', () => { const action = read('action.yml') const workflow = read('examples/pull-request.yml')