mirror of
https://git.vectorsigma.ru/public/atlantis.git
synced 2026-07-29 01:48:32 +00:00
Fix automerge bug in Bitbucket Server
BB Server requires we send a 'version' parameter along with our call to /merge.
This commit is contained in:
@@ -247,7 +247,7 @@ func (c *DefaultCommandRunner) automerge(ctx *CommandContext, pullStatus *models
|
||||
if err != nil {
|
||||
ctx.Log.Err("automerging failed: %s", err)
|
||||
|
||||
failureComment := fmt.Sprintf("Automerging failed: %s", err)
|
||||
failureComment := fmt.Sprintf("Automerging failed:\n```\n%s\n```", err)
|
||||
if commentErr := c.VCSClient.CreateComment(ctx.BaseRepo, ctx.Pull.Num, failureComment); commentErr != nil {
|
||||
ctx.Log.Err("failed to comment about automerge failing: %s", err)
|
||||
}
|
||||
|
||||
@@ -241,7 +241,21 @@ func (b *Client) MergePull(pull models.PullRequest) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
path := fmt.Sprintf("%s/rest/api/1.0/projects/%s/repos/%s/pull-requests/%d/merge", b.BaseURL, projectKey, pull.BaseRepo.Name, pull.Num)
|
||||
|
||||
// We need to make a get pull request API call to get the correct "version".
|
||||
path := fmt.Sprintf("%s/rest/api/1.0/projects/%s/repos/%s/pull-requests/%d", b.BaseURL, projectKey, pull.BaseRepo.Name, pull.Num)
|
||||
resp, err := b.makeRequest("GET", path, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var pullResp PullRequest
|
||||
if err := json.Unmarshal(resp, &pullResp); err != nil {
|
||||
return errors.Wrapf(err, "Could not parse response %q", string(resp))
|
||||
}
|
||||
if err := validator.New().Struct(pullResp); err != nil {
|
||||
return errors.Wrapf(err, "API response %q was missing fields", string(resp))
|
||||
}
|
||||
path = fmt.Sprintf("%s/rest/api/1.0/projects/%s/repos/%s/pull-requests/%d/merge?version=%d", b.BaseURL, projectKey, pull.BaseRepo.Name, pull.Num, *pullResp.Version)
|
||||
_, err = b.makeRequest("POST", path, nil)
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -2,13 +2,14 @@ package bitbucketserver_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/runatlantis/atlantis/server/events/models"
|
||||
"github.com/runatlantis/atlantis/server/events/vcs/bitbucketcloud"
|
||||
"github.com/runatlantis/atlantis/server/events/vcs/bitbucketserver"
|
||||
. "github.com/runatlantis/atlantis/testing"
|
||||
)
|
||||
@@ -79,39 +80,20 @@ func TestClient_GetModifiedFilesPagination(t *testing.T) {
|
||||
Equals(t, []string{"file1.txt", "file2.txt", "file3.txt"}, files)
|
||||
}
|
||||
|
||||
// If the "old" key in the list of files is nil we shouldn't error.
|
||||
func TestClient_GetModifiedFilesOldNil(t *testing.T) {
|
||||
resp := `
|
||||
{
|
||||
"pagelen": 500,
|
||||
"values": [
|
||||
{
|
||||
"status": "added",
|
||||
"old": null,
|
||||
"lines_removed": 0,
|
||||
"lines_added": 2,
|
||||
"new": {
|
||||
"path": "parent/child/file1.txt",
|
||||
"type": "commit_file",
|
||||
"links": {
|
||||
"self": {
|
||||
"href": "https://api.bitbucket.org/2.0/repositories/lkysow/atlantis-example/src/1ed8205eec00dab4f1c0a8c486a4492c98c51f8e/main.tf"
|
||||
}
|
||||
}
|
||||
},
|
||||
"type": "diffstat"
|
||||
}
|
||||
],
|
||||
"page": 1,
|
||||
"size": 1
|
||||
}`
|
||||
|
||||
// Test that we use the correct version parameter in our call to merge the pull
|
||||
// request.
|
||||
func TestClient_MergePull(t *testing.T) {
|
||||
pullRequest, err := ioutil.ReadFile(filepath.Join("testdata", "pull-request.json"))
|
||||
Ok(t, err)
|
||||
testServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
switch r.RequestURI {
|
||||
// The first request should hit this URL.
|
||||
case "/2.0/repositories/owner/repo/pullrequests/1/diffstat":
|
||||
w.Write([]byte(resp)) // nolint: errcheck
|
||||
case "/rest/api/1.0/projects/ow/repos/repo/pull-requests/1":
|
||||
w.Write(pullRequest) // nolint: errcheck
|
||||
return
|
||||
case "/rest/api/1.0/projects/ow/repos/repo/pull-requests/1/merge?version=3":
|
||||
Equals(t, "POST", r.Method)
|
||||
w.Write(pullRequest) // nolint: errcheck
|
||||
default:
|
||||
t.Errorf("got unexpected request at %q", r.RequestURI)
|
||||
http.Error(w, "not found", http.StatusNotFound)
|
||||
@@ -120,22 +102,27 @@ func TestClient_GetModifiedFilesOldNil(t *testing.T) {
|
||||
}))
|
||||
defer testServer.Close()
|
||||
|
||||
client := bitbucketcloud.NewClient(http.DefaultClient, "user", "pass", "runatlantis.io")
|
||||
client.BaseURL = testServer.URL
|
||||
client, err := bitbucketserver.NewClient(http.DefaultClient, "user", "pass", testServer.URL, "runatlantis.io")
|
||||
Ok(t, err)
|
||||
|
||||
files, err := client.GetModifiedFiles(models.Repo{
|
||||
FullName: "owner/repo",
|
||||
Owner: "owner",
|
||||
Name: "repo",
|
||||
CloneURL: "",
|
||||
SanitizedCloneURL: "",
|
||||
VCSHost: models.VCSHost{
|
||||
Type: models.BitbucketCloud,
|
||||
Hostname: "bitbucket.org",
|
||||
err = client.MergePull(models.PullRequest{
|
||||
Num: 1,
|
||||
HeadCommit: "",
|
||||
URL: "",
|
||||
HeadBranch: "",
|
||||
BaseBranch: "",
|
||||
Author: "",
|
||||
State: 0,
|
||||
BaseRepo: models.Repo{
|
||||
FullName: "owner/repo",
|
||||
Owner: "owner",
|
||||
Name: "repo",
|
||||
SanitizedCloneURL: fmt.Sprintf("%s/scm/ow/repo.git", testServer.URL),
|
||||
VCSHost: models.VCSHost{
|
||||
Type: models.BitbucketCloud,
|
||||
Hostname: "bitbucket.org",
|
||||
},
|
||||
},
|
||||
}, models.PullRequest{
|
||||
Num: 1,
|
||||
})
|
||||
Ok(t, err)
|
||||
Equals(t, []string{"parent/child/file1.txt"}, files)
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ type CommonEventData struct {
|
||||
}
|
||||
|
||||
type PullRequest struct {
|
||||
Version *int `json:"version,omitempty" validate:"required"`
|
||||
ID *int `json:"id,omitempty" validate:"required"`
|
||||
FromRef *Ref `json:"fromRef,omitempty" validate:"required"`
|
||||
ToRef *Ref `json:"toRef,omitempty" validate:"required"`
|
||||
|
||||
134
server/events/vcs/bitbucketserver/testdata/pull-request.json
vendored
Normal file
134
server/events/vcs/bitbucketserver/testdata/pull-request.json
vendored
Normal file
@@ -0,0 +1,134 @@
|
||||
{
|
||||
"id": 2,
|
||||
"version": 3,
|
||||
"title": "hi",
|
||||
"state": "MERGED",
|
||||
"open": false,
|
||||
"closed": true,
|
||||
"createdDate": 1550611116280,
|
||||
"updatedDate": 1550611904547,
|
||||
"closedDate": 1550611904547,
|
||||
"fromRef": {
|
||||
"id": "refs/heads/hi",
|
||||
"displayId": "hi",
|
||||
"latestCommit": "bdcaa224f4b65edb853a689404ef79cf47d8cdda",
|
||||
"repository": {
|
||||
"slug": "example",
|
||||
"id": 1,
|
||||
"name": "example",
|
||||
"scmId": "git",
|
||||
"state": "AVAILABLE",
|
||||
"statusMessage": "Available",
|
||||
"forkable": true,
|
||||
"project": {
|
||||
"key": "AT",
|
||||
"id": 1,
|
||||
"name": "atlantis",
|
||||
"public": false,
|
||||
"type": "NORMAL",
|
||||
"links": {
|
||||
"self": [
|
||||
{
|
||||
"href": "http://localhost:7990/projects/AT"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"public": false,
|
||||
"links": {
|
||||
"clone": [
|
||||
{
|
||||
"href": "ssh://git@localhost:7999/at/example.git",
|
||||
"name": "ssh"
|
||||
},
|
||||
{
|
||||
"href": "http://localhost:7990/scm/at/example.git",
|
||||
"name": "http"
|
||||
}
|
||||
],
|
||||
"self": [
|
||||
{
|
||||
"href": "http://localhost:7990/projects/AT/repos/example/browse"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"toRef": {
|
||||
"id": "refs/heads/master",
|
||||
"displayId": "master",
|
||||
"latestCommit": "59e03b9cc44e16e20741e328faaac26e377c07bf",
|
||||
"repository": {
|
||||
"slug": "example",
|
||||
"id": 1,
|
||||
"name": "example",
|
||||
"scmId": "git",
|
||||
"state": "AVAILABLE",
|
||||
"statusMessage": "Available",
|
||||
"forkable": true,
|
||||
"project": {
|
||||
"key": "AT",
|
||||
"id": 1,
|
||||
"name": "atlantis",
|
||||
"public": false,
|
||||
"type": "NORMAL",
|
||||
"links": {
|
||||
"self": [
|
||||
{
|
||||
"href": "http://localhost:7990/projects/AT"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"public": false,
|
||||
"links": {
|
||||
"clone": [
|
||||
{
|
||||
"href": "ssh://git@localhost:7999/at/example.git",
|
||||
"name": "ssh"
|
||||
},
|
||||
{
|
||||
"href": "http://localhost:7990/scm/at/example.git",
|
||||
"name": "http"
|
||||
}
|
||||
],
|
||||
"self": [
|
||||
{
|
||||
"href": "http://localhost:7990/projects/AT/repos/example/browse"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"locked": false,
|
||||
"author": {
|
||||
"user": {
|
||||
"name": "admin",
|
||||
"emailAddress": "luke@hashicorp.com",
|
||||
"id": 1,
|
||||
"displayName": "admin",
|
||||
"active": true,
|
||||
"slug": "admin",
|
||||
"type": "NORMAL",
|
||||
"links": {
|
||||
"self": [
|
||||
{
|
||||
"href": "http://localhost:7990/users/admin"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"role": "AUTHOR",
|
||||
"approved": false,
|
||||
"status": "UNAPPROVED"
|
||||
},
|
||||
"reviewers": [],
|
||||
"participants": [],
|
||||
"links": {
|
||||
"self": [
|
||||
{
|
||||
"href": "http://localhost:7990/projects/AT/repos/example/pull-requests/2"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user