The workflows of a project add their parts to the one report¶
- Status: accepted
- Date: 2026-10-25
Context¶
The PR coach keeps one comment on a pull request (decision 0030): the checks that failed, the release, the coverage and the website. The workflows of a project had no way into it, so each one that had something to say about a pull request kept a comment of its own: the visual tests of ha-autodarts and of paperless-unified-search, the size of the card module of ha-autodarts, and the screenshots of the changed pages of a website. A pull request had more than one comment of a bot again, each with its own notifications, and each workflow wrote the code of its comment anew, with its own rules for text that the pull request controls.
Such a workflow runs the code of the pull request, also of one from a fork, so what it hands over is as trusted as the pull request itself.
Options¶
- Each workflow writes a section into the comment of the coach. The coach writes the whole comment anew after every workflow, and GitHub can't write a comment only if nobody changed it since, so a section could get lost between two writers; and every workflow would need a token that writes pull requests.
- Each workflow keeps its part as an artifact, and the coach collects the artifacts of the head in every run, by any name with a prefix. The API lists the artifacts of a run or of the repository, not those of a commit: the coach would ask once for each run of the head, about fifteen requests in each of its runs, or read the newest artifacts of the repository and miss the part of a busy day.
- As 2, but the catalog of the default branch names each part:
[report.<name>]in.github/checks.project.toml, with its title. The coach asks for the artifactpr-report-<name>by its name, one request for each part, as it does for the website.
Decision¶
Option 3.
- The contract: a workflow keeps the artifact
pr-report-<name>for the head of the pull request with the filereport.md, Markdown in UTF-8.<name>has lowercase letters, digits and hyphens, at most 40. The newest artifact of that name for the head counts, so a run again takes the place of the one before.[report.<name>]in.github/checks.project.toml, or in.github/checks.tomlfor a workflow of the blueprint, gives the part itstitle, an optionalabout, a text in Markdown that the coach shows as it is, and an optionalreplaces, the marker of the old comment of the token of the workflows, such as<!-- visual-check -->, which the coach deletes once the part shows its text, and not while the report has no room for it or the coach couldn't read it. The coach shows at most four parts, in the order of the catalog, after its own; the two catalogs together declare at most four, and more are an error of the catalog, so that none goes unseen without a word. - Data, never code: the coach runs nothing of the artifact. It downloads one of at most 256 kB with
gh run downloadinto a folder of its own and reads the first 64 kB ofreport.md, never a link. The text shows only as code: a paragraph, an item of a list or a heading as inline code, a table with code in each cell and every pipe escaped, a block of code in a fence that none of its lines can close, without a language that GitHub draws as a picture instead of code (mermaid,geojson,topojson,stl,math), without control characters, at most 8,000 characters of a part, 20 rows and 6 columns of a table and 30 lines of a block of code. Links, images, HTML and mentions of the text show as they are written, and the only links of a part lead to its artifact on GitHub, built from the numbers of the API. - News: a part is news, so that a pull request of a person whose checks pass gets the comment, unless the first line of its
report.mdis<!-- quiet -->, such as a size that stays as it was. Areport.mdthat says nothing gives no part. An artifact too large to read is news and says so, one that the coach couldn't read is no news and waits for the next run. - When: the coach runs after the workflows that start it, those of the blueprint and those that the answer
test_workflowsnames. A workflow of the project that keeps a part belongs intotest_workflows; otherwise its part shows with the next run of the coach for the same commit. - The size of the comment: the parts fill the comment first, in their order, as many as fit, and a note counts those that don't; the checks that failed take the room that is left, as before.
Consequences¶
A workflow of a project says what it found in the comment of the coach, with the rules of the coach for untrusted text, and needs no token that writes pull requests for it. Its old comment goes away with replaces. A rich report, such as pictures of visual tests, shows as a table or a list in the part, with the link to the artifact that holds the pictures; the coach shows no picture, as it would load it from wherever the pull request says.
The coach asks GitHub once more for each declared part in each of its runs, and three times more for each part whose artifact the head has, as gh run download lists the artifacts of the run and downloads the one. A repository declares only the parts of its workflows, so a pull request of a repository without parts costs nothing more. A pull request of a bot gets no parts, as before.
The catalog of an existing repository belongs to the project, so the update brings no [report.<name>]: each repository adds the parts of its own workflows, and the starter of .github/checks.project.toml shows how.