Skip to content

Commit

Permalink
Add tag command.
Browse files Browse the repository at this point in the history
  • Loading branch information
Gerrit91 committed Feb 27, 2024
1 parent d2d921b commit eb2e20a
Show file tree
Hide file tree
Showing 4 changed files with 131 additions and 22 deletions.
45 changes: 45 additions & 0 deletions pkg/git/git.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,51 @@ func DeleteBranch(repoURL, branch string) error {
return nil
}

func CreateTag(repoURL, branch, tag string) error {
r, err := git.Clone(memory.NewStorage(), memfs.New(), &git.CloneOptions{
URL: repoURL,
Depth: 1,
})
if err != nil {
return fmt.Errorf("error cloning git repo %w", err)
}

w, err := r.Worktree()
if err != nil {
return fmt.Errorf("error retrieving git worktree %w", err)
}

err = w.Checkout(&git.CheckoutOptions{
Branch: plumbing.ReferenceName(defaultLocalRef + "/" + branch),
Force: true,
})
if err != nil {
return fmt.Errorf("error during git checkout %w", err)
}

head, err := r.Head()
if err != nil {
return fmt.Errorf("error finding head %w", err)
}

_, err = r.CreateTag(tag, head.Hash(), &git.CreateTagOptions{})
if err != nil {
return fmt.Errorf("error creating tag %w", err)
}

err = r.Push(&git.PushOptions{
RemoteName: "origin",
RefSpecs: []config.RefSpec{
config.RefSpec("refs/tags/*:refs/tags/*"),
},
})
if err != nil {
return fmt.Errorf("error pushing to repo %w", err)
}

return nil
}

