Skip to content

Post to Phabricator when a task link is added after the PR is opened - #6809

Open
josephseddon wants to merge 4 commits into
mainfrom
claude/github-actions-inventory-jlsdso
Open

Post to Phabricator when a task link is added after the PR is opened#6809
josephseddon wants to merge 4 commits into
mainfrom
claude/github-actions-inventory-jlsdso

Conversation

@josephseddon

Copy link
Copy Markdown

What does this do?

Subscribes android_phab.yml to the edited pull request event, and posts to Phabricator only for task IDs that the edit actually added — diffing github.event.changes.body.from (the pre-edit body) against the current body.

Event Behavior
opened unchanged — notifies every task in the body, verb opened
edited, task added posts <actor> linked <PR url> for the new task(s) only
edited, task already present nothing
edited, title/base-branch only exits early (no changes.body in the payload)
closed unchanged — notifies every task, verb closed

The 10s pause between posts is unchanged.

Why is this needed?

The workflow only listened for opened and closed, reading the task ID from the PR body at event time. If a PR was created before the **Phabricator:** line was filled in, the task never got an "opened" notification — edited wasn't subscribed to, and re-running the original job replays the original task-less payload. The task only heard about the PR when it closed.

This repo's PR template ships a https://phabricator.wikimedia.org/T... placeholder, which doesn't match T[0-9]+. So every PR opened before that placeholder is replaced with a real task ID hits this case.

Naively adding edited would over-correct: every later body edit — filling in sections, fixing a typo — would re-post to an already-linked task. Hence the set difference.

One subtlety worth flagging for review: the "was the body actually edited" check is done in bash against toJSON(...) rather than as a GitHub expression. github.event.changes.body.from != null looks equivalent but isn't — an edit from an empty body yields '', which compares equal to null under GitHub's type casting, and would skip exactly the case this fixes.

Also carried along:

  • printf '%s' instead of echo -e, which was interpreting backslash escapes in the body before matching
  • strip CR and sort -u, so a CRLF body naming one task twice posts once rather than twice
  • || true on the extraction pipeline, so a body with no task reference isn't an error under a pipefail shell (harmless under the current bash -e {0}, but one shell: bash away from breaking)
  • API token moved out of the inlined curl argument into env:
  • dropped the step-level if:, which re-checked what on: already guarantees

Test Steps

Verified locally by extracting the run: block and driving it with stubbed curl/sleep — 16 cases, all passing, including:

Case Expected
template untouched (T... placeholder) silent
template with real ID, URL on its own line posts
edit replacing placeholder with real ID posts linked once
later edit, ID already present silent
edit adding a second task posts only the new one
title-only edit silent
edit from an empty body posts
task removed by an edit silent
CRLF body naming one task twice one comment
closed with two tasks both, sleep 10 between

Confirmed exit 0 under both bash -e (what actually runs) and bash -eo pipefail.

This PR can also serve as a live test: it was opened with the template placeholder intact, so no comment should have been posted. Editing the description to add a real task ID should post exactly one linked comment to that task, and any edit after that should post nothing. Note this posts to Phabricator for real — use a scratch task.

Phabricator:
https://phabricator.wikimedia.org/T...


This mirrors the same change made to post_phab.yml in wikipedia-ios#6079.

🤖 Generated with Claude Code

https://claude.ai/code/session_01XyimsJL4PymoNhpfWeQ5DG


Generated by Claude Code

The workflow only listened for `opened` and `closed`, reading the task ID
from the PR body at event time. A PR created before the `**Phabricator:**`
line was filled in never notified the task, even if the link was added
later -- `edited` wasn't subscribed to, so the task only heard about the PR
on close. The PR template ships a `https://phabricator.wikimedia.org/T...`
placeholder, so a PR opened before that is replaced with a real task ID hits
this case.

Subscribe to `edited` and post only for task IDs the edit actually added,
diffing `github.event.changes.body.from` against the current body. Unrelated
body edits no longer re-notify an already-linked task. Edit-triggered
comments use the verb "linked" to distinguish them from open/close
notifications.

`edited` also fires for title and base-branch changes, which carry no
changes.body; those exit early. The check is done in bash against
toJSON(...) rather than as a GitHub expression, because `changes.body.from
!= null` is false for an edit from an empty body and would wrongly skip it.

Also while here:
- printf '%s' instead of echo -e, which was interpreting backslash escapes
  in the body before matching
- strip CR and sort -u, so a CRLF body naming one task twice posts once
- `|| true` on the extraction pipeline, so a body with no task reference is
  not an error under a pipefail shell
- move the API token out of the inlined curl argument into env
- drop the step-level `if:`, which re-checked what `on:` already guarantees

The 10s pause between posts is unchanged.

This mirrors the same change made to post_phab.yml in wikipedia-ios.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XyimsJL4PymoNhpfWeQ5DG
Copilot AI balanced review requested due to automatic review settings August 19, 2026 00:19

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Extends Phabricator notifications to newly linked tasks after PR body edits.

Changes:

  • Handles edited pull request events.
  • Diffs task IDs before and after edits.
  • Improves task extraction and secret handling.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread .github/workflows/android_phab.yml
The extraction regexes are case-insensitive, but `sort -u` and the
`grep -Fxv` set difference are not. "T123" and "t123" were therefore treated
as two distinct tasks: a body naming both posted twice, and an edit that
changed only the identifier's casing looked like a newly added task and
emitted another "linked" comment for a task already linked. The lowercase
form was also sent to Phabricator as objectIdentifier.

Upper-case extracted IDs before they reach `sort -u` and the diff, which
fixes both and sends the canonical form.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XyimsJL4PymoNhpfWeQ5DG

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 1 out of 1 changed files in this pull request and generated no new comments.

The two extraction branches had drifted apart: the URL branch tolerated
markdown bold around its label ("**Phabricator:**"), while the trailer branch
was anchored on a bare "^Bug:". So "**Bug:** T430815" -- a natural thing to
write, mirroring the bolded label the PR template itself uses -- matched
nothing and silently notified no one. A bare ID after a label
("**Phabricator:** T430815", no URL) was likewise unmatched.

Replace both branches with one label rule: "Bug:" or "Phabricator:",
optionally markdown-bolded, followed by either a bare T123 or a
phabricator.wikimedia.org URL; plus a bare URL with no label, as before.

A bare "T123" with neither label nor URL still does not match -- accepting
that anywhere a line happens to start with a T-number would be too loose.

Verified: the two new forms match; all previously matching forms still do;
and "T430815" alone, "Debug: T999", a mid-line URL, and the PR template's
own "T..." placeholder all still correctly match nothing.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XyimsJL4PymoNhpfWeQ5DG
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Development

Successfully merging this pull request may close these issues.

4 participants