--- on: workflow_run: workflows: ["Check requirements (deterministic)"] types: [completed] # On workflow_run the actor is the PR author, so the default role gate # (admin/maintainer/write) skips every PR from an outside contributor — which is # exactly who this review is for. The job is read-only and its single safe-output # is a sanitized comment on the PR recorded in the trusted upstream artifact. roles: all permissions: contents: read actions: read pull-requests: read network: allowed: - python tools: web-fetch: {} github: toolsets: [repos, pull_requests] min-integrity: unapproved if: needs.prepare.outputs.skip != 'true' safe-outputs: add-comment: max: 1 target: "${{ needs.prepare.outputs.pr_number }}" needs: - prepare jobs: prepare: # The deterministic stage always uploads an artifact; its `skip_aw` flag is # true when no tracked requirement file changed since the last comment, # which is our cue to skip the (token-spending) agent. Recover the PR number # to comment on either way. if: github.event.workflow_run.conclusion == 'success' runs-on: ubuntu-latest permissions: actions: read contents: read outputs: skip: ${{ steps.prepare.outputs.skip }} pr_number: ${{ steps.prepare.outputs.pr_number }} steps: - name: Download deterministic-results artifact id: download uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: name: check-requirements-deterministic path: /tmp/deterministic run-id: ${{ github.event.workflow_run.id }} github-token: ${{ secrets.GITHUB_TOKEN }} - name: Resolve skip and PR number from the artifact id: prepare run: | echo "skip=$(jq -r '.skip_aw' /tmp/deterministic/results.json)" >> "${GITHUB_OUTPUT}" echo "pr_number=$(jq -r '.pr_number' /tmp/deterministic/results.json)" >> "${GITHUB_OUTPUT}" concurrency: group: ${{ github.workflow }}-${{ github.event.workflow_run.id }} cancel-in-progress: true steps: - name: Download deterministic-results artifact if: github.event.workflow_run.conclusion == 'success' uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: name: check-requirements-deterministic path: /tmp/gh-aw/deterministic run-id: ${{ github.event.workflow_run.id }} github-token: ${{ secrets.GITHUB_TOKEN }} post-steps: - name: Verify agent produced an add_comment safe-output if: always() && github.event.workflow_run.conclusion == 'success' run: | OUTPUT=/tmp/gh-aw/agent_output.json if [ ! -f "${OUTPUT}" ]; then echo "::error::Agent output file ${OUTPUT} is missing; the agent did not run to completion." exit 1 fi if ! grep -q '"add_comment"' "${OUTPUT}"; then echo "::error::Agent did not emit an add_comment safe-output; no review comment was posted to the PR." echo "Agent output:" cat "${OUTPUT}" exit 1 fi description: > Resolves the deterministic-stage artifact's NEEDS_AGENT checks for changed Python package requirements on PRs targeting the core repo, then posts the final review comment. Triggered by completion of the deterministic workflow. Reads the uploaded artifact from disk, replaces placeholders for any check whose status is `needs_agent`, and posts the merged comment using the PR number recorded inside the artifact itself. Each check kind has a dedicated instruction section below; if the artifact contains a check kind that does not have a section here, the agent fails hard rather than guess. --- # Check requirements (AW) You are a code-review assistant for Home Assistant. The deterministic stage already evaluated every check it can and produced an artifact at `/tmp/gh-aw/deterministic/results.json`. Your only job is to resolve any `needs_agent` checks and post the rendered comment. ## Step 1 — Read the artifact Read the JSON directly for the full schema. Key fields: - `pr_number`, `needs_agent` (bool), `packages[]`, `rendered_comment`. - Each `package`: `name`, `old_version` (`null` if new), `new_version`, `repo_url`, `publisher_kind`, `checks` (keyed by check-kind, each with `status` of `pass`/`warn`/`fail`/`needs_agent` and `details`). - `rendered_comment` contains, for each `needs_agent` check, two placeholders to replace: - `{{CHECK_CELL::}}` → exactly one of `✅`, `☑️`, `⚠️`, `❌`. The **`security`** check kind uses `☑️` instead of `✅` for the success case — see its section below for why. - `{{CHECK_DETAIL::}}` → ` ` (the bullet's `- **