diff --git a/runatlantis.io/docs/api-endpoints.md b/runatlantis.io/docs/api-endpoints.md index ce622979da..b1f5d463c2 100644 --- a/runatlantis.io/docs/api-endpoints.md +++ b/runatlantis.io/docs/api-endpoints.md @@ -28,6 +28,8 @@ Execute [atlantis plan](using-atlantis.md#atlantis-plan) on the specified reposi | Type | string | Yes | Type of the VCS provider (Github/Gitlab) | | Paths | Path | Yes | Paths to the projects to run the plan | | PR | int | No | Pull Request number | +| BaseBranch | string | No | The branch where the PR will be merged | +| Commit | string | No | The commit to checkout in the PR | #### Path diff --git a/server/controllers/api_controller.go b/server/controllers/api_controller.go index ff85371469..d0d9d5b94f 100644 --- a/server/controllers/api_controller.go +++ b/server/controllers/api_controller.go @@ -39,6 +39,8 @@ type APIRequest struct { Repository string `validate:"required"` Ref string `validate:"required"` Type string `validate:"required"` + Commit string + BaseBranch string PR int Projects []string Paths []struct { @@ -167,6 +169,13 @@ func (a *APIController) apiPlan(request *APIRequest, ctx *command.Context) (*com return &command.Result{ProjectResults: projectResults}, nil } +func GetOrElse(val, def string) string { + if val != "" { + return val + } + return def +} + func (a *APIController) apiApply(request *APIRequest, ctx *command.Context) (*command.Result, error) { cmds, cc, err := request.getCommands(ctx, a.ProjectCommandBuilder.BuildApplyCommands) if err != nil { @@ -233,13 +242,16 @@ func (a *APIController) apiParseAndValidate(r *http.Request) (*APIRequest, *comm return nil, nil, http.StatusForbidden, fmt.Errorf("repo not allowlisted") } + baseBranch := GetOrElse(request.BaseBranch, request.Ref) + headCommit := GetOrElse(request.Commit, request.Ref) + return &request, &command.Context{ HeadRepo: baseRepo, Pull: models.PullRequest{ Num: request.PR, - BaseBranch: request.Ref, + BaseBranch: baseBranch, HeadBranch: request.Ref, - HeadCommit: request.Ref, + HeadCommit: headCommit, BaseRepo: baseRepo, }, Scope: a.Scope, diff --git a/server/controllers/api_controller_test.go b/server/controllers/api_controller_test.go index 3b3aa520aa..9877e7b909 100644 --- a/server/controllers/api_controller_test.go +++ b/server/controllers/api_controller_test.go @@ -24,11 +24,22 @@ const atlantisTokenHeader = "X-Atlantis-Token" const atlantisToken = "token" func TestAPIController_Plan(t *testing.T) { + testPlan(t, "main", "", "") +} + +func TestAPIController_PlanWithNewParams(t *testing.T) { + testPlan(t, "my-feature-branch", "HEAD", "main") +} + +func testPlan(t *testing.T, ref, commit, baseBranch string) { ac, projectCommandBuilder, projectCommandRunner := setup(t) body, _ := json.Marshal(controllers.APIRequest{ Repository: "Repo", - Ref: "main", + Ref: ref, Type: "Gitlab", + Commit: commit, + BaseBranch: baseBranch, + PR: 100, Projects: []string{"default"}, }) req, _ := http.NewRequest("POST", "", bytes.NewBuffer(body)) @@ -36,7 +47,28 @@ func TestAPIController_Plan(t *testing.T) { w := httptest.NewRecorder() ac.Plan(w, req) ResponseContains(t, w, http.StatusOK, "") - projectCommandBuilder.VerifyWasCalledOnce().BuildPlanCommands(Any[*command.Context](), Any[*events.CommentCommand]()) + + headCommit := controllers.GetOrElse(commit, ref) + baseBranch = controllers.GetOrElse(baseBranch, ref) + + repo := models.Repo{} + cmdContext := &command.Context{ + HeadRepo: repo, + Pull: models.PullRequest{ + Num: 100, + BaseBranch: baseBranch, + HeadBranch: ref, + HeadCommit: headCommit, + BaseRepo: repo, + }, + Scope: ac.Scope, + Log: ac.Logger, + } + commentCmd := &events.CommentCommand{ + ProjectName: "default", + } + + projectCommandBuilder.VerifyWasCalledOnce().BuildPlanCommands(cmdContext, commentCmd) projectCommandRunner.VerifyWasCalledOnce().Plan(Any[command.ProjectContext]()) }