feat: add head_branch to pull request diff status (#23076)

Adds the `head_branch` field (the source/feature branch name of a PR) to
the diff status pipeline. Previously only `base_branch` (target branch)
and the head commit SHA were captured from the GitHub API, but not the
head branch name itself.

## Changes

- **Migration 438**: Add `head_branch` nullable TEXT column to
`chat_diff_statuses`
- **gitprovider**: Parse `head.ref` from the GitHub API response
(alongside `head.sha`) and add `HeadBranch` to `PRStatus`
- **gitsync**: Wire `HeadBranch` through `refreshOne()` into the DB
upsert params
- **worker**: Map `HeadBranch` in `chatDiffStatusFromRow()`
- **coderd**: Convert `HeadBranch` in `convertChatDiffStatus()`
- **codersdk**: Expose as `head_branch` (`*string`, omitempty) in
`ChatDiffStatus` API response
- **Tests**: Updated `github_test.go` pull JSON fixtures and assertions
This commit is contained in:
Kyle Carberry
2026-03-14 17:24:19 +00:00
committed by GitHub
parent 3f7f25b3ee
commit 0d3e39a24e
14 changed files with 54 additions and 24 deletions
@@ -657,7 +657,7 @@ func TestFetchPullRequestStatus(t *testing.T) {
}{
{
name: "OpenPR/NoReviews",
pullJSON: `{"state":"open","merged":false,"draft":false,"additions":10,"deletions":5,"changed_files":3,"head":{"sha":"abc123"}}`,
pullJSON: `{"state":"open","merged":false,"draft":false,"additions":10,"deletions":5,"changed_files":3,"head":{"sha":"abc123","ref":"feature-branch"}}`,
reviews: []review{},
expectedState: gitprovider.PRStateOpen,
expectedDraft: false,
@@ -665,14 +665,14 @@ func TestFetchPullRequestStatus(t *testing.T) {
},
{
name: "OpenPR/SingleChangesRequested",
pullJSON: `{"state":"open","merged":false,"draft":false,"additions":10,"deletions":5,"changed_files":3,"head":{"sha":"abc123"}}`,
pullJSON: `{"state":"open","merged":false,"draft":false,"additions":10,"deletions":5,"changed_files":3,"head":{"sha":"abc123","ref":"feature-branch"}}`,
reviews: []review{makeReview(1, "CHANGES_REQUESTED", "alice")},
expectedState: gitprovider.PRStateOpen,
changesRequested: true,
},
{
name: "OpenPR/ChangesRequestedThenApproved",
pullJSON: `{"state":"open","merged":false,"draft":false,"additions":10,"deletions":5,"changed_files":3,"head":{"sha":"abc123"}}`,
pullJSON: `{"state":"open","merged":false,"draft":false,"additions":10,"deletions":5,"changed_files":3,"head":{"sha":"abc123","ref":"feature-branch"}}`,
reviews: []review{
makeReview(1, "CHANGES_REQUESTED", "alice"),
makeReview(2, "APPROVED", "alice"),
@@ -682,7 +682,7 @@ func TestFetchPullRequestStatus(t *testing.T) {
},
{
name: "OpenPR/ChangesRequestedThenDismissed",
pullJSON: `{"state":"open","merged":false,"draft":false,"additions":10,"deletions":5,"changed_files":3,"head":{"sha":"abc123"}}`,
pullJSON: `{"state":"open","merged":false,"draft":false,"additions":10,"deletions":5,"changed_files":3,"head":{"sha":"abc123","ref":"feature-branch"}}`,
reviews: []review{
makeReview(1, "CHANGES_REQUESTED", "alice"),
makeReview(2, "DISMISSED", "alice"),
@@ -692,7 +692,7 @@ func TestFetchPullRequestStatus(t *testing.T) {
},
{
name: "OpenPR/MultipleReviewersMixed",
pullJSON: `{"state":"open","merged":false,"draft":false,"additions":10,"deletions":5,"changed_files":3,"head":{"sha":"abc123"}}`,
pullJSON: `{"state":"open","merged":false,"draft":false,"additions":10,"deletions":5,"changed_files":3,"head":{"sha":"abc123","ref":"feature-branch"}}`,
reviews: []review{
makeReview(1, "APPROVED", "alice"),
makeReview(2, "CHANGES_REQUESTED", "bob"),
@@ -702,7 +702,7 @@ func TestFetchPullRequestStatus(t *testing.T) {
},
{
name: "OpenPR/CommentedDoesNotAffect",
pullJSON: `{"state":"open","merged":false,"draft":false,"additions":10,"deletions":5,"changed_files":3,"head":{"sha":"abc123"}}`,
pullJSON: `{"state":"open","merged":false,"draft":false,"additions":10,"deletions":5,"changed_files":3,"head":{"sha":"abc123","ref":"feature-branch"}}`,
reviews: []review{
makeReview(1, "COMMENTED", "alice"),
},
@@ -711,14 +711,14 @@ func TestFetchPullRequestStatus(t *testing.T) {
},
{
name: "MergedPR",
pullJSON: `{"state":"closed","merged":true,"draft":false,"additions":10,"deletions":5,"changed_files":3,"head":{"sha":"abc123"}}`,
pullJSON: `{"state":"closed","merged":true,"draft":false,"additions":10,"deletions":5,"changed_files":3,"head":{"sha":"abc123","ref":"feature-branch"}}`,
reviews: []review{},
expectedState: gitprovider.PRStateMerged,
changesRequested: false,
},
{
name: "DraftPR",
pullJSON: `{"state":"open","merged":false,"draft":true,"additions":10,"deletions":5,"changed_files":3,"head":{"sha":"abc123"}}`,
pullJSON: `{"state":"open","merged":false,"draft":true,"additions":10,"deletions":5,"changed_files":3,"head":{"sha":"abc123","ref":"feature-branch"}}`,
reviews: []review{},
expectedState: gitprovider.PRStateOpen,
expectedDraft: true,
@@ -762,6 +762,7 @@ func TestFetchPullRequestStatus(t *testing.T) {
assert.Equal(t, tc.expectedDraft, status.Draft)
assert.Equal(t, tc.changesRequested, status.ChangesRequested)
assert.Equal(t, "abc123", status.HeadSHA)
assert.Equal(t, "feature-branch", status.HeadBranch)
assert.Equal(t, int32(10), status.DiffStats.Additions)
assert.Equal(t, int32(5), status.DiffStats.Deletions)
assert.Equal(t, int32(3), status.DiffStats.ChangedFiles)