func CommitAndPush(r *git.Repository, msg string) (string, error) {
w, err := r.Worktree()
if err != nil {
Expand Down
4 changes: 2 additions & 2 deletions pkg/webhooks/github/actions/aggregate_releases.go
Original file line number Diff line number Diff line change
Expand Up @@ -249,11 +249,11 @@ func isReleaseFreeze(ctx context.Context, client *v3.Client, number int, owner,
for _, comment := range comments {
comment := comment

if ok := searchForCommandInBody(pointer.SafeDeref(comment.Body), IssueCommentReleaseFreeze); ok {
if _, ok := searchForCommandInBody(pointer.SafeDeref(comment.Body), IssueCommentReleaseFreeze); ok {
return true, nil
}

if ok := searchForCommandInBody(pointer.SafeDeref(comment.Body), IssueCommentReleaseUnfreeze); ok {
if _, ok := searchForCommandInBody(pointer.SafeDeref(comment.Body), IssueCommentReleaseUnfreeze); ok {
return false, nil
}
}
Expand Down
58 changes: 53 additions & 5 deletions pkg/webhooks/github/actions/issues_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,15 @@ const (
IssueCommentBuildFork IssueCommentCommand = IssueCommentCommandPrefix + "ok-to-build"
IssueCommentReleaseFreeze IssueCommentCommand = IssueCommentCommandPrefix + "freeze"
IssueCommentReleaseUnfreeze IssueCommentCommand = IssueCommentCommandPrefix + "unfreeze"
IssueCommentTag IssueCommentCommand = IssueCommentCommandPrefix + "tag"
)

var (
IssueCommentCommands = map[IssueCommentCommand]bool{
IssueCommentBuildFork: true,
IssueCommentReleaseFreeze: true,
IssueCommentReleaseUnfreeze: true,
IssueCommentTag: true,
}

AllowedAuthorAssociations = map[string]bool{
Expand Down Expand Up @@ -84,13 +86,20 @@ func (r *IssuesAction) HandleIssueComment(ctx context.Context, p *IssuesActionPa
return nil
}

if ok := searchForCommandInBody(p.Comment, IssueCommentBuildFork); ok {
if _, ok := searchForCommandInBody(p.Comment, IssueCommentBuildFork); ok {
err := r.buildForkPR(ctx, p)
if err != nil {
return err
}
}

if args, ok := searchForCommandInBody(p.Comment, IssueCommentTag); ok {
err := r.tag(ctx, p, args)
if err != nil {
return err
}
}

return nil
}

Expand Down Expand Up @@ -138,21 +147,60 @@ func (r *IssuesAction) buildForkPR(ctx context.Context, p *IssuesActionParams) e
return nil
}

func searchForCommandInBody(comment string, want IssueCommentCommand) bool {
func (r *IssuesAction) tag(ctx context.Context, p *IssuesActionParams, args []string) error {
if len(args) == 0 {
return fmt.Errorf("no tag name given, skipping")
}

tag := args[0]

pullRequest, _, err := r.client.GetV3Client().PullRequests.Get(ctx, r.client.Organization(), p.RepositoryName, p.PullRequestNumber)
if err != nil {
return fmt.Errorf("error finding issue related pull request %w", err)
}

token, err := r.client.GitToken(ctx)
if err != nil {
return fmt.Errorf("error creating git token %w", err)
}

targetRepoURL, err := url.Parse(p.RepositoryURL)
if err != nil {
return err
}
targetRepoURL.User = url.UserPassword("x-access-token", token)

headRef := *pullRequest.Head.Ref
err = git.CreateTag(p.RepositoryURL, headRef, tag)
if err != nil {
return err
}

r.logger.Infow("pushed tag to repo", "repo", p.RepositoryName, "branch", headRef, "tag", tag)

return nil
}

func searchForCommandInBody(comment string, want IssueCommentCommand) ([]string, bool) {
for _, line := range strings.Split(comment, "\n") {
line = strings.TrimSpace(line)

cmd := IssueCommentCommand(line)
fields := strings.Fields(line)
if len(fields) == 0 {
continue
}

cmd, args := IssueCommentCommand(fields[0]), fields[1:]

_, ok := IssueCommentCommands[cmd]
if !ok {
continue
}

if cmd == want {
return true
return args, true
}
}

return false
return nil, false
}
46 changes: 31 additions & 15 deletions pkg/webhooks/github/actions/issues_handler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,18 @@ import (

func Test_searchForCommandInBody(t *testing.T) {
tests := []struct {
name string
body string
search IssueCommentCommand
want bool
name string
body string
search IssueCommentCommand
want bool
wantArgs []string
}{
{
name: "find in single line",
body: "/freeze",
search: IssueCommentReleaseFreeze,
want: true,
name: "find in single line",
body: "/freeze",
search: IssueCommentReleaseFreeze,
want: true,
wantArgs: []string{},
},
{
name: "no match",
Expand All @@ -26,26 +28,40 @@ func Test_searchForCommandInBody(t *testing.T) {
want: false,
},
{
name: "find with strip",
body: " /freeze ",
search: IssueCommentReleaseFreeze,
want: true,
name: "find with strip",
body: " /freeze ",
search: IssueCommentReleaseFreeze,
want: true,
wantArgs: []string{},
},
{
name: "find in multi line",
body: `Release is frozen now.
/freeze
`,
search: IssueCommentReleaseFreeze,
want: true,
search: IssueCommentReleaseFreeze,
want: true,
wantArgs: []string{},
},
{
name: "with args",
body: `Tagging.
/tag v0.1.17-rc.0
`,
search: IssueCommentTag,
want: true,
wantArgs: []string{"v0.1.17-rc.0"},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := searchForCommandInBody(tt.body, tt.search)
gotArgs, got := searchForCommandInBody(tt.body, tt.search)
if diff := cmp.Diff(got, tt.want); diff != "" {
t.Errorf("diff: %s", diff)
}
if diff := cmp.Diff(gotArgs, tt.wantArgs); diff != "" {
t.Errorf("diff: %s", diff)
}
})
}
}

0 comments on commit eb2e20a

Please sign in to comment.