Skip to content

Commit e7504dc

Browse files
authored
support auto_merge_strategy option (#1922)
* support auto_merge_strategy option * address review errors * fix build
1 parent ceae074 commit e7504dc

File tree

19 files changed

+76
-36
lines changed

19 files changed

+76
-36
lines changed

backend/controllers/projects.go

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -729,20 +729,22 @@ func AutomergePRforBatchIfEnabled(gh utils.GithubClientProvider, batch *models.D
729729
log.Printf("Error loading digger config from batch: %v", err)
730730
return fmt.Errorf("error loading digger config from batch: %v", err)
731731
}
732-
733-
var automerge bool
734-
if diggerConfigYml.AutoMerge != nil {
735-
automerge = *diggerConfigYml.AutoMerge
736-
} else {
737-
automerge = false
732+
config, _, err := digger_config.ConvertDiggerYamlToConfig(diggerConfigYml)
733+
if err != nil {
734+
log.Printf("Error loading digger config from yaml: %v", err)
735+
return fmt.Errorf("error loading digger config from yaml: %v", err)
738736
}
737+
738+
automerge := config.AutoMerge
739+
automergeStrategy := config.AutoMergeStrategy
740+
739741
if batch.Status == orchestrator_scheduler.BatchJobSucceeded && batch.BatchType == orchestrator_scheduler.DiggerCommandApply && automerge == true {
740742
prService, err := GetPrServiceFromBatch(batch, gh)
741743
if err != nil {
742744
log.Printf("Error getting github service: %v", err)
743745
return fmt.Errorf("error getting github service: %v", err)
744746
}
745-
err = prService.MergePullRequest(batch.PrNumber)
747+
err = prService.MergePullRequest(batch.PrNumber, string(automergeStrategy))
746748
if err != nil {
747749
log.Printf("Error merging pull request: %v", err)
748750
return fmt.Errorf("error merging pull request: %v", err)

cli/pkg/digger/digger.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -791,7 +791,7 @@ func SortedCommandsByDependency(project []orchestrator.Job, dependencyGraph *gra
791791
return sortedCommands
792792
}
793793

794-
func MergePullRequest(ciService ci.PullRequestService, prNumber int) {
794+
func MergePullRequest(ciService ci.PullRequestService, prNumber int, mergeStrategy config.AutomergeStrategy) {
795795
time.Sleep(5 * time.Second)
796796

797797
// CheckAccessPolicy if it was manually merged
@@ -821,7 +821,7 @@ func MergePullRequest(ciService ci.PullRequestService, prNumber int) {
821821
log.Fatalf("PR is not mergeable")
822822
}
823823

824-
err = ciService.MergePullRequest(prNumber)
824+
err = ciService.MergePullRequest(prNumber, string(mergeStrategy))
825825
if err != nil {
826826
log.Fatalf("failed to merge PR, %v", err)
827827
}

cli/pkg/digger/digger_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ func (m *MockPRManager) GetCombinedPullRequestStatus(prNumber int) (string, erro
113113
return "", nil
114114
}
115115

116-
func (m *MockPRManager) MergePullRequest(prNumber int) error {
116+
func (m *MockPRManager) MergePullRequest(prNumber int, mergeStrategy string) error {
117117
m.Commands = append(m.Commands, RunInfo{"MergePullRequest", strconv.Itoa(prNumber), time.Now()})
118118
return nil
119119
}

cli/pkg/github/github.go

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -175,18 +175,17 @@ func GitHubCI(lock core_locking.Lock, policyCheckerProvider core_policy.PolicyCh
175175

176176
StateEnvProvider, CommandEnvProvider := scheduler.GetStateAndCommandProviders(projectConfig)
177177

178-
stateArn, cmdArn := "",""
179-
if(projectConfig.AwsRoleToAssume != nil) {
178+
stateArn, cmdArn := "", ""
179+
if projectConfig.AwsRoleToAssume != nil {
180180
if projectConfig.AwsRoleToAssume.State != "" {
181181
stateArn = projectConfig.AwsRoleToAssume.State
182182
}
183183

184184
if projectConfig.AwsRoleToAssume.Command != "" {
185-
cmdArn = projectConfig.AwsRoleToAssume.Command
185+
cmdArn = projectConfig.AwsRoleToAssume.Command
186186
}
187187
}
188188

189-
190189
job := scheduler.Job{
191190
ProjectName: projectConfig.Name,
192191
ProjectDir: projectConfig.Dir,
@@ -204,8 +203,8 @@ func GitHubCI(lock core_locking.Lock, policyCheckerProvider core_policy.PolicyCh
204203
EventName: "drift-detect",
205204
StateEnvProvider: StateEnvProvider,
206205
CommandEnvProvider: CommandEnvProvider,
207-
StateRoleArn: stateArn,
208-
CommandRoleArn: cmdArn,
206+
StateRoleArn: stateArn,
207+
CommandRoleArn: cmdArn,
209208
}
210209

211210
notification, err := driftNotificationProvider.Get(githubPrService)
@@ -303,7 +302,7 @@ func GitHubCI(lock core_locking.Lock, policyCheckerProvider core_policy.PolicyCh
303302
}
304303

305304
if diggerConfig.AutoMerge && allAppliesSuccessful && atLeastOneApply && coversAllImpactedProjects {
306-
digger.MergePullRequest(&githubPrService, prNumber)
305+
digger.MergePullRequest(&githubPrService, prNumber, diggerConfig.AutoMergeStrategy)
307306
log.Println("PR merged successfully")
308307
}
309308

docs/ce/howto/auto-merge.mdx

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,12 @@ projects:
1111
- name: production
1212
dir: prod
1313
auto_merge: true
14+
auto_merge_strategy: "squash" # optional, only supported on github
1415
```
16+
17+
If you are using github VCS you can also specify
18+
`auto_merge_strategy` to define the type of strategy. Possible values are:
19+
20+
- squash: for squash merge
21+
- rebase: for rebase merge
22+
- merge: for merge commits merge

docs/ce/reference/digger.yml.mdx

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -98,15 +98,16 @@ workflows:
9898

9999
### Top-level
100100

101-
| Key | Type | Default | Required | Description | Notes |
102-
| --------------------------- | ---------------------------------------------------------- | ------- | -------- | ------------------------------------------------------ | ----- |
103-
| telemetry | boolean | true | no | allows collecting anonymised usage and debugging data | |
104-
| auto_merge | boolean | false | no | automatically merge pull requests when all checks pass | |
105-
| pr_locks | boolean | true | no | Enable PR-level locking | |
106-
| projects | array of [Projects](/ce/reference/digger.yml#project) | \[\] | no | list of projects to manage | |
107-
| generate_projects | [GenerateProjects](/ce/reference/digger.yml#generateprojects) | {} | no | generate projects from a directory structure | |
108-
| workflows | map of [Workflows](/ce/reference/digger.yml#workflows) | {} | no | workflows and configurations to run on events | |
109-
| traverse_to_nested_projects | boolean | false | no | enabled traversal of nested directories | |
101+
| Key | Type | Default | Required | Description | Notes |
102+
|-----------------------------|---------------------------------------------------------------|----------|----------|----------------------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------|
103+
| telemetry | boolean | true | no | allows collecting anonymised usage and debugging data | |
104+
| auto_merge | boolean | false | no | automatically merge pull requests when all checks pass | |
105+
| auto_merge_strategy | string | "squash" | no | The merge strategy to use while automerging, defaults to "squash". Possible values: 'squash', 'merge' (for merge commits) and 'rebase' | currently only github supported for this flag |
106+
| pr_locks | boolean | true | no | Enable PR-level locking | |
107+
| projects | array of [Projects](/ce/reference/digger.yml#project) | \[\] | no | list of projects to manage | |
108+
| generate_projects | [GenerateProjects](/ce/reference/digger.yml#generateprojects) | {} | no | generate projects from a directory structure | |
109+
| workflows | map of [Workflows](/ce/reference/digger.yml#workflows) | {} | no | workflows and configurations to run on events | |
110+
| traverse_to_nested_projects | boolean | false | no | enabled traversal of nested directories | |
110111

111112
### Project
112113

libs/ci/azure/azure.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -273,7 +273,7 @@ func (a *AzureReposService) GetCombinedPullRequestStatus(prNumber int) (string,
273273
return "pending", nil
274274
}
275275

276-
func (a *AzureReposService) MergePullRequest(prNumber int) error {
276+
func (a *AzureReposService) MergePullRequest(prNumber int, mergeStrategy string) error {
277277
pullRequest, err := a.Client.GetPullRequestById(context.Background(), git.GetPullRequestByIdArgs{
278278
Project: &a.ProjectName,
279279
PullRequestId: &prNumber,

libs/ci/bitbucket/bitbucket.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -381,7 +381,7 @@ func (b BitbucketAPI) GetCombinedPullRequestStatus(prNumber int) (string, error)
381381

382382
}
383383

384-
func (b BitbucketAPI) MergePullRequest(prNumber int) error {
384+
func (b BitbucketAPI) MergePullRequest(prNumber int, mergeStrategy string) error {
385385
url := fmt.Sprintf("%s/repositories/%s/%s/pullrequests/%d/merge", bitbucketBaseURL, b.RepoWorkspace, b.RepoName, prNumber)
386386

387387
resp, err := b.sendRequest("POST", url, nil)

libs/ci/ci.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ type PullRequestService interface {
1515
// SetStatus set status of specified pull/merge request, status could be: "pending", "failure", "success"
1616
SetStatus(prNumber int, status string, statusContext string) error
1717
GetCombinedPullRequestStatus(prNumber int) (string, error)
18-
MergePullRequest(prNumber int) error
18+
MergePullRequest(prNumber int, mergeStrategy string) error
1919
// IsMergeable is still open and ready to be merged
2020
IsMergeable(prNumber int) (bool, error)
2121
// IsMerged merged and closed

libs/ci/github/github.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -284,7 +284,7 @@ func (svc GithubService) GetCombinedPullRequestStatus(prNumber int) (string, err
284284
return *statuses.State, nil
285285
}
286286

287-
func (svc GithubService) MergePullRequest(prNumber int) error {
287+
func (svc GithubService) MergePullRequest(prNumber int, mergeStrategy string) error {
288288
isPullRequest, err := svc.IsPullRequest(prNumber)
289289
if err != nil {
290290
log.Printf("error checking if PR is issue: %v", err)
@@ -314,7 +314,7 @@ func (svc GithubService) MergePullRequest(prNumber int) error {
314314
}
315315

316316
_, _, err = svc.Client.PullRequests.Merge(context.Background(), svc.Owner, svc.RepoName, prNumber, "auto-merge", &github.PullRequestOptions{
317-
MergeMethod: "squash",
317+
MergeMethod: mergeStrategy,
318318
SHA: pr.Head.GetSHA(),
319319
})
320320
return err

libs/ci/github/mocks.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ func (t MockCiService) GetCombinedPullRequestStatus(prNumber int) (string, error
5959
return "", nil
6060
}
6161

62-
func (t MockCiService) MergePullRequest(prNumber int) error {
62+
func (t MockCiService) MergePullRequest(prNumber int, mergeStrategy string) error {
6363
return nil
6464
}
6565

libs/ci/gitlab/gitlab.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,7 @@ func (gitlabService GitLabService) GetCombinedPullRequestStatus(mergeRequestID i
215215
return "success", nil
216216
}
217217

218-
func (gitlabService GitLabService) MergePullRequest(mergeRequestID int) error {
218+
func (gitlabService GitLabService) MergePullRequest(mergeRequestID int, mergeStrategy string) error {
219219
projectId := *gitlabService.Context.ProjectId
220220
mergeRequestIID := *gitlabService.Context.MergeRequestIId
221221
mergeWhenPipelineSucceeds := true

libs/ci/mocks.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ func (t MockPullRequestManager) GetApprovals(prNumber int) ([]string, error) {
4343
return t.Approvals, nil
4444
}
4545

46-
func (t MockPullRequestManager) MergePullRequest(prNumber int) error {
46+
func (t MockPullRequestManager) MergePullRequest(prNumber int, mergeStrategy string) error {
4747
return nil
4848
}
4949

libs/comment_utils/reporting/reporting_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ func (t MockCiService) GetCombinedPullRequestStatus(prNumber int) (string, error
5959
return "", nil
6060
}
6161

62-
func (t MockCiService) MergePullRequest(prNumber int) error {
62+
func (t MockCiService) MergePullRequest(prNumber int, mergeStrategy string) error {
6363
return nil
6464
}
6565

libs/digger_config/config.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,12 @@ package digger_config
33
const CommentRenderModeBasic = "basic"
44
const CommentRenderModeGroupByModule = "group_by_module"
55

6+
type AutomergeStrategy string
7+
8+
const AutomergeStrategySquash AutomergeStrategy = "squash"
9+
const AutomergeStrategyMerge AutomergeStrategy = "merge"
10+
const AutomergeStrategyRebase AutomergeStrategy = "rebase"
11+
612
type DiggerConfig struct {
713
ApplyAfterMerge bool
814
AllowDraftPRs bool
@@ -11,6 +17,7 @@ type DiggerConfig struct {
1117
PrLocks bool
1218
Projects []Project
1319
AutoMerge bool
20+
AutoMergeStrategy AutomergeStrategy
1421
Telemetry bool
1522
Workflows map[string]Workflow
1623
MentionDriftedProjectsInPR bool

libs/digger_config/converters.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,16 @@ func ConvertDiggerYamlToConfig(diggerYaml *DiggerConfigYaml) (*DiggerConfig, gra
209209
diggerConfig.AutoMerge = false
210210
}
211211

212+
if diggerYaml.AutoMergeStrategy != nil {
213+
err := ValidateAutomergeStrategy(*diggerYaml.AutoMergeStrategy)
214+
if err != nil {
215+
return nil, nil, err
216+
}
217+
diggerConfig.AutoMergeStrategy = AutomergeStrategy(*diggerYaml.AutoMergeStrategy)
218+
} else {
219+
diggerConfig.AutoMergeStrategy = AutomergeStrategySquash
220+
}
221+
212222
if diggerYaml.ApplyAfterMerge != nil {
213223
diggerConfig.ApplyAfterMerge = *diggerYaml.ApplyAfterMerge
214224
} else {

libs/digger_config/validators.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package digger_config
2+
3+
import "fmt"
4+
5+
func ValidateAutomergeStrategy(strategy string) error {
6+
switch strategy {
7+
case string(AutomergeStrategySquash), string(AutomergeStrategyMerge), string(AutomergeStrategyRebase):
8+
return nil
9+
default:
10+
return fmt.Errorf("invalid merge strategy: %v, valid values are: %v, %v, %v", strategy, AutomergeStrategySquash, AutomergeStrategyMerge, AutomergeStrategyRebase)
11+
}
12+
}

libs/digger_config/yaml.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ type DiggerConfigYaml struct {
1313
PrLocks *bool `yaml:"pr_locks"`
1414
Projects []*ProjectYaml `yaml:"projects"`
1515
AutoMerge *bool `yaml:"auto_merge"`
16+
AutoMergeStrategy *string `yaml:"auto_merge_strategy"`
1617
CommentRenderMode *string `yaml:"comment_render_mode"`
1718
Workflows map[string]*WorkflowYaml `yaml:"workflows"`
1819
Telemetry *bool `yaml:"telemetry,omitempty"`

libs/orchestrator/mock.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ func (mockGithubPullrequestManager *MockGithubPullrequestManager) GetCombinedPul
4747
return "", nil
4848
}
4949

50-
func (mockGithubPullrequestManager *MockGithubPullrequestManager) MergePullRequest(prNumber int) error {
50+
func (mockGithubPullrequestManager *MockGithubPullrequestManager) MergePullRequest(prNumber int, mergeStrategy string) error {
5151
mockGithubPullrequestManager.commands = append(mockGithubPullrequestManager.commands, "MergePullRequest")
5252
return nil
5353
}

0 commit comments

Comments
 (0)