Skip to content

Commit 0978c6e

Browse files
authored
Added updateBranch command (#4)
* added updateBranch command
1 parent a4b3127 commit 0978c6e

File tree

9 files changed

+93
-55
lines changed

9 files changed

+93
-55
lines changed

.github/workflows/release.yml

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@ name: Create and publish a Docker image
22

33
on:
44
push:
5-
tags:
5+
branches:
6+
- "!main"
7+
- "*"
8+
tags:
69
- "v*.*.*"
710

811
env:
@@ -42,7 +45,7 @@ jobs:
4245
uses: docker/setup-buildx-action@v1
4346

4447
- name: Cache Docker layers
45-
uses: actions/cache@v2
48+
uses: actions/cache@v4
4649
with:
4750
path: /tmp/.buildx-cache
4851
key: ${{ runner.os }}-buildx-${{ github.sha }}

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
### Commands
1313
- !merge
1414
- !check
15+
- !update
1516

1617
### Setup
1718
1. Invite bot ([@mergeapprovebot](https://gitlab.com/mergeapprovebot)) in your repository as **maintainer** (you can revoke permissions from usual developers in order to prevent merging)

bot.go

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,7 @@ func Handler(c echo.Context) error {
4545
return err
4646
}
4747

48-
err = hook.ParseRequest(c.Request())
49-
if err != nil {
48+
if err = hook.ParseRequest(c.Request()); err != nil {
5049
slog.Error("ParseRequest", "err", err)
5150
return err
5251
}
@@ -55,8 +54,7 @@ func Handler(c echo.Context) error {
5554

5655
if f, ok := handlerFuncs[hook.Event]; ok {
5756
go func() {
58-
err := f(providerName, hook)
59-
if err != nil {
57+
if err := f(providerName, hook); err != nil {
6058
slog.Error("handlerFunc", "err", err)
6159
}
6260
}()
@@ -71,8 +69,7 @@ var (
7169

7270
func handle(onEvent string, funcHandler func(string, *webhook.Webhook) error) {
7371
handlerFuncs[onEvent] = func(provider string, hook *webhook.Webhook) error {
74-
err := funcHandler(provider, hook)
75-
if err != nil {
72+
if err := funcHandler(provider, hook); err != nil {
7673
// metrics.CommandFailedInc(hook.GetCmd(), provider)
7774
return err
7875
}

commands.go

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,19 +9,32 @@ import (
99
func init() {
1010
handle("!merge", MergeCmd)
1111
handle("!check", CheckCmd)
12+
handle("!update", UpdateBranchCmd)
1213
handle(webhook.OnNewMR, NewMR)
1314
}
1415

16+
func UpdateBranchCmd(providerName string, hook *webhook.Webhook) error {
17+
command, err := handlers.New(providerName)
18+
if err != nil {
19+
return err
20+
}
21+
22+
if err := command.UpdateFromMaster(hook.GetProjectID(), hook.GetID()); err != nil {
23+
slog.Error("updateBranchCmd", "error", err)
24+
return command.LeaveComment(hook.GetProjectID(), hook.GetID(), "❌ i couldn't update branch from master")
25+
}
26+
27+
return err
28+
}
29+
1530
func MergeCmd(providerName string, hook *webhook.Webhook) error {
1631
command, err := handlers.New(providerName)
1732
if err != nil {
18-
slog.Error("command merge", "err", err)
1933
return err
2034
}
2135

2236
ok, text, err := command.Merge(hook.GetProjectID(), hook.GetID())
2337
if err != nil {
24-
slog.Error("command merge", "err", err)
2538
return err
2639
}
2740

@@ -34,13 +47,11 @@ func MergeCmd(providerName string, hook *webhook.Webhook) error {
3447
func CheckCmd(providerName string, hook *webhook.Webhook) error {
3548
command, err := handlers.New(providerName)
3649
if err != nil {
37-
slog.Error("command merge", "err", err)
3850
return err
3951
}
4052

4153
ok, text, err := command.IsValid(hook.GetProjectID(), hook.GetID())
4254
if err != nil {
43-
slog.Error("command check", "err", err)
4455
return err
4556
}
4657

@@ -54,13 +65,10 @@ func CheckCmd(providerName string, hook *webhook.Webhook) error {
5465
func NewMR(providerName string, hook *webhook.Webhook) error {
5566
command, err := handlers.New(providerName)
5667
if err != nil {
57-
slog.Error("new mr", "err", err)
5868
return err
5969
}
6070

61-
err = command.Greetings(hook.GetProjectID(), hook.GetID())
62-
if err != nil {
63-
slog.Error("new mr", "err", err)
71+
if err = command.Greetings(hook.GetProjectID(), hook.GetID()); err != nil {
6472
return err
6573
}
6674

docker-compose.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,15 @@ services:
44
bot:
55
image: ghcr.io/gasoid/merge-bot:latest
66
restart: always
7+
volumes:
8+
- tls-cache:/tmp/tls/.cache
79
ports:
810
- "443:443"
911
- "8080:8080"
1012
env_file:
1113
- bot.env
1214
logging:
1315
driver: syslog
16+
17+
volumes:
18+
tls-cache:

handlers/gitlab/gitlab.go

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,7 @@ func (g *GitlabProvider) loadMR(projectId, mergeId int) error {
4040
}
4141

4242
func (g *GitlabProvider) UpdateFromMaster(projectId, mergeId int) error {
43-
err := g.loadMR(projectId, mergeId)
44-
if err != nil {
43+
if err := g.loadMR(projectId, mergeId); err != nil {
4544
return err
4645
}
4746

@@ -54,8 +53,13 @@ func (g *GitlabProvider) UpdateFromMaster(projectId, mergeId int) error {
5453
return handlers.RepoSizeError
5554
}
5655

57-
err = handlers.MergeMaster(tokenUsername, os.Getenv(gitlabToken), project.HTTPURLToRepo, g.mr.SourceBranch, g.mr.TargetBranch)
58-
if err != nil {
56+
if err = handlers.MergeMaster(
57+
tokenUsername,
58+
os.Getenv(gitlabToken),
59+
project.HTTPURLToRepo,
60+
g.mr.SourceBranch,
61+
g.mr.TargetBranch,
62+
); err != nil {
5963
return err
6064
}
6165

@@ -122,8 +126,7 @@ func (g *GitlabProvider) GetFailedPipelines() (int, error) {
122126
}
123127

124128
func (g *GitlabProvider) IsValid(projectId, mergeId int) (bool, error) {
125-
err := g.loadMR(projectId, mergeId)
126-
if err != nil {
129+
if err := g.loadMR(projectId, mergeId); err != nil {
127130
return false, err
128131
}
129132

handlers/merge.go

Lines changed: 36 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
package handlers
22

33
import (
4-
"crypto/md5"
5-
"encoding/hex"
6-
"errors"
4+
"fmt"
75
"log/slog"
86
"net/url"
97
"os"
108

9+
"github.com/ldez/go-git-cmd-wrapper/v2/checkout"
1110
"github.com/ldez/go-git-cmd-wrapper/v2/clone"
11+
"github.com/ldez/go-git-cmd-wrapper/v2/config"
1212
"github.com/ldez/go-git-cmd-wrapper/v2/git"
1313
"github.com/ldez/go-git-cmd-wrapper/v2/merge"
1414
"github.com/ldez/go-git-cmd-wrapper/v2/push"
@@ -22,38 +22,55 @@ func MergeMaster(username, password, repoUrl, branchName, master string) error {
2222
if username != "" && password != "" {
2323
parsedUrl, err := url.Parse(repoUrl)
2424
if err != nil {
25-
slog.Error("url.Parse", "err", err)
2625
return err
2726
}
2827
parsedUrl.User = url.UserPassword(username, password)
2928
repoUrl = parsedUrl.String()
3029
}
3130

32-
hasher := md5.New()
33-
hasher.Write([]byte(repoUrl))
34-
dir := hex.EncodeToString(hasher.Sum([]byte(branchName)))
35-
36-
if _, err := os.Stat(dir); !os.IsNotExist(err) {
37-
return errors.New("directory exists")
31+
dir, err := os.MkdirTemp("", "merge-bot")
32+
if err != nil {
33+
slog.Debug("temp dir error")
34+
return err
3835
}
3936

4037
defer os.RemoveAll(dir)
4138

42-
_, err := git.Clone(clone.Repository(repoUrl), clone.Branch(branchName), clone.Directory(dir))
43-
if err != nil {
44-
slog.Error("git.Clone", "err", err)
39+
if _, err := git.Clone(clone.Repository(repoUrl), clone.Directory(dir)); err != nil {
40+
slog.Debug("git clone error", "dir", dir)
4541
return err
4642
}
4743

48-
_, err = git.Merge(merge.NoFf, merge.Commits(master))
49-
if err != nil {
50-
slog.Error("git.Merge", "err", err)
44+
if err := os.Chdir(dir); err != nil {
45+
slog.Debug("chdir error")
5146
return err
5247
}
5348

54-
_, err = git.Push(push.Remote(defaultRemote))
55-
if err != nil {
56-
slog.Error("git.Push", "err", err)
49+
if _, err := git.Config(config.Entry("user.email", fmt.Sprintf("%s@localhost", username))); err != nil {
50+
slog.Debug("git config error", "user.email", fmt.Sprintf("%s@localhost", username))
51+
return err
52+
}
53+
54+
if _, err := git.Config(config.Entry("user.name", username)); err != nil {
55+
slog.Debug("git config error", "user.name", username)
56+
return err
57+
}
58+
59+
if _, err := git.Checkout(checkout.Branch(branchName)); err != nil {
60+
slog.Debug("git checkout error", "branch", branchName)
61+
return err
62+
}
63+
64+
if _, err := git.Merge(merge.Commits(master), merge.M("update from master")); err != nil {
65+
slog.Debug("git merge error")
66+
if _, err := git.Merge(merge.NoFf, merge.Commits(master), merge.M("update from master")); err != nil {
67+
slog.Debug("git merge --noff error")
68+
return err
69+
}
70+
}
71+
72+
if _, err := git.Push(push.Remote(defaultRemote), push.RefSpec(branchName)); err != nil {
73+
slog.Debug("git push error")
5774
return err
5875
}
5976

handlers/request.go

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,7 @@ func (r *Request) LoadInfoAndConfig(projectId, id int) error {
3131
}
3232

3333
func (r *Request) IsValid(projectId, id int) (bool, string, error) {
34-
err := r.LoadInfoAndConfig(projectId, id)
35-
if err != nil {
34+
if err := r.LoadInfoAndConfig(projectId, id); err != nil {
3635
return false, "", err
3736
}
3837

@@ -69,8 +68,7 @@ func (r *Request) ParseConfig(content string) (*Config, error) {
6968
AutoMasterMerge: false,
7069
}
7170

72-
err := yaml.Unmarshal([]byte(content), mrConfig)
73-
if err != nil {
71+
if err := yaml.Unmarshal([]byte(content), mrConfig); err != nil {
7472
return nil, err
7573
}
7674
return mrConfig, nil
@@ -81,8 +79,7 @@ func (r *Request) LeaveComment(projectId, id int, message string) error {
8179
}
8280

8381
func (r *Request) Greetings(projectId, id int) error {
84-
err := r.LoadInfoAndConfig(projectId, id)
85-
if err != nil {
82+
if err := r.LoadInfoAndConfig(projectId, id); err != nil {
8683
return err
8784
}
8885

@@ -92,17 +89,15 @@ func (r *Request) Greetings(projectId, id int) error {
9289
}
9390

9491
buf := &bytes.Buffer{}
95-
err = tmpl.Execute(buf, r.config)
96-
if err != nil {
92+
if err = tmpl.Execute(buf, r.config); err != nil {
9793
return err
9894
}
9995

10096
return r.LeaveComment(projectId, id, buf.String())
10197
}
10298

10399
func (r *Request) Merge(projectId, id int) (bool, string, error) {
104-
err := r.LoadInfoAndConfig(projectId, id)
105-
if err != nil {
100+
if err := r.LoadInfoAndConfig(projectId, id); err != nil {
106101
return false, "", err
107102
}
108103

@@ -112,12 +107,22 @@ func (r *Request) Merge(projectId, id int) (bool, string, error) {
112107
}
113108

114109
if ok, text, err := r.IsValid(projectId, id); ok {
115-
err := r.provider.Merge(projectId, id, fmt.Sprintf("%s\nMerged by MergeApproveBot", r.info.Title))
116-
if err != nil {
110+
if err := r.provider.Merge(projectId, id, fmt.Sprintf("%s\nMerged by MergeApproveBot", r.info.Title)); err != nil {
117111
return false, "", err
118112
}
119113
return true, "", nil
120114
} else {
121115
return false, text, err
122116
}
123117
}
118+
119+
func (r *Request) UpdateFromMaster(projectId, id int) error {
120+
if err := r.LoadInfoAndConfig(projectId, id); err != nil {
121+
return err
122+
}
123+
124+
if err := r.provider.UpdateFromMaster(projectId, id); err != nil {
125+
return err
126+
}
127+
return nil
128+
}

webhook/webhook.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,7 @@ func (w *Webhook) ParseRequest(request *http.Request) error {
6666
return &Error{text: "Request is not provided"}
6767
}
6868

69-
err := w.provider.ParseRequest(request)
70-
if err != nil {
69+
if err := w.provider.ParseRequest(request); err != nil {
7170
return err
7271
}
7372

0 commit comments

Comments
 (0)