mirror of
https://github.com/go-gitea/gitea.git
synced 2026-09-08 22:13:26 +09:00
feat(actions): add before/after to PR synchronize event payload (#37827)
## Summary - Add `before` and `after` fields to `PullRequestPayload` for `synchronize` events - Thread push old/new commit SHAs through the PR synchronize notifier path (regular and Agit flows) - Populate the fields in webhook and Actions event payloads so workflows can access them via `github.event.before` and `github.event.after` Fixes #33395 --------- Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -434,6 +434,10 @@ type ChangesPayload struct {
|
|||||||
type PullRequestPayload struct {
|
type PullRequestPayload struct {
|
||||||
// The action performed on the pull request
|
// The action performed on the pull request
|
||||||
Action HookIssueAction `json:"action"`
|
Action HookIssueAction `json:"action"`
|
||||||
|
// The SHA of the most recent commit on the PR head branch before the push
|
||||||
|
Before string `json:"before,omitempty"`
|
||||||
|
// The SHA of the most recent commit on the PR head branch after the push
|
||||||
|
After string `json:"after,omitempty"`
|
||||||
// The index number of the pull request
|
// The index number of the pull request
|
||||||
Index int64 `json:"number"`
|
Index int64 `json:"number"`
|
||||||
// Changes made to the pull request (for edit actions)
|
// Changes made to the pull request (for edit actions)
|
||||||
|
|||||||
@@ -0,0 +1,59 @@
|
|||||||
|
// Copyright 2026 The Gitea Authors. All rights reserved.
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
package structs
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"code.gitea.io/gitea/modules/json"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestPullRequestPayloadSynchronizeBeforeAfter(t *testing.T) {
|
||||||
|
payload := &PullRequestPayload{
|
||||||
|
Action: HookIssueSynchronized,
|
||||||
|
Before: "1111111111111111111111111111111111111111",
|
||||||
|
After: "2222222222222222222222222222222222222222",
|
||||||
|
Index: 12,
|
||||||
|
}
|
||||||
|
|
||||||
|
data, err := json.Marshal(payload)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
assert.JSONEq(t, `{
|
||||||
|
"action": "synchronized",
|
||||||
|
"before": "1111111111111111111111111111111111111111",
|
||||||
|
"after": "2222222222222222222222222222222222222222",
|
||||||
|
"number": 12,
|
||||||
|
"commit_id": "",
|
||||||
|
"pull_request": null,
|
||||||
|
"repository": null,
|
||||||
|
"requested_reviewer": null,
|
||||||
|
"review": null,
|
||||||
|
"sender": null
|
||||||
|
}`, string(data))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPullRequestPayloadNonSynchronizeOmitsBeforeAfter(t *testing.T) {
|
||||||
|
payload := &PullRequestPayload{
|
||||||
|
Action: HookIssueOpened,
|
||||||
|
Index: 12,
|
||||||
|
}
|
||||||
|
|
||||||
|
data, err := json.Marshal(payload)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
assert.JSONEq(t, `{
|
||||||
|
"action": "opened",
|
||||||
|
"number": 12,
|
||||||
|
"commit_id": "",
|
||||||
|
"pull_request": null,
|
||||||
|
"repository": null,
|
||||||
|
"requested_reviewer": null,
|
||||||
|
"review": null,
|
||||||
|
"sender": null
|
||||||
|
}`, string(data))
|
||||||
|
}
|
||||||
@@ -687,7 +687,7 @@ func (n *actionsNotifier) AutoMergePullRequest(ctx context.Context, doer *user_m
|
|||||||
n.MergePullRequest(ctx, doer, pr)
|
n.MergePullRequest(ctx, doer, pr)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *actionsNotifier) PullRequestSynchronized(ctx context.Context, doer *user_model.User, pr *issues_model.PullRequest) {
|
func (n *actionsNotifier) PullRequestSynchronized(ctx context.Context, doer *user_model.User, pr *issues_model.PullRequest, before, after string) {
|
||||||
ctx = withMethod(ctx, "PullRequestSynchronized")
|
ctx = withMethod(ctx, "PullRequestSynchronized")
|
||||||
|
|
||||||
if err := pr.LoadIssue(ctx); err != nil {
|
if err := pr.LoadIssue(ctx); err != nil {
|
||||||
@@ -703,6 +703,8 @@ func (n *actionsNotifier) PullRequestSynchronized(ctx context.Context, doer *use
|
|||||||
newNotifyInput(pr.Issue.Repo, doer, webhook_module.HookEventPullRequestSync).
|
newNotifyInput(pr.Issue.Repo, doer, webhook_module.HookEventPullRequestSync).
|
||||||
WithPayload(&api.PullRequestPayload{
|
WithPayload(&api.PullRequestPayload{
|
||||||
Action: api.HookIssueSynchronized,
|
Action: api.HookIssueSynchronized,
|
||||||
|
Before: before,
|
||||||
|
After: after,
|
||||||
Index: pr.Issue.Index,
|
Index: pr.Issue.Index,
|
||||||
PullRequest: convert.ToAPIPullRequest(ctx, pr, nil),
|
PullRequest: convert.ToAPIPullRequest(ctx, pr, nil),
|
||||||
Repository: convert.ToRepo(ctx, pr.Issue.Repo, access_model.Permission{AccessMode: perm_model.AccessModeNone}),
|
Repository: convert.ToRepo(ctx, pr.Issue.Repo, access_model.Permission{AccessMode: perm_model.AccessModeNone}),
|
||||||
|
|||||||
@@ -286,7 +286,7 @@ func ProcReceive(ctx context.Context, repo *repo_model.Repository, gitRepo *git.
|
|||||||
} else if commentCreated {
|
} else if commentCreated {
|
||||||
notify_service.PullRequestPushCommits(ctx, pusher, pr, comment)
|
notify_service.PullRequestPushCommits(ctx, pusher, pr, comment)
|
||||||
}
|
}
|
||||||
notify_service.PullRequestSynchronized(ctx, pusher, pr)
|
notify_service.PullRequestSynchronized(ctx, pusher, pr, oldCommitID, opts.NewCommitIDs[i])
|
||||||
|
|
||||||
results = append(results, private.HookProcReceiveRefResult{
|
results = append(results, private.HookProcReceiveRefResult{
|
||||||
OldOID: oldCommitID,
|
OldOID: oldCommitID,
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ type Notifier interface {
|
|||||||
NewPullRequest(ctx context.Context, pr *issues_model.PullRequest, mentions []*user_model.User)
|
NewPullRequest(ctx context.Context, pr *issues_model.PullRequest, mentions []*user_model.User)
|
||||||
MergePullRequest(ctx context.Context, doer *user_model.User, pr *issues_model.PullRequest)
|
MergePullRequest(ctx context.Context, doer *user_model.User, pr *issues_model.PullRequest)
|
||||||
AutoMergePullRequest(ctx context.Context, doer *user_model.User, pr *issues_model.PullRequest)
|
AutoMergePullRequest(ctx context.Context, doer *user_model.User, pr *issues_model.PullRequest)
|
||||||
PullRequestSynchronized(ctx context.Context, doer *user_model.User, pr *issues_model.PullRequest)
|
PullRequestSynchronized(ctx context.Context, doer *user_model.User, pr *issues_model.PullRequest, before, after string)
|
||||||
PullRequestReview(ctx context.Context, pr *issues_model.PullRequest, review *issues_model.Review, comment *issues_model.Comment, mentions []*user_model.User)
|
PullRequestReview(ctx context.Context, pr *issues_model.PullRequest, review *issues_model.Review, comment *issues_model.Comment, mentions []*user_model.User)
|
||||||
PullRequestCodeComment(ctx context.Context, pr *issues_model.PullRequest, comment *issues_model.Comment, mentions []*user_model.User)
|
PullRequestCodeComment(ctx context.Context, pr *issues_model.PullRequest, comment *issues_model.Comment, mentions []*user_model.User)
|
||||||
PullRequestChangeTargetBranch(ctx context.Context, doer *user_model.User, pr *issues_model.PullRequest, oldBranch string)
|
PullRequestChangeTargetBranch(ctx context.Context, doer *user_model.User, pr *issues_model.PullRequest, oldBranch string)
|
||||||
|
|||||||
@@ -120,9 +120,9 @@ func NewPullRequest(ctx context.Context, pr *issues_model.PullRequest, mentions
|
|||||||
}
|
}
|
||||||
|
|
||||||
// PullRequestSynchronized notifies Synchronized pull request
|
// PullRequestSynchronized notifies Synchronized pull request
|
||||||
func PullRequestSynchronized(ctx context.Context, doer *user_model.User, pr *issues_model.PullRequest) {
|
func PullRequestSynchronized(ctx context.Context, doer *user_model.User, pr *issues_model.PullRequest, before, after string) {
|
||||||
for _, notifier := range notifiers {
|
for _, notifier := range notifiers {
|
||||||
notifier.PullRequestSynchronized(ctx, doer, pr)
|
notifier.PullRequestSynchronized(ctx, doer, pr, before, after)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ func (*NullNotifier) AutoMergePullRequest(ctx context.Context, doer *user_model.
|
|||||||
}
|
}
|
||||||
|
|
||||||
// PullRequestSynchronized places a place holder function
|
// PullRequestSynchronized places a place holder function
|
||||||
func (*NullNotifier) PullRequestSynchronized(ctx context.Context, doer *user_model.User, pr *issues_model.PullRequest) {
|
func (*NullNotifier) PullRequestSynchronized(ctx context.Context, doer *user_model.User, pr *issues_model.PullRequest, before, after string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// PullRequestChangeTargetBranch places a place holder function
|
// PullRequestChangeTargetBranch places a place holder function
|
||||||
|
|||||||
@@ -479,7 +479,7 @@ func AddTestPullRequestTask(opts TestPullRequestOptions) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
notify_service.PullRequestSynchronized(ctx, opts.Doer, pr)
|
notify_service.PullRequestSynchronized(ctx, opts.Doer, pr, opts.OldCommitID, opts.NewCommitID)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -818,7 +818,7 @@ func (m *webhookNotifier) CreateRef(ctx context.Context, pusher *user_model.User
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *webhookNotifier) PullRequestSynchronized(ctx context.Context, doer *user_model.User, pr *issues_model.PullRequest) {
|
func (m *webhookNotifier) PullRequestSynchronized(ctx context.Context, doer *user_model.User, pr *issues_model.PullRequest, before, after string) {
|
||||||
if err := pr.LoadIssue(ctx); err != nil {
|
if err := pr.LoadIssue(ctx); err != nil {
|
||||||
log.Error("LoadIssue: %v", err)
|
log.Error("LoadIssue: %v", err)
|
||||||
return
|
return
|
||||||
@@ -830,6 +830,8 @@ func (m *webhookNotifier) PullRequestSynchronized(ctx context.Context, doer *use
|
|||||||
|
|
||||||
if err := PrepareWebhooks(ctx, EventSource{Repository: pr.Issue.Repo}, webhook_module.HookEventPullRequestSync, &api.PullRequestPayload{
|
if err := PrepareWebhooks(ctx, EventSource{Repository: pr.Issue.Repo}, webhook_module.HookEventPullRequestSync, &api.PullRequestPayload{
|
||||||
Action: api.HookIssueSynchronized,
|
Action: api.HookIssueSynchronized,
|
||||||
|
Before: before,
|
||||||
|
After: after,
|
||||||
Index: pr.Issue.Index,
|
Index: pr.Issue.Index,
|
||||||
PullRequest: convert.ToAPIPullRequest(ctx, pr, doer),
|
PullRequest: convert.ToAPIPullRequest(ctx, pr, doer),
|
||||||
Repository: convert.ToRepo(ctx, pr.Issue.Repo, access_model.Permission{AccessMode: perm.AccessModeOwner}),
|
Repository: convert.ToRepo(ctx, pr.Issue.Repo, access_model.Permission{AccessMode: perm.AccessModeOwner}),
|
||||||
|
|||||||
Reference in New Issue
Block a user