Skip to content

Commit 2a0314b

Browse files
rolandshoemakergopherbot
authored andcommitted
internal/task: add workflow to build internal security release branches
Take security patches in the internal gerrit and from them build the internal release branches that are used to build a security release. Updates golang/go#59717 Change-Id: I2eb4e9fda773e49fbde1fe967678ab3cc813bac8 Reviewed-on: https://go-review.googlesource.com/c/build/+/612116 Reviewed-by: Dmitri Shuralyov <[email protected]> Auto-Submit: Roland Shoemaker <[email protected]> Reviewed-by: Dmitri Shuralyov <[email protected]> LUCI-TryBot-Result: Go LUCI <[email protected]>
1 parent 81e4bd7 commit 2a0314b

File tree

6 files changed

+632
-0
lines changed

6 files changed

+632
-0
lines changed

cmd/relui/main.go

+6
Original file line numberDiff line numberDiff line change
@@ -365,6 +365,12 @@ func main() {
365365
}
366366
dh.RegisterDefinition("Publish a private patch to a x/ repo", privateXPatchTask.NewDefinition(tagTasks))
367367

368+
securityReleaseCoalesceTask := &task.SecurityReleaseCoalesceTask{
369+
PrivateGerrit: privateGerritClient,
370+
Version: versionTasks,
371+
}
372+
dh.RegisterDefinition("Prepare internal security release branches", securityReleaseCoalesceTask.NewDefinition())
373+
368374
var base *url.URL
369375
if *baseURL != "" {
370376
base, err = url.Parse(*baseURL)

gerrit/gerrit.go

+75
Original file line numberDiff line numberDiff line change
@@ -326,6 +326,9 @@ type ChangeInfo struct {
326326
// MoreChanges is set on the last change from QueryChanges if
327327
// the result set is truncated by an 'n' parameter.
328328
MoreChanges bool `json:"_more_changes"`
329+
330+
// ContainsGitConflicts indicates if the change has merge conflicts.
331+
ContainsGitConflicts bool `json:"contains_git_conflicts"`
329332
}
330333

331334
// ReviewerUpdateInfo is a Gerrit data structure.
@@ -1204,3 +1207,75 @@ func (c *Client) GetCommitsInRefs(ctx context.Context, project string, commits,
12041207
err := c.do(ctx, &result, "GET", "/projects/"+url.PathEscape(project)+"/commits:in", urlValues(vals))
12051208
return result, err
12061209
}
1210+
1211+
// CherryPickRevision cherry picks a change revision to a destination branch.
1212+
//
1213+
// See https://gerrit-review.googlesource.com/Documentation/rest-api-changes.html#cherry-pick.
1214+
func (c *Client) CherryPickRevision(ctx context.Context, changeID, revisionID string, cpi CherryPickInput) (ChangeInfo, error) {
1215+
var change ChangeInfo
1216+
err := c.do(ctx, &change, "POST", "/changes/"+changeID+"/revisions/"+revisionID+"/cherrypick", reqBodyJSON{&cpi}, wantResStatus(http.StatusOK))
1217+
return change, err
1218+
}
1219+
1220+
// CherryPickInput contains the options for creating a new cherry-pick.
1221+
//
1222+
// See https://gerrit-review.googlesource.com/Documentation/rest-api-changes.html#cherrypick-input.
1223+
type CherryPickInput struct {
1224+
Destination string `json:"destination"`
1225+
KeepReviewers bool `json:"keep_reviewers"`
1226+
AllowConflicts bool `json:"allow_conflicts"`
1227+
Message string `json:"message,omitempty"`
1228+
}
1229+
1230+
// MoveChange moves a change onto a destination branch.
1231+
//
1232+
// See https://gerrit-review.googlesource.com/Documentation/rest-api-changes.html#move-change.
1233+
func (c *Client) MoveChange(ctx context.Context, changeID string, mi MoveInput) (ChangeInfo, error) {
1234+
var change ChangeInfo
1235+
err := c.do(ctx, &change, "POST", "/changes/"+changeID+"/move", reqBodyJSON{&mi}, wantResStatus(http.StatusOK))
1236+
return change, err
1237+
}
1238+
1239+
// MoveInput contains the options for moving a change.
1240+
//
1241+
// See https://gerrit-review.googlesource.com/Documentation/rest-api-changes.html#move-input.
1242+
type MoveInput struct {
1243+
DestinationBranch string `json:"destination_branch"`
1244+
KeepAllVotes bool `json:"keep_all_votes"`
1245+
}
1246+
1247+
// RebaseChange rebases a change onto a new base revision, or directly on top of
1248+
// the target branch.
1249+
//
1250+
// See https://gerrit-review.googlesource.com/Documentation/rest-api-changes.html#rebase-change.
1251+
func (c *Client) RebaseChange(ctx context.Context, changeID string, ri RebaseInput) (ChangeInfo, error) {
1252+
var change ChangeInfo
1253+
err := c.do(ctx, &change, "POST", "/changes/"+changeID+"/rebase", reqBodyJSON{&ri}, wantResStatus(http.StatusOK))
1254+
return change, err
1255+
}
1256+
1257+
// RebaseInput contains the options for rebasing a change.
1258+
//
1259+
// See https://gerrit-review.googlesource.com/Documentation/rest-api-changes.html#rebase-input.
1260+
type RebaseInput struct {
1261+
Base string `json:"base,omitempty"`
1262+
AllowConflicts bool `json:"allow_conflicts"`
1263+
}
1264+
1265+
// GetCommitMessage retrieves the commit message for a change.
1266+
//
1267+
// See https://gerrit-review.googlesource.com/Documentation/rest-api-changes.html#get-message.
1268+
func (c *Client) GetCommitMessage(ctx context.Context, changeID string) (CommitMessageInfo, error) {
1269+
var cmi CommitMessageInfo
1270+
err := c.do(ctx, &cmi, "GET", "/changes/"+changeID+"/message")
1271+
return cmi, err
1272+
}
1273+
1274+
// CommitMessageInfo contains information about a commit message.
1275+
//
1276+
// See https://gerrit-review.googlesource.com/Documentation/rest-api-changes.html#commit-message-info.
1277+
type CommitMessageInfo struct {
1278+
Subject string `json:"subject"`
1279+
FullMessage string `json:"full_message"`
1280+
Footers map[string]string `json:"footers"`
1281+
}

internal/task/fakes.go

+24
Original file line numberDiff line numberDiff line change
@@ -520,6 +520,30 @@ func (*FakeGerrit) GetChange(_ context.Context, _ string, _ ...gerrit.QueryChang
520520
return nil, nil
521521
}
522522

523+
func (*FakeGerrit) SubmitChange(ctx context.Context, changeID string) (gerrit.ChangeInfo, error) {
524+
return gerrit.ChangeInfo{}, nil
525+
}
526+
527+
func (*FakeGerrit) CreateCherryPick(ctx context.Context, changeID string, branch string, message string) (gerrit.ChangeInfo, bool, error) {
528+
return gerrit.ChangeInfo{}, false, nil
529+
}
530+
531+
func (*FakeGerrit) MoveChange(ctx context.Context, changeID string, branch string, keepAllVotes bool) (gerrit.ChangeInfo, error) {
532+
return gerrit.ChangeInfo{}, nil
533+
}
534+
535+
func (*FakeGerrit) RebaseChange(ctx context.Context, changeID string, baseRev string) (gerrit.ChangeInfo, error) {
536+
return gerrit.ChangeInfo{}, nil
537+
}
538+
539+
func (*FakeGerrit) GetRevisionActions(ctx context.Context, changeID, revision string) (map[string]*gerrit.ActionInfo, error) {
540+
return map[string]*gerrit.ActionInfo{}, nil
541+
}
542+
543+
func (*FakeGerrit) GetCommitMessage(ctx context.Context, changeID string) (string, error) {
544+
return "", nil
545+
}
546+
523547
// NewFakeSignService returns a fake signing service that can sign PKGs, MSIs,
524548
// and generate GPG signatures. MSIs are "signed" by adding a suffix to them.
525549
// PKGs must actually be tarballs with a prefix of "I'm a PKG!\n". Any files

internal/task/gerrit.go

+59
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,22 @@ type GerritClient interface {
6464
SetHashtags(ctx context.Context, changeID string, hashtags gerrit.HashtagsInput) error
6565
// GetChange gets information about a specific change.
6666
GetChange(ctx context.Context, changeID string, opts ...gerrit.QueryChangesOpt) (*gerrit.ChangeInfo, error)
67+
// SubmitChange submits a specific change.
68+
SubmitChange(ctx context.Context, changeID string) (gerrit.ChangeInfo, error)
69+
// CreateCherryPick creates a cherry-pick change. If there are no merge
70+
// conflicts, it starts trybots. If commitMessage is provided, the commit
71+
// message is updated, otherwise it is taken from the original change.
72+
// Reviewers are taken from the original change.
73+
CreateCherryPick(ctx context.Context, changeID string, branch string, commitMessage string) (_ gerrit.ChangeInfo, conflicts bool, _ error)
74+
// RebaseChange rebases a change onto a base revision. If revision is empty,
75+
// the change is rebased directly on top of the target branch.
76+
RebaseChange(ctx context.Context, changeID string, revision string) (gerrit.ChangeInfo, error)
77+
// MoveChange moves a change onto a new branch.
78+
MoveChange(ctx context.Context, changeID string, branch string, keepAllVotes bool) (gerrit.ChangeInfo, error)
79+
// GetRevisionActions retrieves revision actions.
80+
GetRevisionActions(ctx context.Context, changeID, revision string) (map[string]*gerrit.ActionInfo, error)
81+
// GetCommitMessage retrieves the commit message for a change.
82+
GetCommitMessage(ctx context.Context, changeID string) (string, error)
6783
}
6884

6985
type RealGerritClient struct {
@@ -311,3 +327,46 @@ func (c *RealGerritClient) SetHashtags(ctx context.Context, changeID string, has
311327
_, err := c.Client.SetHashtags(ctx, changeID, hashtags)
312328
return err
313329
}
330+
331+
func (c *RealGerritClient) SubmitChange(ctx context.Context, changeID string) (gerrit.ChangeInfo, error) {
332+
return c.Client.SubmitChange(ctx, changeID)
333+
}
334+
335+
func (c *RealGerritClient) CreateCherryPick(ctx context.Context, changeID string, branch string, commitMessage string) (gerrit.ChangeInfo, bool, error) {
336+
cpi := gerrit.CherryPickInput{Destination: branch, KeepReviewers: true, AllowConflicts: true, Message: commitMessage}
337+
ci, err := c.Client.CherryPickRevision(ctx, changeID, "current", cpi)
338+
if err != nil {
339+
return gerrit.ChangeInfo{}, false, err
340+
}
341+
if ci.ContainsGitConflicts {
342+
return ci, true, nil
343+
}
344+
if err := c.Client.SetReview(ctx, ci.ID, "current", gerrit.ReviewInput{
345+
Labels: map[string]int{
346+
"Commit-Queue": 1,
347+
},
348+
}); err != nil {
349+
return gerrit.ChangeInfo{}, false, err
350+
}
351+
return ci, false, nil
352+
}
353+
354+
func (c *RealGerritClient) MoveChange(ctx context.Context, changeID string, branch string, keepAllVotes bool) (gerrit.ChangeInfo, error) {
355+
return c.Client.MoveChange(ctx, changeID, gerrit.MoveInput{DestinationBranch: branch, KeepAllVotes: keepAllVotes})
356+
}
357+
358+
func (c *RealGerritClient) RebaseChange(ctx context.Context, changeID string, base string) (gerrit.ChangeInfo, error) {
359+
return c.Client.RebaseChange(ctx, changeID, gerrit.RebaseInput{Base: base, AllowConflicts: true})
360+
}
361+
362+
func (c *RealGerritClient) GetRevisionActions(ctx context.Context, changeID, revision string) (map[string]*gerrit.ActionInfo, error) {
363+
return c.Client.GetRevisionActions(ctx, changeID, revision)
364+
}
365+
366+
func (c *RealGerritClient) GetCommitMessage(ctx context.Context, changeID string) (string, error) {
367+
cmi, err := c.Client.GetCommitMessage(ctx, changeID)
368+
if err != nil {
369+
return "", err
370+
}
371+
return cmi.FullMessage, nil
372+
}

0 commit comments

Comments
 (0)