mirror of
https://git.vectorsigma.ru/public/atlantis.git
synced 2026-08-05 03:38:54 +00:00
feat: --silence-no-projects to comments with -d and -p (#2969)
* Expand --silence-no-projects to targeted commands * Cover other commands, test+docs * Add more tests, refactor doc * fix tests * fix dangling pending VCS statuses * fix: codeql yaml * fix: lint
This commit is contained in:
1
.github/workflows/codeql.yml
vendored
1
.github/workflows/codeql.yml
vendored
@@ -26,7 +26,6 @@ on:
|
||||
|
||||
jobs:
|
||||
analyze:
|
||||
if: github.event.pull_request.draft == false
|
||||
name: Analyze
|
||||
if: github.event.pull_request.draft == false
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
@@ -873,6 +873,9 @@ and set `--autoplan-modules` to `false`.
|
||||
ATLANTIS_SILENCE_NO_PROJECTS=true
|
||||
```
|
||||
`--silence-no-projects` will tell Atlantis to ignore PRs if none of the modified files are part of a project defined in the `atlantis.yaml` file.
|
||||
This flag ensures an Atlantis server only responds to its explicitly declared projects.
|
||||
This has no effect if projects are undefined in the repo level `atlantis.yaml`.
|
||||
This also silences targeted commands (eg. `atlantis plan -d mydir` or `atlantis apply -p myproj`) so if the project is not in the repo config `atlantis.yaml`, these commands will not run or report back in a comment.
|
||||
|
||||
This is useful when running multiple Atlantis servers against a single repository so you can
|
||||
delegate work to each Atlantis server. Also useful when used with pre_workflow_hooks to dynamically generate an `atlantis.yaml` file.
|
||||
|
||||
@@ -1177,6 +1177,7 @@ func setupE2E(t *testing.T, repoDir string, opt setupOption) (events_controllers
|
||||
"",
|
||||
"**/*.tf,**/*.tfvars,**/*.tfvars.json,**/terragrunt.hcl,**/.terraform.lock.hcl",
|
||||
false,
|
||||
false,
|
||||
statsScope,
|
||||
logger,
|
||||
terraformClient,
|
||||
@@ -1327,6 +1328,7 @@ func setupE2E(t *testing.T, repoDir string, opt setupOption) (events_controllers
|
||||
e2ePullReqStatusFetcher,
|
||||
projectCommandBuilder,
|
||||
projectCommandRunner,
|
||||
silenceNoProjects,
|
||||
)
|
||||
|
||||
stateCommandRunner := events.NewStateCommandRunner(
|
||||
|
||||
@@ -124,14 +124,34 @@ func (a *ApplyCommandRunner) Run(ctx *command.Context, cmd *CommentCommand) {
|
||||
|
||||
// If there are no projects to apply, don't respond to the PR and ignore
|
||||
if len(projectCmds) == 0 && a.SilenceNoProjects {
|
||||
ctx.Log.Info("determined there was no project to run apply in.")
|
||||
ctx.Log.Info("determined there was no project to run plan in")
|
||||
if !a.silenceVCSStatusNoProjects {
|
||||
// If there were no projects modified, we set successful commit statuses
|
||||
// with 0/0 projects applied successfully because some users require
|
||||
// the Atlantis status to be passing for all pull requests.
|
||||
ctx.Log.Debug("setting VCS status to success with no projects found")
|
||||
if err := a.commitStatusUpdater.UpdateCombinedCount(baseRepo, pull, models.SuccessCommitStatus, command.Apply, 0, 0); err != nil {
|
||||
ctx.Log.Warn("unable to update commit status: %s", err)
|
||||
if cmd.IsForSpecificProject() {
|
||||
// With a specific apply, just reset the status so it's not stuck in pending state
|
||||
pullStatus, err := a.Backend.GetPullStatus(pull)
|
||||
if err != nil {
|
||||
ctx.Log.Warn("unable to fetch pull status: %s", err)
|
||||
return
|
||||
}
|
||||
if pullStatus == nil {
|
||||
// default to 0/0
|
||||
ctx.Log.Debug("setting VCS status to 0/0 success as no previous state was found")
|
||||
if err := a.commitStatusUpdater.UpdateCombinedCount(baseRepo, pull, models.SuccessCommitStatus, command.Apply, 0, 0); err != nil {
|
||||
ctx.Log.Warn("unable to update commit status: %s", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
ctx.Log.Debug("resetting VCS status")
|
||||
a.updateCommitStatus(ctx, *pullStatus)
|
||||
} else {
|
||||
// With a generic apply, we set successful commit statuses
|
||||
// with 0/0 projects planned successfully because some users require
|
||||
// the Atlantis status to be passing for all pull requests.
|
||||
// Does not apply to skipped runs for specific projects
|
||||
ctx.Log.Debug("setting VCS status to success with no projects found")
|
||||
if err := a.commitStatusUpdater.UpdateCombinedCount(baseRepo, pull, models.SuccessCommitStatus, command.Apply, 0, 0); err != nil {
|
||||
ctx.Log.Warn("unable to update commit status: %s", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
|
||||
@@ -6,13 +6,16 @@ import (
|
||||
|
||||
"github.com/google/go-github/v49/github"
|
||||
. "github.com/petergtz/pegomock"
|
||||
"github.com/runatlantis/atlantis/server/core/db"
|
||||
"github.com/runatlantis/atlantis/server/core/locking"
|
||||
"github.com/runatlantis/atlantis/server/events"
|
||||
"github.com/runatlantis/atlantis/server/events/command"
|
||||
"github.com/runatlantis/atlantis/server/events/mocks/matchers"
|
||||
"github.com/runatlantis/atlantis/server/events/models"
|
||||
"github.com/runatlantis/atlantis/server/events/models/testdata"
|
||||
"github.com/runatlantis/atlantis/server/logging"
|
||||
"github.com/runatlantis/atlantis/server/metrics"
|
||||
. "github.com/runatlantis/atlantis/testing"
|
||||
)
|
||||
|
||||
func TestApplyCommandRunner_IsLocked(t *testing.T) {
|
||||
@@ -73,3 +76,140 @@ func TestApplyCommandRunner_IsLocked(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestApplyCommandRunner_IsSilenced(t *testing.T) {
|
||||
RegisterMockTestingT(t)
|
||||
|
||||
cases := []struct {
|
||||
Description string
|
||||
Matched bool
|
||||
Targeted bool
|
||||
VCSStatusSilence bool
|
||||
PrevApplyStored bool // stores a 1/1 passing apply in the backend
|
||||
ExpVCSStatusSet bool
|
||||
ExpVCSStatusTotal int
|
||||
ExpVCSStatusSucc int
|
||||
ExpSilenced bool
|
||||
}{
|
||||
{
|
||||
Description: "When applying, don't comment but set the 0/0 VCS status",
|
||||
ExpVCSStatusSet: true,
|
||||
ExpSilenced: true,
|
||||
},
|
||||
{
|
||||
Description: "When applying with any previous apply's, don't comment but set the 0/0 VCS status",
|
||||
PrevApplyStored: true,
|
||||
ExpVCSStatusSet: true,
|
||||
ExpSilenced: true,
|
||||
},
|
||||
{
|
||||
Description: "When applying with unmatched target, don't comment but set the 0/0 VCS status",
|
||||
Targeted: true,
|
||||
ExpVCSStatusSet: true,
|
||||
ExpSilenced: true,
|
||||
},
|
||||
{
|
||||
Description: "When applying with unmatched target and any previous apply's, don't comment and maintain VCS status",
|
||||
Targeted: true,
|
||||
PrevApplyStored: true,
|
||||
ExpVCSStatusSet: true,
|
||||
ExpSilenced: true,
|
||||
ExpVCSStatusSucc: 1,
|
||||
ExpVCSStatusTotal: 1,
|
||||
},
|
||||
{
|
||||
Description: "When applying with silenced VCS status, don't do anything",
|
||||
VCSStatusSilence: true,
|
||||
ExpVCSStatusSet: false,
|
||||
ExpSilenced: true,
|
||||
},
|
||||
{
|
||||
Description: "When applying with matching projects, comment as usual",
|
||||
Matched: true,
|
||||
ExpVCSStatusSet: true,
|
||||
ExpSilenced: false,
|
||||
ExpVCSStatusSucc: 1,
|
||||
ExpVCSStatusTotal: 1,
|
||||
},
|
||||
}
|
||||
|
||||
for _, c := range cases {
|
||||
t.Run(c.Description, func(t *testing.T) {
|
||||
// create an empty DB
|
||||
tmp := t.TempDir()
|
||||
db, err := db.New(tmp)
|
||||
Ok(t, err)
|
||||
|
||||
vcsClient := setup(t, func(tc *TestConfig) {
|
||||
tc.SilenceNoProjects = true
|
||||
tc.silenceVCSStatusNoProjects = c.VCSStatusSilence
|
||||
tc.backend = db
|
||||
})
|
||||
|
||||
scopeNull, _, _ := metrics.NewLoggingScope(logger, "atlantis")
|
||||
modelPull := models.PullRequest{BaseRepo: testdata.GithubRepo, State: models.OpenPullState, Num: testdata.Pull.Num}
|
||||
|
||||
cmd := &events.CommentCommand{Name: command.Apply}
|
||||
if c.Targeted {
|
||||
cmd.RepoRelDir = "mydir"
|
||||
}
|
||||
|
||||
ctx := &command.Context{
|
||||
User: testdata.User,
|
||||
Log: logging.NewNoopLogger(t),
|
||||
Scope: scopeNull,
|
||||
Pull: modelPull,
|
||||
HeadRepo: testdata.GithubRepo,
|
||||
Trigger: command.CommentTrigger,
|
||||
}
|
||||
if c.PrevApplyStored {
|
||||
_, err = db.UpdatePullWithResults(modelPull, []command.ProjectResult{
|
||||
{
|
||||
Command: command.Apply,
|
||||
RepoRelDir: "prevdir",
|
||||
Workspace: "default",
|
||||
},
|
||||
})
|
||||
Ok(t, err)
|
||||
}
|
||||
|
||||
When(projectCommandBuilder.BuildApplyCommands(ctx, cmd)).Then(func(args []Param) ReturnValues {
|
||||
if c.Matched {
|
||||
return ReturnValues{[]command.ProjectContext{{
|
||||
CommandName: command.Apply,
|
||||
ProjectPlanStatus: models.PlannedPlanStatus,
|
||||
}}, nil}
|
||||
}
|
||||
return ReturnValues{[]command.ProjectContext{}, nil}
|
||||
})
|
||||
|
||||
applyCommandRunner.Run(ctx, cmd)
|
||||
|
||||
timesComment := 1
|
||||
if c.ExpSilenced {
|
||||
timesComment = 0
|
||||
}
|
||||
|
||||
vcsClient.VerifyWasCalled(Times(timesComment)).CreateComment(AnyRepo(), AnyInt(), AnyString(), AnyString())
|
||||
if c.ExpVCSStatusSet {
|
||||
commitUpdater.VerifyWasCalledOnce().UpdateCombinedCount(
|
||||
matchers.AnyModelsRepo(),
|
||||
matchers.AnyModelsPullRequest(),
|
||||
matchers.EqModelsCommitStatus(models.SuccessCommitStatus),
|
||||
matchers.EqCommandName(command.Apply),
|
||||
EqInt(c.ExpVCSStatusSucc),
|
||||
EqInt(c.ExpVCSStatusTotal),
|
||||
)
|
||||
} else {
|
||||
commitUpdater.VerifyWasCalled(Never()).UpdateCombinedCount(
|
||||
matchers.AnyModelsRepo(),
|
||||
matchers.AnyModelsPullRequest(),
|
||||
matchers.AnyModelsCommitStatus(),
|
||||
matchers.EqCommandName(command.Apply),
|
||||
AnyInt(),
|
||||
AnyInt(),
|
||||
)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,12 +16,14 @@ package events_test
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"regexp"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/runatlantis/atlantis/server/core/config/valid"
|
||||
"github.com/runatlantis/atlantis/server/core/db"
|
||||
"github.com/runatlantis/atlantis/server/core/locking"
|
||||
"github.com/runatlantis/atlantis/server/events/command"
|
||||
"github.com/runatlantis/atlantis/server/logging"
|
||||
"github.com/runatlantis/atlantis/server/metrics"
|
||||
@@ -70,21 +72,35 @@ var importCommandRunner *events.ImportCommandRunner
|
||||
var preWorkflowHooksCommandRunner events.PreWorkflowHooksCommandRunner
|
||||
var postWorkflowHooksCommandRunner events.PostWorkflowHooksCommandRunner
|
||||
|
||||
func AnyRepo() models.Repo {
|
||||
RegisterMatcher(NewAnyMatcher(reflect.TypeOf(models.Repo{})))
|
||||
return models.Repo{}
|
||||
}
|
||||
|
||||
type TestConfig struct {
|
||||
parallelPoolSize int
|
||||
SilenceNoProjects bool
|
||||
StatusName string
|
||||
discardApprovalOnPlan bool
|
||||
parallelPoolSize int
|
||||
SilenceNoProjects bool
|
||||
silenceVCSStatusNoPlans bool
|
||||
silenceVCSStatusNoProjects bool
|
||||
StatusName string
|
||||
discardApprovalOnPlan bool
|
||||
backend locking.Backend
|
||||
}
|
||||
|
||||
func setup(t *testing.T, options ...func(testConfig *TestConfig)) *vcsmocks.MockClient {
|
||||
RegisterMockTestingT(t)
|
||||
|
||||
// create an empty DB
|
||||
tmp := t.TempDir()
|
||||
defaultBoltDB, err := db.New(tmp)
|
||||
Ok(t, err)
|
||||
|
||||
testConfig := &TestConfig{
|
||||
parallelPoolSize: 1,
|
||||
SilenceNoProjects: false,
|
||||
StatusName: "atlantis-test",
|
||||
discardApprovalOnPlan: false,
|
||||
backend: defaultBoltDB,
|
||||
}
|
||||
|
||||
for _, op := range options {
|
||||
@@ -103,9 +119,6 @@ func setup(t *testing.T, options ...func(testConfig *TestConfig)) *vcsmocks.Mock
|
||||
pendingPlanFinder = mocks.NewMockPendingPlanFinder()
|
||||
commitUpdater = mocks.NewMockCommitStatusUpdater()
|
||||
pullReqStatusFetcher = vcsmocks.NewMockPullReqStatusFetcher()
|
||||
tmp := t.TempDir()
|
||||
defaultBoltDB, err := db.New(tmp)
|
||||
Ok(t, err)
|
||||
|
||||
drainer = &events.Drainer{}
|
||||
deleteLockCommand = mocks.NewMockDeleteLockCommand()
|
||||
@@ -113,7 +126,7 @@ func setup(t *testing.T, options ...func(testConfig *TestConfig)) *vcsmocks.Mock
|
||||
lockingLocker = lockingmocks.NewMockLocker()
|
||||
|
||||
dbUpdater = &events.DBUpdater{
|
||||
Backend: defaultBoltDB,
|
||||
Backend: testConfig.backend,
|
||||
}
|
||||
|
||||
pullUpdater = &events.PullUpdater{
|
||||
@@ -133,13 +146,13 @@ func setup(t *testing.T, options ...func(testConfig *TestConfig)) *vcsmocks.Mock
|
||||
commitUpdater,
|
||||
projectCommandRunner,
|
||||
testConfig.parallelPoolSize,
|
||||
false,
|
||||
testConfig.silenceVCSStatusNoProjects,
|
||||
false,
|
||||
)
|
||||
|
||||
planCommandRunner = events.NewPlanCommandRunner(
|
||||
false,
|
||||
false,
|
||||
testConfig.silenceVCSStatusNoPlans,
|
||||
testConfig.silenceVCSStatusNoProjects,
|
||||
vcsClient,
|
||||
pendingPlanFinder,
|
||||
workingDir,
|
||||
@@ -152,7 +165,7 @@ func setup(t *testing.T, options ...func(testConfig *TestConfig)) *vcsmocks.Mock
|
||||
autoMerger,
|
||||
testConfig.parallelPoolSize,
|
||||
testConfig.SilenceNoProjects,
|
||||
defaultBoltDB,
|
||||
testConfig.backend,
|
||||
lockingLocker,
|
||||
testConfig.discardApprovalOnPlan,
|
||||
pullReqStatusFetcher,
|
||||
@@ -168,10 +181,10 @@ func setup(t *testing.T, options ...func(testConfig *TestConfig)) *vcsmocks.Mock
|
||||
autoMerger,
|
||||
pullUpdater,
|
||||
dbUpdater,
|
||||
defaultBoltDB,
|
||||
testConfig.backend,
|
||||
testConfig.parallelPoolSize,
|
||||
testConfig.SilenceNoProjects,
|
||||
false,
|
||||
testConfig.silenceVCSStatusNoProjects,
|
||||
pullReqStatusFetcher,
|
||||
)
|
||||
|
||||
@@ -182,7 +195,7 @@ func setup(t *testing.T, options ...func(testConfig *TestConfig)) *vcsmocks.Mock
|
||||
pullUpdater,
|
||||
dbUpdater,
|
||||
testConfig.SilenceNoProjects,
|
||||
false,
|
||||
testConfig.silenceVCSStatusNoProjects,
|
||||
vcsClient,
|
||||
)
|
||||
|
||||
@@ -205,6 +218,7 @@ func setup(t *testing.T, options ...func(testConfig *TestConfig)) *vcsmocks.Mock
|
||||
pullReqStatusFetcher,
|
||||
projectCommandBuilder,
|
||||
projectCommandRunner,
|
||||
testConfig.SilenceNoProjects,
|
||||
)
|
||||
|
||||
commentCommandRunnerByCmd := map[command.Name]events.CommentCommandRunner{
|
||||
@@ -242,7 +256,7 @@ func setup(t *testing.T, options ...func(testConfig *TestConfig)) *vcsmocks.Mock
|
||||
Drainer: drainer,
|
||||
PreWorkflowHooksCommandRunner: preWorkflowHooksCommandRunner,
|
||||
PostWorkflowHooksCommandRunner: postWorkflowHooksCommandRunner,
|
||||
PullStatusFetcher: defaultBoltDB,
|
||||
PullStatusFetcher: testConfig.backend,
|
||||
}
|
||||
|
||||
return vcsClient
|
||||
@@ -383,6 +397,28 @@ func TestRunCommentCommandPlan_NoProjects_SilenceEnabled(t *testing.T) {
|
||||
)
|
||||
}
|
||||
|
||||
func TestRunCommentCommandPlan_NoProjectsTarget_SilenceEnabled(t *testing.T) {
|
||||
// TODO
|
||||
t.Log("if a plan command is run against a project and SilenceNoProjects is enabled, we are silencing all comments if the project is not in the repo config")
|
||||
vcsClient := setup(t)
|
||||
planCommandRunner.SilenceNoProjects = true
|
||||
var pull github.PullRequest
|
||||
modelPull := models.PullRequest{BaseRepo: testdata.GithubRepo, State: models.OpenPullState}
|
||||
When(githubGetter.GetPullRequest(testdata.GithubRepo, testdata.Pull.Num)).ThenReturn(&pull, nil)
|
||||
When(eventParsing.ParseGithubPull(&pull)).ThenReturn(modelPull, modelPull.BaseRepo, testdata.GithubRepo, nil)
|
||||
|
||||
ch.RunCommentCommand(testdata.GithubRepo, nil, nil, testdata.User, testdata.Pull.Num, &events.CommentCommand{Name: command.Plan, ProjectName: "meow"})
|
||||
vcsClient.VerifyWasCalled(Never()).CreateComment(matchers.AnyModelsRepo(), AnyInt(), AnyString(), AnyString())
|
||||
commitUpdater.VerifyWasCalledOnce().UpdateCombinedCount(
|
||||
matchers.AnyModelsRepo(),
|
||||
matchers.AnyModelsPullRequest(),
|
||||
matchers.EqModelsCommitStatus(models.SuccessCommitStatus),
|
||||
matchers.EqCommandName(command.Plan),
|
||||
EqInt(0),
|
||||
EqInt(0),
|
||||
)
|
||||
}
|
||||
|
||||
func TestRunCommentCommandApply_NoProjects_SilenceEnabled(t *testing.T) {
|
||||
t.Log("if an apply command is run on a pull request and SilenceNoProjects is enabled and we are silencing all comments if the modified files don't have a matching project")
|
||||
vcsClient := setup(t)
|
||||
@@ -438,6 +474,19 @@ func TestRunCommentCommandUnlock_NoProjects_SilenceEnabled(t *testing.T) {
|
||||
vcsClient.VerifyWasCalled(Never()).CreateComment(matchers.AnyModelsRepo(), AnyInt(), AnyString(), AnyString())
|
||||
}
|
||||
|
||||
func TestRunCommentCommandImport_NoProjects_SilenceEnabled(t *testing.T) {
|
||||
t.Log("if an import command is run on a pull request and SilenceNoProjects is enabled, we are silencing all comments if the modified files don't have a matching project")
|
||||
vcsClient := setup(t)
|
||||
importCommandRunner.SilenceNoProjects = true
|
||||
var pull github.PullRequest
|
||||
modelPull := models.PullRequest{BaseRepo: testdata.GithubRepo, State: models.OpenPullState}
|
||||
When(githubGetter.GetPullRequest(testdata.GithubRepo, testdata.Pull.Num)).ThenReturn(&pull, nil)
|
||||
When(eventParsing.ParseGithubPull(&pull)).ThenReturn(modelPull, modelPull.BaseRepo, testdata.GithubRepo, nil)
|
||||
|
||||
ch.RunCommentCommand(testdata.GithubRepo, nil, nil, testdata.User, testdata.Pull.Num, &events.CommentCommand{Name: command.Import})
|
||||
vcsClient.VerifyWasCalled(Never()).CreateComment(matchers.AnyModelsRepo(), AnyInt(), AnyString(), AnyString())
|
||||
}
|
||||
|
||||
func TestRunCommentCommand_DisableApplyAllDisabled(t *testing.T) {
|
||||
t.Log("if \"atlantis apply\" is run and this is disabled atlantis should" +
|
||||
" comment saying that this is not allowed")
|
||||
|
||||
@@ -10,12 +10,14 @@ func NewImportCommandRunner(
|
||||
pullReqStatusFetcher vcs.PullReqStatusFetcher,
|
||||
prjCmdBuilder ProjectImportCommandBuilder,
|
||||
prjCmdRunner ProjectImportCommandRunner,
|
||||
SilenceNoProjects bool,
|
||||
) *ImportCommandRunner {
|
||||
return &ImportCommandRunner{
|
||||
pullUpdater: pullUpdater,
|
||||
pullReqStatusFetcher: pullReqStatusFetcher,
|
||||
prjCmdBuilder: prjCmdBuilder,
|
||||
prjCmdRunner: prjCmdRunner,
|
||||
SilenceNoProjects: SilenceNoProjects,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,6 +26,7 @@ type ImportCommandRunner struct {
|
||||
pullReqStatusFetcher vcs.PullReqStatusFetcher
|
||||
prjCmdBuilder ProjectImportCommandBuilder
|
||||
prjCmdRunner ProjectImportCommandRunner
|
||||
SilenceNoProjects bool
|
||||
}
|
||||
|
||||
func (v *ImportCommandRunner) Run(ctx *command.Context, cmd *CommentCommand) {
|
||||
@@ -48,6 +51,10 @@ func (v *ImportCommandRunner) Run(ctx *command.Context, cmd *CommentCommand) {
|
||||
ctx.Log.Warn("Error %s", err)
|
||||
}
|
||||
|
||||
if len(projectCmds) == 0 && v.SilenceNoProjects {
|
||||
ctx.Log.Info("determined there was no project to run import in.")
|
||||
return
|
||||
}
|
||||
var result command.Result
|
||||
if len(projectCmds) > 1 {
|
||||
// There is no usecase to kick terraform import into multiple projects.
|
||||
|
||||
@@ -18,9 +18,11 @@ func TestImportCommandRunner_Run(t *testing.T) {
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
silenced bool
|
||||
pullReqStatus models.PullReqStatus
|
||||
projectCmds []command.ProjectContext
|
||||
expComment string
|
||||
expNoComment bool
|
||||
}{
|
||||
{
|
||||
name: "success with zero projects",
|
||||
@@ -40,10 +42,22 @@ func TestImportCommandRunner_Run(t *testing.T) {
|
||||
projectCmds: []command.ProjectContext{{}, {}},
|
||||
expComment: "**Import Failed**: import cannot run on multiple projects. please specify one project.",
|
||||
},
|
||||
{
|
||||
name: "no comment with zero projects and silencing",
|
||||
pullReqStatus: models.PullReqStatus{
|
||||
ApprovalStatus: models.ApprovalStatus{IsApproved: true},
|
||||
Mergeable: true,
|
||||
},
|
||||
projectCmds: []command.ProjectContext{},
|
||||
silenced: true,
|
||||
expNoComment: true,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
vcsClient := setup(t)
|
||||
vcsClient := setup(t, func(tc *TestConfig) {
|
||||
tc.SilenceNoProjects = tt.silenced
|
||||
})
|
||||
|
||||
scopeNull, _, _ := metrics.NewLoggingScope(logger, "atlantis")
|
||||
modelPull := models.PullRequest{BaseRepo: testdata.GithubRepo, State: models.OpenPullState, Num: testdata.Pull.Num}
|
||||
@@ -63,7 +77,11 @@ func TestImportCommandRunner_Run(t *testing.T) {
|
||||
importCommandRunner.Run(ctx, cmd)
|
||||
|
||||
Assert(t, ctx.PullRequestStatus.Mergeable == true, "PullRequestStatus must be set for import_requirements")
|
||||
vcsClient.VerifyWasCalledOnce().CreateComment(testdata.GithubRepo, modelPull.Num, tt.expComment, "import")
|
||||
if tt.expNoComment {
|
||||
vcsClient.VerifyWasCalled(Never()).CreateComment(AnyRepo(), AnyInt(), AnyString(), AnyString())
|
||||
} else {
|
||||
vcsClient.VerifyWasCalledOnce().CreateComment(testdata.GithubRepo, modelPull.Num, tt.expComment, "import")
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -202,12 +202,32 @@ func (p *PlanCommandRunner) run(ctx *command.Context, cmd *CommentCommand) {
|
||||
if len(projectCmds) == 0 && p.SilenceNoProjects {
|
||||
ctx.Log.Info("determined there was no project to run plan in")
|
||||
if !p.silenceVCSStatusNoProjects {
|
||||
// If there were no projects modified, we set successful commit statuses
|
||||
// with 0/0 projects planned successfully because some users require
|
||||
// the Atlantis status to be passing for all pull requests.
|
||||
ctx.Log.Debug("setting VCS status to success with no projects found")
|
||||
if err := p.commitStatusUpdater.UpdateCombinedCount(baseRepo, pull, models.SuccessCommitStatus, command.Plan, 0, 0); err != nil {
|
||||
ctx.Log.Warn("unable to update commit status: %s", err)
|
||||
if cmd.IsForSpecificProject() {
|
||||
// With a specific plan, just reset the status so it's not stuck in pending state
|
||||
pullStatus, err := p.pullStatusFetcher.GetPullStatus(pull)
|
||||
if err != nil {
|
||||
ctx.Log.Warn("unable to fetch pull status: %s", err)
|
||||
return
|
||||
}
|
||||
if pullStatus == nil {
|
||||
// default to 0/0
|
||||
ctx.Log.Debug("setting VCS status to 0/0 success as no previous state was found")
|
||||
if err := p.commitStatusUpdater.UpdateCombinedCount(baseRepo, pull, models.SuccessCommitStatus, command.Plan, 0, 0); err != nil {
|
||||
ctx.Log.Warn("unable to update commit status: %s", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
ctx.Log.Debug("resetting VCS status")
|
||||
p.updateCommitStatus(ctx, *pullStatus)
|
||||
} else {
|
||||
// With a generic plan, we set successful commit statuses
|
||||
// with 0/0 projects planned successfully because some users require
|
||||
// the Atlantis status to be passing for all pull requests.
|
||||
// Does not apply to skipped runs for specific projects
|
||||
ctx.Log.Debug("setting VCS status to success with no projects found")
|
||||
if err := p.commitStatusUpdater.UpdateCombinedCount(baseRepo, pull, models.SuccessCommitStatus, command.Plan, 0, 0); err != nil {
|
||||
ctx.Log.Warn("unable to update commit status: %s", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
|
||||
151
server/events/plan_command_runner_test.go
Normal file
151
server/events/plan_command_runner_test.go
Normal file
@@ -0,0 +1,151 @@
|
||||
package events_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
. "github.com/petergtz/pegomock"
|
||||
"github.com/runatlantis/atlantis/server/core/db"
|
||||
"github.com/runatlantis/atlantis/server/events"
|
||||
"github.com/runatlantis/atlantis/server/events/command"
|
||||
"github.com/runatlantis/atlantis/server/events/mocks/matchers"
|
||||
"github.com/runatlantis/atlantis/server/events/models"
|
||||
"github.com/runatlantis/atlantis/server/events/models/testdata"
|
||||
"github.com/runatlantis/atlantis/server/logging"
|
||||
"github.com/runatlantis/atlantis/server/metrics"
|
||||
. "github.com/runatlantis/atlantis/testing"
|
||||
)
|
||||
|
||||
func TestPlanCommandRunner_IsSilenced(t *testing.T) {
|
||||
RegisterMockTestingT(t)
|
||||
|
||||
cases := []struct {
|
||||
Description string
|
||||
Matched bool
|
||||
Targeted bool
|
||||
VCSStatusSilence bool
|
||||
PrevPlanStored bool // stores a 1/1 passing plan in the backend
|
||||
ExpVCSStatusSet bool
|
||||
ExpVCSStatusTotal int
|
||||
ExpVCSStatusSucc int
|
||||
ExpSilenced bool
|
||||
}{
|
||||
{
|
||||
Description: "When planning, don't comment but set the 0/0 VCS status",
|
||||
ExpVCSStatusSet: true,
|
||||
ExpSilenced: true,
|
||||
},
|
||||
{
|
||||
Description: "When planning with any previous plans, don't comment but set the 0/0 VCS status",
|
||||
PrevPlanStored: true,
|
||||
ExpVCSStatusSet: true,
|
||||
ExpSilenced: true,
|
||||
},
|
||||
{
|
||||
Description: "When planning with unmatched target, don't comment but set the 0/0 VCS status",
|
||||
Targeted: true,
|
||||
ExpVCSStatusSet: true,
|
||||
ExpSilenced: true,
|
||||
},
|
||||
{
|
||||
Description: "When planning with unmatched target and any previous plans, don't comment and maintain VCS status",
|
||||
Targeted: true,
|
||||
PrevPlanStored: true,
|
||||
ExpVCSStatusSet: true,
|
||||
ExpSilenced: true,
|
||||
ExpVCSStatusSucc: 1,
|
||||
ExpVCSStatusTotal: 1,
|
||||
},
|
||||
{
|
||||
Description: "When planning with silenced VCS status, don't do anything",
|
||||
VCSStatusSilence: true,
|
||||
ExpVCSStatusSet: false,
|
||||
ExpSilenced: true,
|
||||
},
|
||||
{
|
||||
Description: "When planning with matching projects, comment as usual",
|
||||
Matched: true,
|
||||
ExpVCSStatusSet: true,
|
||||
ExpSilenced: false,
|
||||
ExpVCSStatusSucc: 1,
|
||||
ExpVCSStatusTotal: 1,
|
||||
},
|
||||
}
|
||||
|
||||
for _, c := range cases {
|
||||
t.Run(c.Description, func(t *testing.T) {
|
||||
// create an empty DB
|
||||
tmp := t.TempDir()
|
||||
db, err := db.New(tmp)
|
||||
Ok(t, err)
|
||||
|
||||
vcsClient := setup(t, func(tc *TestConfig) {
|
||||
tc.SilenceNoProjects = true
|
||||
tc.silenceVCSStatusNoProjects = c.VCSStatusSilence
|
||||
tc.backend = db
|
||||
})
|
||||
|
||||
scopeNull, _, _ := metrics.NewLoggingScope(logger, "atlantis")
|
||||
modelPull := models.PullRequest{BaseRepo: testdata.GithubRepo, State: models.OpenPullState, Num: testdata.Pull.Num}
|
||||
|
||||
cmd := &events.CommentCommand{Name: command.Plan}
|
||||
if c.Targeted {
|
||||
cmd.RepoRelDir = "mydir"
|
||||
}
|
||||
|
||||
ctx := &command.Context{
|
||||
User: testdata.User,
|
||||
Log: logging.NewNoopLogger(t),
|
||||
Scope: scopeNull,
|
||||
Pull: modelPull,
|
||||
HeadRepo: testdata.GithubRepo,
|
||||
Trigger: command.CommentTrigger,
|
||||
}
|
||||
if c.PrevPlanStored {
|
||||
_, err = db.UpdatePullWithResults(modelPull, []command.ProjectResult{
|
||||
{
|
||||
Command: command.Plan,
|
||||
RepoRelDir: "prevdir",
|
||||
Workspace: "default",
|
||||
PlanSuccess: &models.PlanSuccess{},
|
||||
},
|
||||
})
|
||||
Ok(t, err)
|
||||
}
|
||||
|
||||
When(projectCommandBuilder.BuildPlanCommands(ctx, cmd)).Then(func(args []Param) ReturnValues {
|
||||
if c.Matched {
|
||||
return ReturnValues{[]command.ProjectContext{{CommandName: command.Plan}}, nil}
|
||||
}
|
||||
return ReturnValues{[]command.ProjectContext{}, nil}
|
||||
})
|
||||
|
||||
planCommandRunner.Run(ctx, cmd)
|
||||
|
||||
timesComment := 1
|
||||
if c.ExpSilenced {
|
||||
timesComment = 0
|
||||
}
|
||||
|
||||
vcsClient.VerifyWasCalled(Times(timesComment)).CreateComment(AnyRepo(), AnyInt(), AnyString(), AnyString())
|
||||
if c.ExpVCSStatusSet {
|
||||
commitUpdater.VerifyWasCalledOnce().UpdateCombinedCount(
|
||||
matchers.AnyModelsRepo(),
|
||||
matchers.AnyModelsPullRequest(),
|
||||
matchers.EqModelsCommitStatus(models.SuccessCommitStatus),
|
||||
matchers.EqCommandName(command.Plan),
|
||||
EqInt(c.ExpVCSStatusSucc),
|
||||
EqInt(c.ExpVCSStatusTotal),
|
||||
)
|
||||
} else {
|
||||
commitUpdater.VerifyWasCalled(Never()).UpdateCombinedCount(
|
||||
matchers.AnyModelsRepo(),
|
||||
matchers.AnyModelsPullRequest(),
|
||||
matchers.AnyModelsCommitStatus(),
|
||||
matchers.EqCommandName(command.Plan),
|
||||
AnyInt(),
|
||||
AnyInt(),
|
||||
)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -53,6 +53,7 @@ func NewInstrumentedProjectCommandBuilder(
|
||||
AutoDetectModuleFiles string,
|
||||
AutoplanFileList string,
|
||||
RestrictFileList bool,
|
||||
SilenceNoProjects bool,
|
||||
scope tally.Scope,
|
||||
logger logging.SimpleLogging,
|
||||
terraformClient terraform.Client,
|
||||
@@ -79,6 +80,7 @@ func NewInstrumentedProjectCommandBuilder(
|
||||
AutoDetectModuleFiles,
|
||||
AutoplanFileList,
|
||||
RestrictFileList,
|
||||
SilenceNoProjects,
|
||||
scope,
|
||||
logger,
|
||||
terraformClient,
|
||||
@@ -103,6 +105,7 @@ func NewProjectCommandBuilder(
|
||||
AutoDetectModuleFiles string,
|
||||
AutoplanFileList string,
|
||||
RestrictFileList bool,
|
||||
SilenceNoProjects bool,
|
||||
scope tally.Scope,
|
||||
logger logging.SimpleLogging,
|
||||
terraformClient terraform.Client,
|
||||
@@ -120,6 +123,7 @@ func NewProjectCommandBuilder(
|
||||
AutoDetectModuleFiles: AutoDetectModuleFiles,
|
||||
AutoplanFileList: AutoplanFileList,
|
||||
RestrictFileList: RestrictFileList,
|
||||
SilenceNoProjects: SilenceNoProjects,
|
||||
ProjectCommandContextBuilder: NewProjectCommandContextBuilder(
|
||||
policyChecksSupported,
|
||||
commentBuilder,
|
||||
@@ -202,6 +206,7 @@ type DefaultProjectCommandBuilder struct {
|
||||
AutoplanFileList string
|
||||
EnableDiffMarkdownFormat bool
|
||||
RestrictFileList bool
|
||||
SilenceNoProjects bool
|
||||
TerraformExecutor terraform.Client
|
||||
}
|
||||
|
||||
@@ -561,7 +566,11 @@ func (p *DefaultProjectCommandBuilder) getCfg(ctx *command.Context, projectName
|
||||
}
|
||||
}
|
||||
if len(projectsCfg) == 0 {
|
||||
err = fmt.Errorf("no project with name %q is defined in %s", projectName, repoCfgFile)
|
||||
if p.SilenceNoProjects && len(repoConfig.Projects) > 0 {
|
||||
ctx.Log.Debug("no project with name %q found but silencing the error", projectName)
|
||||
} else {
|
||||
err = fmt.Errorf("no project with name %q is defined in %s", projectName, repoCfgFile)
|
||||
}
|
||||
return
|
||||
}
|
||||
return
|
||||
@@ -718,6 +727,12 @@ func (p *DefaultProjectCommandBuilder) buildProjectCommandCtx(ctx *command.Conte
|
||||
)...)
|
||||
}
|
||||
} else {
|
||||
// Ignore the project if silenced with projects set in the repo config
|
||||
if p.SilenceNoProjects && repoCfgPtr != nil && len(repoCfgPtr.Projects) > 0 {
|
||||
ctx.Log.Debug("silencing is in effect, project will be ignored")
|
||||
return []command.ProjectContext{}, nil
|
||||
}
|
||||
|
||||
projCfg = p.GlobalCfg.DefaultProjCfg(ctx.Log, ctx.Pull.BaseRepo.ID(), repoRelDir, workspace)
|
||||
projCtxs = append(projCtxs,
|
||||
p.ProjectCommandContextBuilder.BuildProjectContext(
|
||||
|
||||
@@ -662,6 +662,7 @@ projects:
|
||||
"",
|
||||
"**/*.tf,**/*.tfvars,**/*.tfvars.json,**/terragrunt.hcl,**/.terraform.lock.hcl",
|
||||
false,
|
||||
false,
|
||||
statsScope,
|
||||
logger,
|
||||
terraformClient,
|
||||
@@ -871,6 +872,7 @@ projects:
|
||||
"",
|
||||
"**/*.tf,**/*.tfvars,**/*.tfvars.json,**/terragrunt.hcl,**/.terraform.lock.hcl",
|
||||
false,
|
||||
false,
|
||||
statsScope,
|
||||
logger,
|
||||
terraformClient,
|
||||
@@ -1111,6 +1113,7 @@ workflows:
|
||||
"",
|
||||
"**/*.tf,**/*.tfvars,**/*.tfvars.json,**/terragrunt.hcl,**/.terraform.lock.hcl",
|
||||
false,
|
||||
false,
|
||||
statsScope,
|
||||
logger,
|
||||
terraformClient,
|
||||
@@ -1168,6 +1171,126 @@ workflows:
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuildProjectCmdCtx_WithSilenceNoProjects(t *testing.T) {
|
||||
globalCfg := `
|
||||
repos:
|
||||
- id: /.*/
|
||||
`
|
||||
logger := logging.NewNoopLogger(t)
|
||||
baseRepo := models.Repo{
|
||||
FullName: "owner/repo",
|
||||
VCSHost: models.VCSHost{
|
||||
Hostname: "github.com",
|
||||
},
|
||||
}
|
||||
cases := map[string]struct {
|
||||
repoCfg string
|
||||
expLen int
|
||||
}{
|
||||
// One project matches the repo cfg, return it
|
||||
"matching project": {
|
||||
repoCfg: `
|
||||
version: 3
|
||||
automerge: true
|
||||
projects:
|
||||
- dir: project1
|
||||
workspace: myworkspace
|
||||
`,
|
||||
expLen: 1,
|
||||
},
|
||||
// No project matches the repo cfg, ignore it
|
||||
"no matching project": {
|
||||
repoCfg: `
|
||||
version: 3
|
||||
automerge: true
|
||||
projects:
|
||||
- dir: project2
|
||||
workspace: myworkspace
|
||||
`,
|
||||
expLen: 0,
|
||||
},
|
||||
}
|
||||
|
||||
for name, c := range cases {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
tmp := DirStructure(t, map[string]interface{}{
|
||||
"project1": map[string]interface{}{
|
||||
"main.tf": nil,
|
||||
},
|
||||
"modules": map[string]interface{}{
|
||||
"module": map[string]interface{}{
|
||||
"main.tf": nil,
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
workingDir := NewMockWorkingDir()
|
||||
When(workingDir.Clone(matchers.AnyLoggingSimpleLogging(), matchers.AnyModelsRepo(), matchers.AnyModelsPullRequest(), AnyString())).ThenReturn(tmp, false, nil)
|
||||
vcsClient := vcsmocks.NewMockClient()
|
||||
When(vcsClient.GetModifiedFiles(matchers.AnyModelsRepo(), matchers.AnyModelsPullRequest())).ThenReturn([]string{"modules/module/main.tf"}, nil)
|
||||
|
||||
// Write and parse the global config file.
|
||||
globalCfgPath := filepath.Join(tmp, "global.yaml")
|
||||
Ok(t, os.WriteFile(globalCfgPath, []byte(globalCfg), 0600))
|
||||
parser := &config.ParserValidator{}
|
||||
globalCfgArgs := valid.GlobalCfgArgs{
|
||||
AllowRepoCfg: false,
|
||||
MergeableReq: false,
|
||||
ApprovedReq: false,
|
||||
UnDivergedReq: false,
|
||||
}
|
||||
|
||||
globalCfg, err := parser.ParseGlobalCfg(globalCfgPath, valid.NewGlobalCfgFromArgs(globalCfgArgs))
|
||||
Ok(t, err)
|
||||
|
||||
if c.repoCfg != "" {
|
||||
Ok(t, os.WriteFile(filepath.Join(tmp, "atlantis.yaml"), []byte(c.repoCfg), 0600))
|
||||
}
|
||||
statsScope, _, _ := metrics.NewLoggingScope(logging.NewNoopLogger(t), "atlantis")
|
||||
|
||||
terraformClient := mocks.NewMockClient()
|
||||
|
||||
builder := NewProjectCommandBuilder(
|
||||
false,
|
||||
parser,
|
||||
&DefaultProjectFinder{},
|
||||
vcsClient,
|
||||
workingDir,
|
||||
NewDefaultWorkingDirLocker(),
|
||||
globalCfg,
|
||||
&DefaultPendingPlanFinder{},
|
||||
&CommentParser{ExecutableName: "atlantis"},
|
||||
false,
|
||||
false,
|
||||
"",
|
||||
"**/*.tf,**/*.tfvars,**/*.tfvars.json,**/terragrunt.hcl,**/.terraform.lock.hcl",
|
||||
false,
|
||||
true,
|
||||
statsScope,
|
||||
logger,
|
||||
terraformClient,
|
||||
)
|
||||
|
||||
for _, cmd := range []command.Name{command.Plan, command.Apply} {
|
||||
t.Run(cmd.String(), func(t *testing.T) {
|
||||
ctxs, err := builder.buildProjectCommandCtx(&command.Context{
|
||||
Log: logger,
|
||||
Scope: statsScope,
|
||||
Pull: models.PullRequest{
|
||||
BaseRepo: baseRepo,
|
||||
},
|
||||
PullRequestStatus: models.PullReqStatus{
|
||||
Mergeable: true,
|
||||
},
|
||||
}, cmd, "", "", []string{}, tmp, "project1", "myworkspace", true)
|
||||
Equals(t, c.expLen, len(ctxs))
|
||||
Ok(t, err)
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func mustVersion(v string) *version.Version {
|
||||
vers, err := version.NewVersion(v)
|
||||
if err != nil {
|
||||
|
||||
@@ -165,6 +165,7 @@ projects:
|
||||
"",
|
||||
"**/*.tf,**/*.tfvars,**/*.tfvars.json,**/terragrunt.hcl,**/.terraform.lock.hcl",
|
||||
false,
|
||||
false,
|
||||
scope,
|
||||
logger,
|
||||
terraformClient,
|
||||
@@ -195,6 +196,7 @@ func TestDefaultProjectCommandBuilder_BuildSinglePlanApplyCommand(t *testing.T)
|
||||
Description string
|
||||
AtlantisYAML string
|
||||
Cmd events.CommentCommand
|
||||
Silenced bool
|
||||
ExpCommentArgs []string
|
||||
ExpWorkspace string
|
||||
ExpDir string
|
||||
@@ -203,6 +205,7 @@ func TestDefaultProjectCommandBuilder_BuildSinglePlanApplyCommand(t *testing.T)
|
||||
ExpApplyReqs []string
|
||||
ExpParallelApply bool
|
||||
ExpParallelPlan bool
|
||||
ExpNoProjects bool
|
||||
}{
|
||||
{
|
||||
Description: "no atlantis.yaml",
|
||||
@@ -366,6 +369,22 @@ projects:
|
||||
`,
|
||||
ExpErr: "no project with name \"notconfigured\" is defined in atlantis.yaml",
|
||||
},
|
||||
{
|
||||
Description: "atlantis.yaml with project flag not matching but silenced",
|
||||
Cmd: events.CommentCommand{
|
||||
Name: command.Plan,
|
||||
RepoRelDir: ".",
|
||||
Workspace: "default",
|
||||
ProjectName: "notconfigured",
|
||||
},
|
||||
AtlantisYAML: `
|
||||
version: 3
|
||||
projects:
|
||||
- dir: .
|
||||
`,
|
||||
Silenced: true,
|
||||
ExpNoProjects: true,
|
||||
},
|
||||
{
|
||||
Description: "atlantis.yaml with ParallelPlan Set to true",
|
||||
Cmd: events.CommentCommand{
|
||||
@@ -438,6 +457,7 @@ projects:
|
||||
"",
|
||||
"**/*.tf,**/*.tfvars,**/*.tfvars.json,**/terragrunt.hcl,**/.terraform.lock.hcl",
|
||||
false,
|
||||
c.Silenced,
|
||||
scope,
|
||||
logger,
|
||||
terraformClient,
|
||||
@@ -459,6 +479,10 @@ projects:
|
||||
return
|
||||
}
|
||||
Ok(t, err)
|
||||
if c.ExpNoProjects {
|
||||
Equals(t, 0, len(actCtxs))
|
||||
return
|
||||
}
|
||||
Equals(t, 1, len(actCtxs))
|
||||
actCtx := actCtxs[0]
|
||||
Equals(t, c.ExpDir, actCtx.RepoRelDir)
|
||||
@@ -615,6 +639,7 @@ projects:
|
||||
"",
|
||||
"**/*.tf,**/*.tfvars,**/*.tfvars.json,**/terragrunt.hcl,**/.terraform.lock.hcl",
|
||||
true,
|
||||
false,
|
||||
scope,
|
||||
logger,
|
||||
terraformClient,
|
||||
@@ -800,6 +825,7 @@ projects:
|
||||
"",
|
||||
"**/*.tf,**/*.tfvars,**/*.tfvars.json,**/terragrunt.hcl,**/.terraform.lock.hcl",
|
||||
false,
|
||||
false,
|
||||
scope,
|
||||
logger,
|
||||
terraformClient,
|
||||
@@ -898,6 +924,7 @@ func TestDefaultProjectCommandBuilder_BuildMultiApply(t *testing.T) {
|
||||
"",
|
||||
"**/*.tf,**/*.tfvars,**/*.tfvars.json,**/terragrunt.hcl,**/.terraform.lock.hcl",
|
||||
false,
|
||||
false,
|
||||
scope,
|
||||
logger,
|
||||
terraformClient,
|
||||
@@ -987,6 +1014,7 @@ projects:
|
||||
"",
|
||||
"**/*.tf,**/*.tfvars,**/*.tfvars.json,**/terragrunt.hcl,**/.terraform.lock.hcl",
|
||||
false,
|
||||
false,
|
||||
scope,
|
||||
logger,
|
||||
terraformClient,
|
||||
@@ -1071,6 +1099,7 @@ func TestDefaultProjectCommandBuilder_EscapeArgs(t *testing.T) {
|
||||
"",
|
||||
"**/*.tf,**/*.tfvars,**/*.tfvars.json,**/terragrunt.hcl,**/.terraform.lock.hcl",
|
||||
false,
|
||||
false,
|
||||
scope,
|
||||
logger,
|
||||
terraformClient,
|
||||
@@ -1237,6 +1266,7 @@ projects:
|
||||
"",
|
||||
"**/*.tf,**/*.tfvars,**/*.tfvars.json,**/terragrunt.hcl,**/.terraform.lock.hcl",
|
||||
false,
|
||||
false,
|
||||
scope,
|
||||
logger,
|
||||
terraformClient,
|
||||
@@ -1330,6 +1360,7 @@ parallel_plan: true`,
|
||||
"",
|
||||
"**/*.tf,**/*.tfvars,**/*.tfvars.json,**/terragrunt.hcl,**/.terraform.lock.hcl",
|
||||
false,
|
||||
false,
|
||||
scope,
|
||||
logger,
|
||||
terraformClient,
|
||||
@@ -1393,6 +1424,7 @@ func TestDefaultProjectCommandBuilder_WithPolicyCheckEnabled_BuildAutoplanComman
|
||||
"",
|
||||
"**/*.tf,**/*.tfvars,**/*.tfvars.json,**/terragrunt.hcl,**/.terraform.lock.hcl",
|
||||
false,
|
||||
false,
|
||||
scope,
|
||||
logger,
|
||||
terraformClient,
|
||||
@@ -1479,6 +1511,7 @@ func TestDefaultProjectCommandBuilder_BuildVersionCommand(t *testing.T) {
|
||||
"",
|
||||
"**/*.tf,**/*.tfvars,**/*.tfvars.json,**/terragrunt.hcl,**/.terraform.lock.hcl",
|
||||
false,
|
||||
false,
|
||||
scope,
|
||||
logger,
|
||||
terraformClient,
|
||||
|
||||
@@ -567,6 +567,7 @@ func NewServer(userConfig UserConfig, config Config) (*Server, error) {
|
||||
userConfig.AutoplanModulesFromProjects,
|
||||
userConfig.AutoplanFileList,
|
||||
userConfig.RestrictFileList,
|
||||
userConfig.SilenceNoProjects,
|
||||
statsScope,
|
||||
logger,
|
||||
terraformClient,
|
||||
@@ -730,6 +731,7 @@ func NewServer(userConfig UserConfig, config Config) (*Server, error) {
|
||||
pullReqStatusFetcher,
|
||||
projectCommandBuilder,
|
||||
instrumentedProjectCmdRunner,
|
||||
userConfig.SilenceNoProjects,
|
||||
)
|
||||
|
||||
stateCommandRunner := events.NewStateCommandRunner(
|
||||
|
||||
Reference in New Issue
Block a user