Skip to content

Commit 5447ef5

Browse files
authored
Merge pull request #14 from ti-community-infra/refactor/combine-community-cherry-pick-plugin
refactor(external-plugins/cherrypick): add skipFork option and improve
2 parents ab8ba10 + 22e812e commit 5447ef5

File tree

2 files changed

+83
-5
lines changed

2 files changed

+83
-5
lines changed
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
name: Publish images
2+
3+
on:
4+
push:
5+
branches:
6+
- release
7+
paths:
8+
- "**/*.go"
9+
- go.mod
10+
11+
concurrency:
12+
group: ${{ github.workflow }}-${{ github.ref }}
13+
cancel-in-progress: false
14+
15+
jobs:
16+
push-images:
17+
runs-on: ubuntu-latest
18+
steps:
19+
- name: Checkout
20+
uses: actions/checkout@v4
21+
with:
22+
fetch-depth: 0
23+
- name: Set up Go
24+
uses: actions/setup-go@v5
25+
with:
26+
go-version: "1.23"
27+
- name: Log in to the Container registry
28+
uses: ko-build/setup-ko@v0.8
29+
- name: Build & Push images
30+
env:
31+
REGISTRY: ghcr.io/ti-community-infra/prow
32+
run: |
33+
make push-images REGISTRY=${REGISTRY}

cmd/external-plugins/cherrypicker/server.go

Lines changed: 50 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ import (
3131

3232
utilerrors "k8s.io/apimachinery/pkg/util/errors"
3333
"k8s.io/apimachinery/pkg/util/sets"
34+
"k8s.io/utils/exec"
3435
cherrypicker "sigs.k8s.io/prow/cmd/external-plugins/cherrypicker/lib"
3536
"sigs.k8s.io/prow/pkg/config"
3637
"sigs.k8s.io/prow/pkg/git/v2"
@@ -52,7 +53,6 @@ type githubClient interface {
5253
AddLabel(org, repo string, number int, label string) error
5354
AssignIssue(org, repo string, number int, logins []string) error
5455
CreateComment(org, repo string, number int, comment string) error
55-
CreateFork(org, repo string) (string, error)
5656
CreatePullRequest(org, repo, title, body, head, base string, canModify bool) (int, error)
5757
CreateIssue(org, repo, title, body string, milestone int, labels, assignees []string) (int, error)
5858
EnsureFork(forkingUser, org, repo string) (string, error)
@@ -89,6 +89,9 @@ type Server struct {
8989
botUser *github.UserData
9090
email string
9191

92+
// skip to fork the repo
93+
skipFork bool
94+
9295
gc git.ClientFactory
9396
// Used for unit testing
9497
push func(forkName, newBranch string, force bool) error
@@ -471,7 +474,7 @@ func (s *Server) handle(logger logrus.FieldLogger, requester string, comment *gi
471474
startClone := time.Now()
472475
r, err := s.gc.ClientFor(org, repo)
473476
if err != nil {
474-
return fmt.Errorf("failed to get git client for %s/%s: %w", org, forkName, err)
477+
return fmt.Errorf("failed to get git client for %s/%s: %w", org, repo, err)
475478
}
476479
defer func() {
477480
if err := r.Clean(); err != nil {
@@ -531,9 +534,8 @@ func (s *Server) handle(logger logrus.FieldLogger, requester string, comment *gi
531534
titleTargetBranchIndicator := fmt.Sprintf(titleTargetBranchIndicatorTemplate, targetBranch)
532535
title = fmt.Sprintf("%s%s", titleTargetBranchIndicator, omitBaseBranchFromTitle(title, baseBranch))
533536

534-
// Apply the patch.
535-
if err := r.Am(localPath); err != nil {
536-
errs := []error{fmt.Errorf("failed to `git am`: %w", err)}
537+
if err := s.applyToBranch(r, org, repo, localPath, num); err != nil {
538+
errs := []error{fmt.Errorf("failed to cherry-pick: %w", err)}
537539
logger.WithError(err).Warn("failed to apply PR on top of target branch")
538540
resp := fmt.Sprintf("#%d failed to apply on top of branch %q:\n```\n%v\n```", num, targetBranch, err)
539541
if err := s.createComment(logger, org, repo, num, comment, resp); err != nil {
@@ -551,6 +553,11 @@ func (s *Server) handle(logger logrus.FieldLogger, requester string, comment *gi
551553
}
552554

553555
push := r.PushToNamedFork
556+
if s.skipFork {
557+
push = func(_ string, branch string, force bool) error {
558+
return r.PushToCentral(branch, force)
559+
}
560+
}
554561
if s.push != nil {
555562
push = s.push
556563
}
@@ -581,6 +588,11 @@ func (s *Server) handle(logger logrus.FieldLogger, requester string, comment *gi
581588
if err := s.createComment(logger, org, repo, num, comment, resp); err != nil {
582589
return fmt.Errorf("failed to create comment: %w", err)
583590
}
591+
592+
// TODO:
593+
// - Copying original pull request labels.
594+
// - Add picked label.
595+
584596
for _, label := range s.labels {
585597
if err := s.ghc.AddLabel(org, repo, createdNum, label); err != nil {
586598
return fmt.Errorf("failed to add label %s: %w", label, err)
@@ -598,6 +610,35 @@ func (s *Server) handle(logger logrus.FieldLogger, requester string, comment *gi
598610
return nil
599611
}
600612

613+
func (s *Server) applyToBranch(r git.RepoClient, org, repo, localPath string, num int) error {
614+
var errs []error
615+
616+
// try to apply the patch using git am.
617+
{
618+
err := r.Am(localPath)
619+
if err == nil {
620+
return nil
621+
}
622+
errs = append(errs, fmt.Errorf("[try 1] failed to `git am`: %w", err))
623+
}
624+
// try to cherry-pick the merge commit
625+
{
626+
pr, err := s.ghc.GetPullRequest(org, repo, num)
627+
if err != nil {
628+
return fmt.Errorf("[try 2] failed to get pull request %s/%s#%d: %w", org, repo, num, err)
629+
}
630+
cherrypickCmd := exec.New().Command("git", "cherry-pick", "-m", "1", "--cleanup=verbatim", *pr.MergeSHA)
631+
cherrypickCmd.SetDir(r.Directory())
632+
out, err := cherrypickCmd.CombinedOutput()
633+
if err == nil {
634+
return nil
635+
}
636+
errs = append(errs, fmt.Errorf("[try 2] Failed to cherry-pick: %v\n```\n%v\n```", err, string(out)))
637+
}
638+
639+
return utilerrors.NewAggregate(errs)
640+
}
641+
601642
// omitBaseBranchFromTitle returns the title without the base branch's
602643
// indicator, if there is one. We do this to avoid long cherry-pick titles when
603644
// doing a backport of a backport.
@@ -646,6 +687,10 @@ func (s *Server) createIssue(l logrus.FieldLogger, org, repo, title, body string
646687

647688
// ensureForkExists ensures a fork of org/repo exists for the bot.
648689
func (s *Server) ensureForkExists(org, repo string) (string, error) {
690+
if s.skipFork {
691+
return repo, nil
692+
}
693+
649694
fork := s.botUser.Login + "/" + repo
650695

651696
// fork repo if it doesn't exist

0 commit comments

Comments
 (0)