ci: Python emitter regen-diff check (PoC) - #5
l0lawrence wants to merge 1 commit into
Conversation
Regenerate the http-client-python generated test code with the emitter at the PR head and at a pinned baseline commit, diff the two outputs, fail CI on any diff, and post a PR comment linking to an HTML view of the diff (uploaded as a workflow artifact). Adds: - packages/http-client-python/eng/regen-diff-baseline.txt (pinned baseline SHA) - packages/http-client-python/eng/scripts/ci/regen-diff-html.ts (diff -> HTML/comment) - .github/workflows/python-emitter-regen-diff.yml (regen x2 + diff + fail) - .github/workflows/python-emitter-regen-diff-comment.yml (workflow_run comment) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
❌ There is undocummented changes. Run The following packages have changes but are not documented.
Show changes |
There was a problem hiding this comment.
🟡 Changes recommended
Unresolved workflow security, permissions, and reliability issues remain.
Get a fresh assessment by requesting another Copilot review.
Pull request overview
Adds a proof-of-concept CI check comparing Python emitter-generated tests with a pinned baseline, publishing diff artifacts and PR comments.
Changes:
- Adds the baseline commit and diff-report generator.
- Adds head/base regeneration and fail-on-diff workflows.
- Adds artifact-based PR commenting.
File summaries
| File | Description |
|---|---|
packages/http-client-python/eng/scripts/ci/regen-diff-html.ts |
Generates diff reports and comment payloads. |
packages/http-client-python/eng/regen-diff-baseline.txt |
Defines the pinned baseline commit. |
.github/workflows/python-emitter-regen-diff.yml |
Regenerates and compares generated code. |
.github/workflows/python-emitter-regen-diff-comment.yml |
Publishes or updates PR comments from artifacts. |
Review details
Suppressed comments (5)
.github/workflows/python-emitter-regen-diff-comment.yml:11
- GitHub only triggers a
workflow_runworkflow when that workflow file exists on the default branch. Since this companion workflow is introduced by the same PR as the producer workflow, it will not post the promised comment for this PR's run; bootstrap this privileged workflow on the default branch (or use an already-installed commenter) before relying on this pattern.
workflow_run:
workflows: ["Python Emitter Regen Diff"]
types: [completed]
.github/workflows/python-emitter-regen-diff-comment.yml:18
- The producer workflow cancels older runs for the same PR, but this
workflow_runworkflow has no corresponding concurrency control. A canceled older run that already uploaded its payload can be processed after a newer run and overwrite the PR comment with a stale diff link; key this workflow by PR number and cancel the previous commenter run.
jobs:
comment:
if: github.event.workflow_run.event == 'pull_request'
.github/workflows/python-emitter-regen-diff.yml:60
- For a pull request from a fork, this checkout still targets the base repository because no
repositoryis supplied. The head SHA therefore is not present in the repository being checked out, so theheadmatrix job fails before regeneration; select the PR head repository for the head entry and the base repository for the baseline/manual entries.
uses: actions/checkout@v6
with:
ref: ${{ matrix.which == 'base' && needs.read-baseline.outputs.sha || github.event.pull_request.head.sha || github.sha }}
.github/workflows/python-emitter-regen-diff.yml:79
- Both matrix jobs run
npm run regenerate, and that regeneration independently fetches the mutabletypespec-python-generated-testsbranch when preparingtests/generated. If the branch advances between the head and base jobs, the comparison includes upstream seed changes and can fail even when the emitter is unchanged. Resolve the seed branch to one commit once and reuse that commit for both regens (or share one prepared seed artifact).
- name: Regenerate
run: npm run regenerate
packages/http-client-python/eng/scripts/ci/regen-diff-html.ts:125
- Header detection is not limited to pre-hunk metadata. An added line whose content starts with
++is serialized as+++, so this branch consumes real hunk content as a file header, overwritesnewPath, and drops the line from the rendered diff. Only recognize file headers before entering a hunk (for example, by tracking whether@@has been seen).
if (line.startsWith("+++ ")) {
const p = line.slice(4);
if (p === "/dev/null") current.status = "removed";
else current.newPath = p;
- Files reviewed: 4/4 changed files
- Comments generated: 5
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| const prNumber = parseInt( | ||
| fs.readFileSync('comment-payload/pr-number.txt', 'utf8').trim(), | ||
| 10, | ||
| ); |
| permissions: | ||
| pull-requests: write |
| - name: Download comment payload | ||
| uses: actions/download-artifact@v8 | ||
| with: | ||
| name: python-regen-diff-comment | ||
| run-id: ${{ github.event.workflow_run.id }} | ||
| github-token: ${{ secrets.GITHUB_TOKEN }} | ||
| path: comment-payload | ||
|
|
||
| - name: Post or update PR comment | ||
| uses: actions/github-script@v7 | ||
| with: |
| SHA=$(grep -v '^[[:space:]]*#' "$FILE" | grep -v '^[[:space:]]*$' | head -n1 | tr -d '[:space:]') | ||
| if [ -z "$SHA" ]; then echo "No baseline SHA found in $FILE" >&2; exit 1; fi |
| if (line.startsWith("+") && !line.startsWith("+++")) current.insertions++; | ||
| else if (line.startsWith("-") && !line.startsWith("---")) current.deletions++; |
What
Proof-of-concept CI check that detects when a change to the Python emitter (
packages/http-client-python) alters its generated test code.On a PR touching
packages/http-client-python/**, the workflow:packages/http-client-python/eng/regen-diff-baseline.txt.python-regen-diff-html).workflow_runpattern) linking to the artifact.If a diff is expected, the author bumps the baseline SHA to accept the new output.
Files
packages/http-client-python/eng/regen-diff-baseline.txt— pinned baseline commit SHA.packages/http-client-python/eng/scripts/ci/regen-diff-html.ts— dependency-free reporter (git diff --no-index→ HTML + comment payload +result.json)..github/workflows/python-emitter-regen-diff.yml—pull_request: generate (head/base matrix) → diff → fail-on-diff..github/workflows/python-emitter-regen-diff-comment.yml—workflow_run: posts the PR comment (works for fork PRs).Notes / caveats
Azure/typespec-azure. Intended to be extended to the csharp/java/js emitters next.