Repository: diggerhq/digger
Pull request #312 (2023-06-02 14:03:25)

fix: check that there at least one command run


Patch:
diff --git a/cmd/digger/main.go b/cmd/digger/main.go
index e5f50610..307157d7 100644
--- a/cmd/digger/main.go
+++ b/cmd/digger/main.go
@@ -74,6 +74,10 @@ func gitHubCI(lock utils.Lock) {
 		githubPrService.PublishComment(prNumber, reply)
 	}
 
+	if len(impactedProjects) == 0 {
+		reportErrorAndExit(githubRepositoryOwner, "No projects impacted", 0)
+	}
+
 	commandsToRunPerProject, coversAllImpactedProjects, err := digger.ConvertGithubEventToCommands(ghEvent, impactedProjects, requestedProject, diggerConfig.Workflows)
 	if err != nil {
 		reportErrorAndExit(githubRepositoryOwner, fmt.Sprintf("Failed to convert GitHub event to commands. %s", err), 7)
@@ -83,12 +87,12 @@ func gitHubCI(lock utils.Lock) {
 
 	planStorage := newPlanStorage(ghToken, repoOwner, repositoryName, prNumber)
 
-	allAppliesSuccess, err := digger.RunCommandsPerProject(commandsToRunPerProject, repoOwner, repositoryName, eventName, prNumber, githubPrService, lock, planStorage, "")
+	allAppliesSuccessful, atLeastOneApply, err := digger.RunCommandsPerProject(commandsToRunPerProject, repoOwner, repositoryName, eventName, prNumber, githubPrService, lock, planStorage, "")
 	if err != nil {
 		reportErrorAndExit(githubRepositoryOwner, fmt.Sprintf("Failed to run commands. %s", err), 8)
 	}
 
-	if diggerConfig.AutoMerge && allAppliesSuccess && coversAllImpactedProjects {
+	if diggerConfig.AutoMerge && allAppliesSuccessful && atLeastOneApply && coversAllImpactedProjects {
 		digger.MergePullRequest(githubPrService, prNumber)
 		println("PR merged successfully")
 	}
diff --git a/pkg/digger/digger.go b/pkg/digger/digger.go
index 1a7d5ec8..0830b95d 100644
--- a/pkg/digger/digger.go
+++ b/pkg/digger/digger.go
@@ -63,11 +63,10 @@ func ProcessGitHubEvent(ghEvent models.Event, diggerConfig *configuration.Digger
 	return impactedProjects, nil, prNumber, nil
 }
 
-func RunCommandsPerProject(commandsPerProject []ProjectCommand, repoOwner string, repoName string, eventName string, prNumber int, ciService ci.CIService, lock utils.Lock, planStorage utils.PlanStorage, workingDir string) (bool, error) {
-	allAppliesSuccess := true
+func RunCommandsPerProject(commandsPerProject []ProjectCommand, repoOwner string, repoName string, eventName string, prNumber int, ciService ci.CIService, lock utils.Lock, planStorage utils.PlanStorage, workingDir string) (bool, bool, error) {
+
 	appliesPerProject := make(map[string]bool)
 	for _, projectCommands := range commandsPerProject {
-		appliesPerProject[projectCommands.ProjectName] = false
 		for _, command := range projectCommands.Commands {
 			projectLock := &utils.ProjectLockImpl{
 				InternalLock: lock,
@@ -109,18 +108,19 @@ func RunCommandsPerProject(commandsPerProject []ProjectCommand, repoOwner string
 				if err != nil {
 					log.Printf("Failed to run digger plan command. %v", err)
 					ciService.SetStatus(prNumber, "failure", projectCommands.ProjectName+"/plan")
-					return false, fmt.Errorf("failed to run digger plan command. %v", err)
+					return false, false, fmt.Errorf("failed to run digger plan command. %v", err)
 				} else if planPerformed {
 					ciService.SetStatus(prNumber, "success", projectCommands.ProjectName+"/plan")
 				}
 			case "digger apply":
+				appliesPerProject[projectCommands.ProjectName] = false
 				usage.SendUsageRecord(repoName, eventName, "apply")
 				ciService.SetStatus(prNumber, "pending", projectCommands.ProjectName+"/apply")
 				applyPerformed, err := diggerExecutor.Apply(prNumber)
 				if err != nil {
 					log.Printf("Failed to run digger apply command. %v", err)
 					ciService.SetStatus(prNumber, "failure", projectCommands.ProjectName+"/apply")
-					return false, fmt.Errorf("failed to run digger apply command. %v", err)
+					return false, false, fmt.Errorf("failed to run digger apply command. %v", err)
 				} else if applyPerformed {
 					ciService.SetStatus(prNumber, "success", projectCommands.ProjectName+"/apply")
 					appliesPerProject[projectCommands.ProjectName] = true
@@ -129,24 +129,29 @@ func RunCommandsPerProject(commandsPerProject []ProjectCommand, repoOwner string
 				usage.SendUsageRecord(repoOwner, eventName, "unlock")
 				err := diggerExecutor.Unlock(prNumber)
 				if err != nil {
-					return false, fmt.Errorf("failed to unlock project. %v", err)
+					return false, false, fmt.Errorf("failed to unlock project. %v", err)
 				}
 			case "digger lock":
 				usage.SendUsageRecord(repoOwner, eventName, "lock")
 				err := diggerExecutor.Lock(prNumber)
 				if err != nil {
-					return false, fmt.Errorf("failed to lock project. %v", err)
+					return false, false, fmt.Errorf("failed to lock project. %v", err)
 				}
 			}
 		}
 	}
 
+	allAppliesSuccess := true
+
 	for _, success := range appliesPerProject {
 		if !success {
 			allAppliesSuccess = false
 		}
 	}
-	return allAppliesSuccess, nil
+
+	atLeastOneApply := len(appliesPerProject) > 0
+
+	return allAppliesSuccess, atLeastOneApply, nil
 }
 
 func MergePullRequest(githubPrService ci.CIService, prNumber int) {


Test patch:
diff --git a/cmd/digger/main_test.go b/cmd/digger/main_test.go
index e500bbf9..84442006 100644
--- a/cmd/digger/main_test.go
+++ b/cmd/digger/main_test.go
@@ -879,7 +879,7 @@ func TestGitHubNewPullRequestContext(t *testing.T) {
 	impactedProjects, requestedProject, prNumber, err := digger.ProcessGitHubEvent(ghEvent, &diggerConfig, prManager)
 
 	commandsToRunPerProject, _, err := digger.ConvertGithubEventToCommands(ghEvent, impactedProjects, requestedProject, map[string]configuration.Workflow{})
-	_, err = digger.RunCommandsPerProject(commandsToRunPerProject, context.RepositoryOwner, context.Repository, eventName, prNumber, prManager, lock, planStorage, "")
+	_, _, err = digger.RunCommandsPerProject(commandsToRunPerProject, context.RepositoryOwner, context.Repository, eventName, prNumber, prManager, lock, planStorage, "")
 
 	assert.NoError(t, err)
 	if err != nil {
@@ -902,9 +902,9 @@ func TestGitHubNewCommentContext(t *testing.T) {
 	impactedProjects, requestedProject, prNumber, err := digger.ProcessGitHubEvent(ghEvent, &diggerConfig, prManager)
 
 	commandsToRunPerProject, _, err := digger.ConvertGithubEventToCommands(ghEvent, impactedProjects, requestedProject, map[string]configuration.Workflow{})
-	_, err = digger.RunCommandsPerProject(commandsToRunPerProject, context.RepositoryOwner, context.Repository, eventName, prNumber, prManager, lock, planStorage, "")
+	_, _, err = digger.RunCommandsPerProject(commandsToRunPerProject, context.RepositoryOwner, context.Repository, eventName, prNumber, prManager, lock, planStorage, "")
 
-	_, err = digger.RunCommandsPerProject(commandsToRunPerProject, context.RepositoryOwner, context.Repository, eventName, prNumber, prManager, lock, planStorage, "")
+	_, _, err = digger.RunCommandsPerProject(commandsToRunPerProject, context.RepositoryOwner, context.Repository, eventName, prNumber, prManager, lock, planStorage, "")
 
 	assert.NoError(t, err)
 	if err != nil {
diff --git a/pkg/integration/integration_test.go b/pkg/integration/integration_test.go
index 21c61d98..cef34326 100644
--- a/pkg/integration/integration_test.go
+++ b/pkg/integration/integration_test.go
@@ -398,7 +398,7 @@ func TestHappyPath(t *testing.T) {
 		PullRequestNumber: prNumber,
 		ZipManager:        zipManager,
 	}
-	_, err = digger.RunCommandsPerProject(commandsToRunPerProject, repoOwner, repositoryName, eventName, prNumber, githubPrService, lock, planStorage, dir)
+	_, _, err = digger.RunCommandsPerProject(commandsToRunPerProject, repoOwner, repositoryName, eventName, prNumber, githubPrService, lock, planStorage, dir)
 	assert.NoError(t, err)
 
 	projectLock := &utils.ProjectLockImpl{
@@ -425,7 +425,7 @@ func TestHappyPath(t *testing.T) {
 	assert.NoError(t, err)
 	commandsToRunPerProject, _, err = digger.ConvertGithubEventToCommands(ghEvent, impactedProjects, requestedProject, diggerConfig.Workflows)
 	assert.NoError(t, err)
-	_, err = digger.RunCommandsPerProject(commandsToRunPerProject, repoOwner, repositoryName, eventName, prNumber, githubPrService, lock, planStorage, dir)
+	_, _, err = digger.RunCommandsPerProject(commandsToRunPerProject, repoOwner, repositoryName, eventName, prNumber, githubPrService, lock, planStorage, dir)
 	assert.NoError(t, err)
 
 	println("--- digger apply comment ---")
@@ -439,7 +439,7 @@ func TestHappyPath(t *testing.T) {
 	assert.NoError(t, err)
 	commandsToRunPerProject, _, err = digger.ConvertGithubEventToCommands(ghEvent, impactedProjects, requestedProject, diggerConfig.Workflows)
 	assert.NoError(t, err)
-	_, err = digger.RunCommandsPerProject(commandsToRunPerProject, repoOwner, repositoryName, eventName, prNumber, githubPrService, lock, planStorage, dir)
+	_, _, err = digger.RunCommandsPerProject(commandsToRunPerProject, repoOwner, repositoryName, eventName, prNumber, githubPrService, lock, planStorage, dir)
 	assert.NoError(t, err)
 
 	projectLock = &utils.ProjectLockImpl{
@@ -463,7 +463,7 @@ func TestHappyPath(t *testing.T) {
 	assert.NoError(t, err)
 	commandsToRunPerProject, _, err = digger.ConvertGithubEventToCommands(ghEvent, impactedProjects, requestedProject, diggerConfig.Workflows)
 	assert.NoError(t, err)
-	_, err = digger.RunCommandsPerProject(commandsToRunPerProject, repoOwner, repositoryName, eventName, prNumber, githubPrService, lock, planStorage, dir)
+	_, _, err = digger.RunCommandsPerProject(commandsToRunPerProject, repoOwner, repositoryName, eventName, prNumber, githubPrService, lock, planStorage, dir)
 	assert.NoError(t, err)
 
 	projectLock = &utils.ProjectLockImpl{
@@ -550,7 +550,7 @@ func TestMultiEnvHappyPath(t *testing.T) {
 		PullRequestNumber: prNumber,
 		ZipManager:        zipManager,
 	}
-	_, err = digger.RunCommandsPerProject(commandsToRunPerProject, repoOwner, repositoryName, eventName, prNumber, githubPrService, &dynamoDbLock, planStorage, dir)
+	_, _, err = digger.RunCommandsPerProject(commandsToRunPerProject, repoOwner, repositoryName, eventName, prNumber, githubPrService, &dynamoDbLock, planStorage, dir)
 	assert.NoError(t, err)
 
 	projectLock := &utils.ProjectLockImpl{
@@ -576,7 +576,7 @@ func TestMultiEnvHappyPath(t *testing.T) {
 	assert.NoError(t, err)
 	commandsToRunPerProject, _, err = digger.ConvertGithubEventToCommands(ghEvent, impactedProjects, requestedProject, diggerConfig.Workflows)
 	assert.NoError(t, err)
-	_, err = digger.RunCommandsPerProject(commandsToRunPerProject, repoOwner, repositoryName, eventName, prNumber, githubPrService, &dynamoDbLock, planStorage, dir)
+	_, _, err = digger.RunCommandsPerProject(commandsToRunPerProject, repoOwner, repositoryName, eventName, prNumber, githubPrService, &dynamoDbLock, planStorage, dir)
 	assert.NoError(t, err)
 
 	println("--- digger apply comment ---")
@@ -590,7 +590,7 @@ func TestMultiEnvHappyPath(t *testing.T) {
 	assert.NoError(t, err)
 	commandsToRunPerProject, _, err = digger.ConvertGithubEventToCommands(ghEvent, impactedProjects, requestedProject, diggerConfig.Workflows)
 	assert.NoError(t, err)
-	_, err = digger.RunCommandsPerProject(commandsToRunPerProject, repoOwner, repositoryName, eventName, prNumber, githubPrService, &dynamoDbLock, planStorage, dir)
+	_, _, err = digger.RunCommandsPerProject(commandsToRunPerProject, repoOwner, repositoryName, eventName, prNumber, githubPrService, &dynamoDbLock, planStorage, dir)
 	assert.NoError(t, err)
 
 	projectLock = &utils.ProjectLockImpl{
@@ -614,7 +614,7 @@ func TestMultiEnvHappyPath(t *testing.T) {
 	assert.NoError(t, err)
 	commandsToRunPerProject, _, err = digger.ConvertGithubEventToCommands(ghEvent, impactedProjects, requestedProject, diggerConfig.Workflows)
 	assert.NoError(t, err)
-	_, err = digger.RunCommandsPerProject(commandsToRunPerProject, repoOwner, repositoryName, eventName, prNumber, githubPrService, &dynamoDbLock, planStorage, dir)
+	_, _, err = digger.RunCommandsPerProject(commandsToRunPerProject, repoOwner, repositoryName, eventName, prNumber, githubPrService, &dynamoDbLock, planStorage, dir)
 	assert.NoError(t, err)
 
 	projectLock = &utils.ProjectLockImpl{
@@ -765,7 +765,7 @@ workflows:
 		PullRequestNumber: prNumber,
 		ZipManager:        zipManager,
 	}
-	_, err = digger.RunCommandsPerProject(commandsToRunPerProject, repoOwner, repositoryName, eventName, prNumber, githubPrService, lock, planStorage, dir)
+	_, _, err = digger.RunCommandsPerProject(commandsToRunPerProject, repoOwner, repositoryName, eventName, prNumber, githubPrService, lock, planStorage, dir)
 	assert.NoError(t, err)
 
 	projectLock := &utils.ProjectLockImpl{
@@ -792,7 +792,7 @@ workflows:
 	assert.NoError(t, err)
 	commandsToRunPerProject, _, err = digger.ConvertGithubEventToCommands(ghEvent, impactedProjects, requestedProject, diggerConfig.Workflows)
 	assert.NoError(t, err)
-	_, err = digger.RunCommandsPerProject(commandsToRunPerProject, repoOwner, repositoryName, eventName, prNumber, githubPrService, lock, planStorage, dir)
+	_, _, err = digger.RunCommandsPerProject(commandsToRunPerProject, repoOwner, repositoryName, eventName, prNumber, githubPrService, lock, planStorage, dir)
 	assert.NoError(t, err)
 
 	println("--- digger apply comment ---")
@@ -806,7 +806,7 @@ workflows:
 	assert.NoError(t, err)
 	commandsToRunPerProject, _, err = digger.ConvertGithubEventToCommands(ghEvent, impactedProjects, requestedProject, diggerConfig.Workflows)
 	assert.NoError(t, err)
-	_, err = digger.RunCommandsPerProject(commandsToRunPerProject, repoOwner, repositoryName, eventName, prNumber, githubPrService, lock, planStorage, dir)
+	_, _, err = digger.RunCommandsPerProject(commandsToRunPerProject, repoOwner, repositoryName, eventName, prNumber, githubPrService, lock, planStorage, dir)
 	assert.NoError(t, err)
 
 	projectLock = &utils.ProjectLockImpl{
@@ -829,7 +829,7 @@ workflows:
 	assert.NoError(t, err)
 	commandsToRunPerProject, _, err = digger.ConvertGithubEventToCommands(ghEvent, impactedProjects, requestedProject, diggerConfig.Workflows)
 	assert.NoError(t, err)
-	_, err = digger.RunCommandsPerProject(commandsToRunPerProject, repoOwner, repositoryName, eventName, prNumber, githubPrService, lock, planStorage, dir)
+	_, _, err = digger.RunCommandsPerProject(commandsToRunPerProject, repoOwner, repositoryName, eventName, prNumber, githubPrService, lock, planStorage, dir)
 	assert.NoError(t, err)
 
 	projectLock = &utils.ProjectLockImpl{