+7
-6
types/merge.go
+7
-6
types/merge.go
···
13
13
}
14
14
15
15
type MergeRequest struct {
16
-
Patch string `json:"patch"`
17
-
AuthorName string `json:"authorName,omitempty"`
18
-
AuthorEmail string `json:"authorEmail,omitempty"`
19
-
CommitBody string `json:"commitBody,omitempty"`
20
-
CommitMessage string `json:"commitMessage,omitempty"`
21
-
Branch string `json:"branch"`
16
+
Patch string `json:"patch"`
17
+
AuthorName string `json:"authorName,omitempty"`
18
+
AuthorEmail string `json:"authorEmail,omitempty"`
19
+
CommitBody string `json:"commitBody,omitempty"`
20
+
CommitMessage string `json:"commitMessage,omitempty"`
21
+
CommitFooters map[string]string `json:"commitFooters,omitempty"`
22
+
Branch string `json:"branch"`
22
23
}
+2
-1
appview/knotclient/signer.go
+2
-1
appview/knotclient/signer.go
···
201
201
202
202
func (s *SignedClient) Merge(
203
203
patch []byte,
204
-
ownerDid, targetRepo, branch, commitMessage, commitBody, authorName, authorEmail string,
204
+
ownerDid, targetRepo, branch, commitMessage, commitBody, authorName, authorEmail string, footers map[string]string,
205
205
) (*http.Response, error) {
206
206
const (
207
207
Method = "POST"
···
215
215
AuthorName: authorName,
216
216
AuthorEmail: authorEmail,
217
217
Patch: string(patch),
218
+
CommitFooters: footers,
218
219
}
219
220
220
221
body, _ := json.Marshal(mr)
+8
-1
appview/state/pull.go
+8
-1
appview/state/pull.go
···
1534
1534
log.Printf("failed to get primary email: %s", err)
1535
1535
}
1536
1536
1537
+
actor := s.oauth.GetUser(r) // no need to check for nil as this is an authenticated request
1538
+
1539
+
var footers = map[string]string{
1540
+
"Pull-id": string(pull.PullAt()),
1541
+
"Merged-by": actor.Did,
1542
+
}
1543
+
1537
1544
ksClient, err := knotclient.NewSignedClient(f.Knot, secret, s.config.Core.Dev)
1538
1545
if err != nil {
1539
1546
log.Printf("failed to create signed client for %s: %s", f.Knot, err)
···
1542
1549
}
1543
1550
1544
1551
// Merge the pull request
1545
-
resp, err := ksClient.Merge([]byte(pull.LatestPatch()), f.OwnerDid(), f.RepoName, pull.TargetBranch, pull.Title, pull.Body, ident.Handle.String(), email.Address)
1552
+
resp, err := ksClient.Merge([]byte(pull.LatestPatch()), f.OwnerDid(), f.RepoName, pull.TargetBranch, pull.Title, pull.Body, ident.Handle.String(), email.Address, footers)
1546
1553
if err != nil {
1547
1554
log.Printf("failed to merge pull request: %s", err)
1548
1555
s.pages.Notice(w, "pull-merge-error", "Failed to merge pull request. Try again later.")
+21
knotserver/git/merge.go
+21
knotserver/git/merge.go
···
32
32
AuthorName string
33
33
AuthorEmail string
34
34
FormatPatch bool
35
+
CommitFooters map[string]string
35
36
}
36
37
37
38
func (e ErrMerge) Error() string {
···
88
89
var stderr bytes.Buffer
89
90
var cmd *exec.Cmd
90
91
92
+
footers := ""
93
+
for k, v := range opts.CommitFooters {
94
+
footers += fmt.Sprintf("\n%s: %s", k, v)
95
+
}
96
+
91
97
if checkOnly {
92
98
cmd = exec.Command("git", "-C", tmpDir, "apply", "--check", "-v", patchFile)
93
99
} else {
94
100
// if patch is a format-patch, apply using 'git am'
95
101
if opts.FormatPatch {
102
+
patch, err := os.ReadFile(patchFile)
103
+
if err != nil {
104
+
return fmt.Errorf("failed to read patch file: %w", err)
105
+
}
106
+
107
+
re := regexp.MustCompile(`\n(Subject: )([\s\S]*?)(---)\n`)
108
+
patch = re.ReplaceAll(patch, []byte("\n${1}${2}\n"+footers+"\n${3}\n"))
109
+
110
+
err = os.WriteFile(patchFile, patch, 0o644)
111
+
if err != nil {
112
+
return fmt.Errorf("failed to write patch file: %w", err)
113
+
}
114
+
96
115
amCmd := exec.Command("git", "-C", tmpDir, "am", patchFile)
97
116
amCmd.Stderr = &stderr
98
117
if err := amCmd.Run(); err != nil {
···
139
158
commitArgs = append(commitArgs, "-m", opts.CommitBody)
140
159
}
141
160
161
+
commitArgs = append(commitArgs, "-m", footers)
162
+
142
163
cmd = exec.Command("git", commitArgs...)
143
164
} else {
144
165
// If no commit message specified, use git-am which automatically creates a commit