Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
11 KiB
on, permissions, network, tools, safe-outputs, concurrency, steps, post-steps, description
| on | permissions | network | tools | safe-outputs | concurrency | steps | post-steps | 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 the Home Assistant project. The
deterministic stage has already evaluated every check it can on its own
and produced an artifact containing the PR number, per-package check
results, and a pre-rendered comment with placeholders. Your only job is
to read that artifact, resolve any needs_agent checks, and post the
final comment.
Step 1 — Read the deterministic-stage artifact
The deterministic stage uploaded its results to the runner at
/tmp/gh-aw/deterministic/results.json.
The JSON has this shape:
pr_number— the PR being checked. Theadd_commentsafe-output is already targeted at this PR (the workflow extractedpr_numberfrom the artifact and wired it into the safe-output config), so you do not need to setitem_numberyourself — just emitadd_commentwith the rendered body.needs_agent—trueiff any package's check needs resolution.packages[]— one entry per changed package. Each entry has:name,old_version(nullfor a newly added package; otherwise the previous pin),new_version,repo_url,publisher_kind.checks— a dict keyed by check kind (string). Each value has astatus(pass,warn,fail, orneeds_agent) anddetails.
rendered_comment— the final PR comment body, already rendered. For every check whose status isneeds_agentit contains two placeholders you must replace:{{CHECK_CELL:<pkg-name>:<check-kind>}}— one cell of the summary table. Replace with exactly one of✅,⚠️,❌.{{CHECK_DETAIL:<pkg-name>:<check-kind>}}— the body of one bullet in the package's<details>block. Replace with<icon> <one-line explanation>(the bullet's leading- **<label>**:is already rendered — replace only the placeholder).
You must not modify any other content in rendered_comment. Do not
re-evaluate checks that already have a deterministic status. Do not add
or remove packages.
Step 2 — Resolve each needs_agent check
For each package in packages:
For each (check_kind, result) in package.checks where
result.status == "needs_agent":
-
Look up
## Check kind: <check_kind>in the Check instructions section below. -
If no matching section exists: emit a single
add_commentwhose body is:<!-- requirements-check --> ## Check requirements ❌ Internal error: the deterministic artifact contains a check kind (`<check_kind>` on package `<pkg-name>`) that this workflow has no instructions for. Update `.github/workflows/check-requirements.md` to add a matching `## Check kind: <check_kind>` section, or remove the kind from the deterministic stage.Then stop. Do not improvise a verdict for an unknown check kind.
-
Otherwise, follow the instructions in that section. They tell you which icon (✅/⚠️/❌) and one-line explanation to produce.
Step 3 — Post the comment
- Replace every
{{CHECK_CELL:…}}and{{CHECK_DETAIL:…}}placeholder inrendered_commentwith the resolved value. - Emit the resulting markdown using
add_comment— setbodyto the mergedrendered_commentverbatim (the leading<!-- requirements-check -->marker must be preserved). The PR target is already set by the workflow; do not passitem_number.
If the artifact's top-level needs_agent is false (no checks need
you), emit rendered_comment unchanged.
Check instructions
Check kind: repo_public
Verify that the package's source repository is publicly reachable.
- Read
package.repo_url. - Use the
web-fetchtool to GET that URL. - Decide the verdict:
- HTTP 200, returns a public repository page → ✅
<repo_url> is publicly accessible. - HTTP 4xx/5xx, or the response redirects to a login / sign-in page →
❌
Source repository at <repo_url> is not publicly accessible. Home Assistant requires all dependencies to have publicly available source code. - Any other inconclusive result → ⚠️ with a one-line description.
- HTTP 200, returns a public repository page → ✅
If repo_public resolves to ❌ for a package, also mark that
package's release_pipeline cell/detail as — (em dash) and explain
Skipped because the source repository is not publicly accessible. —
because the release pipeline cannot be inspected without a public repo.
Check kind: pr_link
Verify the PR description contains the right link for the change.
- Fetch the PR body via the GitHub MCP tool, using the
pr_numberfield from the artifact. - Extract all URLs from the body.
- For a new package (
package.old_versionisnull):- The PR body must contain a URL that points at
package.repo_url(any sub-path of the sameowner/repoon the same host is acceptable). A PyPI link is not sufficient. - ✅ if such a URL is present.
- ❌ otherwise:
PR description must link to the source repository at <repo_url>. A PyPI page link is not sufficient.
- The PR body must contain a URL that points at
- For a version bump (
package.old_versionis notnull):- The PR body must contain a URL on the same host as
package.repo_urlthat references bothpackage.old_versionandpackage.new_version(e.g. a GitHub compare URLcompare/vX...vY, a release / changelog URL containing both versions, etc.). - ✅ if such a URL is present and the versions match the actual bump.
- ❌ otherwise:
PR description should link to a changelog or compare URL on <repo_url> that mentions both <old_version> and <new_version>.
- The PR body must contain a URL on the same host as
Check kind: release_pipeline
Inspect the upstream project's release / publish CI pipeline.
For each package needing inspection, determine the source repository
host from package.repo_url, then apply the corresponding checklist.
GitHub repositories (github.com)
- List workflows:
GET /repos/{owner}/{repo}/actions/workflows. - Identify any workflow whose name or filename suggests publishing to
PyPI (
release,publish,pypi, ordeploy). - Fetch the workflow file and check:
- Trigger sanity: triggered by
pushto tags,release: published, orworkflow_runon a release job — not solelyworkflow_dispatchwith no environment-protection guard. - OIDC / Trusted Publisher: look for
id-token: writeand one ofpypa/gh-action-pypi-publish,actions/attest-build-provenance, orTWINE_PASSWORDfrom a staticsecrets.PYPI_TOKEN. - No manual upload bypass: no ungated
twine uploadorpip upload.
- Trigger sanity: triggered by
- Verdict:
- ✅ if OIDC + sane triggers + no bypass.
- ⚠️ if static token but version bump, or details unclear.
- ❌ if static token on a new package, or only-manual triggers with no environment protection.
GitLab repositories (gitlab.com or self-hosted GitLab)
- Resolve the project ID via
GET https://gitlab.com/api/v4/projects/{url-encoded-namespace-and-name}. - Fetch
.gitlab-ci.ymlviaGET https://gitlab.com/api/v4/projects/{id}/repository/files/.gitlab-ci.yml/raw?ref=HEAD. - Apply the same conceptual checks: tag-only / protected-branch
triggers, GitLab OIDC
id_tokensor CI/CD protectedPYPI_TOKEN, no ungatedtwine upload. Same verdict rules as GitHub.
Other code hosting providers (Bitbucket, Codeberg, Gitea, Sourcehut, …)
- Use
web-fetchto retrieve any visible CI configuration (.circleci/config.yml,Jenkinsfile,azure-pipelines.yml,bitbucket-pipelines.yml,.builds/*.yml). - Apply the conceptual checks: automated triggers, CI-injected
credentials, no manual
twine upload. - If no CI config can be retrieved: ⚠️
Release pipeline could not be inspected; hosting provider is not GitHub or GitLab.
Notes
- Be constructive and helpful. Reference the inspected workflow / CI file by URL where useful so the contributor can fix the issue.
- The dedup of the requirements-check comment is handled by gh-aw's
add_commentsafe-output via the<!-- requirements-check -->marker on the first line ofrendered_comment. - If the deterministic workflow concluded with a non-success status,
this workflow's
if:guard onDownload deterministic-results artifactskipped the download. If you find no file at/tmp/gh-aw/deterministic/results.json, emit nothing — the post-step verification is also gated and will not complain.