Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
60 commits
Select commit Hold shift + click to select a range
526f0b7
Add Azure Repos support
Spartakovic May 31, 2023
112ae99
renaming
Spartakovic May 31, 2023
cbcfe9b
renaming
Spartakovic May 31, 2023
d2dc1d9
renaming
Spartakovic May 31, 2023
f68b379
renaming
Spartakovic May 31, 2023
d8e6f7f
renaming
Spartakovic May 31, 2023
f7d2da9
renaming
Spartakovic May 31, 2023
43c5f08
renaming
Spartakovic May 31, 2023
35e5f90
renaming
Spartakovic May 31, 2023
283621e
renaming
Spartakovic May 31, 2023
cf0b33a
renaming
Spartakovic May 31, 2023
d98c2d6
renaming
Spartakovic May 31, 2023
b5de46e
renaming
Spartakovic May 31, 2023
e397cb0
renaming
Spartakovic Jun 1, 2023
b390552
renaming
Spartakovic Jun 1, 2023
a000067
renaming
Spartakovic Jun 1, 2023
d56ef3e
renaming
Spartakovic Jun 1, 2023
4d096b5
renaming
Spartakovic Jun 1, 2023
cdca76a
renaming
Spartakovic Jun 1, 2023
79da034
renaming
Spartakovic Jun 1, 2023
3960499
renaming
Spartakovic Jun 1, 2023
c105d80
renaming
Spartakovic Jun 1, 2023
b289897
renaming
Spartakovic Jun 1, 2023
cb39526
renaming
Spartakovic Jun 1, 2023
c491c1d
renaming
Spartakovic Jun 1, 2023
0651c04
renaming
Spartakovic Jun 1, 2023
b1327bd
renaming
Spartakovic Jun 1, 2023
71798b4
renaming
Spartakovic Jun 1, 2023
064257a
renaming
Spartakovic Jun 1, 2023
229fd48
fix
Spartakovic Jun 1, 2023
37d0ec0
fix
Spartakovic Jun 1, 2023
2fc9406
fix
Spartakovic Jun 1, 2023
6abeedf
fix
Spartakovic Jun 1, 2023
9fa3317
fix
Spartakovic Jun 1, 2023
46df924
fix
Spartakovic Jun 1, 2023
7712f35
fix
Spartakovic Jun 1, 2023
aec6ffe
fix
Spartakovic Jun 1, 2023
802e8b7
fix
Spartakovic Jun 1, 2023
360a65a
fix
Spartakovic Jun 1, 2023
8e0f59c
fix
Spartakovic Jun 1, 2023
7fabc14
fix
Spartakovic Jun 1, 2023
25b2d5c
fix
Spartakovic Jun 1, 2023
1f1a7e8
fix
Spartakovic Jun 1, 2023
8b081c8
fix
Spartakovic Jun 1, 2023
d5fbe1d
Revert "fix"
Spartakovic Jun 1, 2023
a4e3453
Revert "Revert "fix""
Spartakovic Jun 1, 2023
2ed49f2
fix
Spartakovic Jun 1, 2023
19970ff
fix
Spartakovic Jun 1, 2023
a2e9cbd
fix
Spartakovic Jun 2, 2023
6c24e01
fix
Spartakovic Jun 2, 2023
22861ea
fix
Spartakovic Jun 2, 2023
a506f70
fix
Spartakovic Jun 2, 2023
221d24f
fix
Spartakovic Jun 2, 2023
b4630f5
prints
Spartakovic Jun 2, 2023
ea3bab4
prints
Spartakovic Jun 2, 2023
e837261
prints
Spartakovic Jun 2, 2023
c3c2456
prints
Spartakovic Jun 2, 2023
99a7d76
Merge branch 'develop' into feat/azure-devops
Spartakovic Jun 2, 2023
f1e2022
Merge branch 'develop' into feat/azure-devops
Spartakovic Jun 5, 2023
79b1586
Merge branch 'develop' into feat/azure-devops
Spartakovic Jun 5, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
111 changes: 96 additions & 15 deletions cmd/digger/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,16 @@ package main

import (
"context"
"digger/pkg/azure"
"digger/pkg/configuration"
"digger/pkg/digger"
"digger/pkg/gcp"
dg_github "digger/pkg/github"
github_models "digger/pkg/github/models"
"digger/pkg/gitlab"
"digger/pkg/locking"
"digger/pkg/models"
"digger/pkg/storage"
"digger/pkg/usage"
"digger/pkg/utils"
"fmt"
Expand All @@ -17,7 +21,7 @@ import (
"strings"
)

func gitHubCI(lock utils.Lock) {
func gitHubCI(lock locking.Lock) {
println("Using GitHub.")
githubRepositoryOwner := os.Getenv("GITHUB_REPOSITORY_OWNER")
if githubRepositoryOwner != "" {
Expand All @@ -36,7 +40,7 @@ func gitHubCI(lock utils.Lock) {
reportErrorAndExit(githubRepositoryOwner, "GITHUB_CONTEXT is not defined", 2)
}

parsedGhContext, err := models.GetGitHubContext(ghContext)
parsedGhContext, err := github_models.GetGitHubContext(ghContext)
if err != nil {
reportErrorAndExit(githubRepositoryOwner, fmt.Sprintf("Failed to parse GitHub context. %s", err), 3)
}
Expand All @@ -50,7 +54,7 @@ func gitHubCI(lock utils.Lock) {
}
println("Digger config read successfully")

lock, err = utils.GetLock()
lock, err = locking.GetLock()
if err != nil {
reportErrorAndExit(githubRepositoryOwner, fmt.Sprintf("Failed to create lock provider. %s", err), 5)
}
Expand All @@ -62,23 +66,26 @@ func gitHubCI(lock utils.Lock) {
repoOwner, repositoryName := splitRepositoryName[0], splitRepositoryName[1]
githubPrService := dg_github.NewGitHubService(ghToken, repositoryName, repoOwner)

impactedProjects, requestedProject, prNumber, err := digger.ProcessGitHubEvent(ghEvent, diggerConfig, githubPrService)
impactedProjects, requestedProject, prNumber, err := dg_github.ProcessGitHubEvent(ghEvent, diggerConfig, githubPrService)
if err != nil {
reportErrorAndExit(githubRepositoryOwner, fmt.Sprintf("Failed to process GitHub event. %s", err), 6)
}
logImpactedProjects(impactedProjects, prNumber)
println("GitHub event processed successfully")

if digger.CheckIfHelpComment(ghEvent) {
if dg_github.CheckIfHelpComment(ghEvent) {
reply := utils.GetCommands()
githubPrService.PublishComment(prNumber, reply)
err := githubPrService.PublishComment(prNumber, reply)
if err != nil {
reportErrorAndExit(githubRepositoryOwner, "Failed to publish help command output", 1)
}
}

if len(impactedProjects) == 0 {
reportErrorAndExit(githubRepositoryOwner, "No projects impacted", 0)
}

commandsToRunPerProject, coversAllImpactedProjects, err := digger.ConvertGithubEventToCommands(ghEvent, impactedProjects, requestedProject, diggerConfig.Workflows)
commandsToRunPerProject, coversAllImpactedProjects, err := dg_github.ConvertGithubEventToCommands(ghEvent, impactedProjects, requestedProject, diggerConfig.Workflows)
if err != nil {
reportErrorAndExit(githubRepositoryOwner, fmt.Sprintf("Failed to convert GitHub event to commands. %s", err), 7)
}
Expand Down Expand Up @@ -108,7 +115,7 @@ func gitHubCI(lock utils.Lock) {
}()
}

func gitLabCI(lock utils.Lock) {
func gitLabCI(lock locking.Lock) {
println("Using GitLab.")

projectNamespace := os.Getenv("CI_PROJECT_NAMESPACE")
Expand Down Expand Up @@ -170,6 +177,7 @@ func gitLabCI(lock utils.Lock) {
fmt.Printf("command: %s, project: %s\n", strings.Join(v.Commands, ", "), v.ProjectName)
}

//planStorage := newPlanStorage(ghToken, repoOwner, repositoryName, prNumber)
planStorage := newPlanStorage(gitlabToken, projectNamespace, projectName, *gitLabContext.MergeRequestIId)

allAppliesSuccess, err := gitlab.RunCommandsPerProject(commandsToRunPerProject, *gitLabContext, diggerConfig, gitlabService, lock, planStorage, currentDir)
Expand All @@ -194,6 +202,77 @@ func gitLabCI(lock utils.Lock) {
}()
}

func azureCI(lock locking.Lock) {
fmt.Println("> Azure CI detected")
azureContext := os.Getenv("AZURE_CONTEXT")
azureToken := os.Getenv("AZURE_TOKEN")
if azureToken == "" {
fmt.Println("AZURE_TOKEN is empty")
}
parsedAzureContext, err := azure.GetAzureReposContext(azureContext)
if err != nil {
fmt.Printf("failed to parse Azure context. %s\n", err.Error())
os.Exit(4)
}

walker := configuration.FileSystemDirWalker{}
currentDir, err := os.Getwd()
if err != nil {
reportErrorAndExit(parsedAzureContext.BaseUrl, fmt.Sprintf("Failed to get current dir. %s", err), 4)
}
fmt.Printf("main: working dir: %s \n", currentDir)

diggerConfig, err := configuration.NewDiggerConfig(currentDir, &walker)
if err != nil {
reportErrorAndExit(parsedAzureContext.BaseUrl, fmt.Sprintf("Failed to read Digger config. %s", err), 4)
}
fmt.Println("Digger config read successfully")

azureService, err := azure.NewAzureReposService(azureToken, parsedAzureContext.BaseUrl, parsedAzureContext.ProjectName, parsedAzureContext.RepositoryId)
if err != nil {
reportErrorAndExit(parsedAzureContext.BaseUrl, fmt.Sprintf("Failed to initialise azure service. %s", err), 5)
}

impactedProjects, requestedProject, prNumber, err := azure.ProcessAzureReposEvent(parsedAzureContext.Event, diggerConfig, azureService)
if err != nil {
reportErrorAndExit(parsedAzureContext.BaseUrl, fmt.Sprintf("Failed to process Azure event. %s", err), 6)
}
fmt.Println("Azure event processed successfully")

commandsToRunPerProject, coversAllImpactedProjects, err := azure.ConvertAzureEventToCommands(parsedAzureContext, impactedProjects, requestedProject, diggerConfig.Workflows)
if err != nil {
reportErrorAndExit(parsedAzureContext.BaseUrl, fmt.Sprintf("Failed to convert event to command. %s", err), 7)

}
fmt.Println(fmt.Sprintf("Azure event converted to commands successfully: %v", commandsToRunPerProject))

for _, v := range commandsToRunPerProject {
fmt.Printf("command: %s, project: %s\n", strings.Join(v.Commands, ", "), v.ProjectName)
}

var planStorage storage.PlanStorage

allAppliesSuccess, atLeastOneApply, err := digger.RunCommandsPerProject(commandsToRunPerProject, parsedAzureContext.ProjectName, parsedAzureContext.ProjectName, parsedAzureContext.EventType, prNumber, azureService, lock, planStorage, currentDir)
if err != nil {
reportErrorAndExit(parsedAzureContext.BaseUrl, fmt.Sprintf("Failed to run commands. %s", err), 8)
}

if diggerConfig.AutoMerge && allAppliesSuccess && atLeastOneApply && coversAllImpactedProjects {
digger.MergePullRequest(azureService, prNumber)
fmt.Println("PR merged successfully")
}

println("Commands executed successfully")

reportErrorAndExit(parsedAzureContext.BaseUrl, "Digger finished successfully", 0)

defer func() {
if r := recover(); r != nil {
reportErrorAndExit(parsedAzureContext.BaseUrl, fmt.Sprintf("Panic occurred. %s", r), 1)
}
}()
}

/*
Exit codes:
0 - No errors
Expand All @@ -219,7 +298,7 @@ func main() {
os.Exit(0)
}

lock, err := utils.GetLock()
lock, err := locking.GetLock()
if err != nil {
fmt.Printf("Failed to create lock provider. %s\n", err)
os.Exit(2)
Expand All @@ -232,20 +311,22 @@ func main() {
gitHubCI(lock)
case digger.GitLab:
gitLabCI(lock)
case digger.Azure:
azureCI(lock)
case digger.BitBucket:
case digger.None:
print("No CI detected.")
os.Exit(10)
}
}

func newPlanStorage(ghToken string, repoOwner string, repositoryName string, prNumber int) utils.PlanStorage {
var planStorage utils.PlanStorage
func newPlanStorage(ghToken string, repoOwner string, repositoryName string, prNumber int) storage.PlanStorage {
var planStorage storage.PlanStorage

uploadDestination := strings.ToLower(os.Getenv("PLAN_UPLOAD_DESTINATION"))
if uploadDestination == "github" {
zipManager := utils.Zipper{}
planStorage = &utils.GithubPlanStorage{
planStorage = &storage.GithubPlanStorage{
Client: github.NewTokenClient(context.Background(), ghToken),
Owner: repoOwner,
RepoName: repositoryName,
Expand All @@ -259,7 +340,7 @@ func newPlanStorage(ghToken string, repoOwner string, repositoryName string, prN
reportErrorAndExit(repoOwner, fmt.Sprintf("GOOGLE_STORAGE_BUCKET is not defined"), 9)
}
bucket := client.Bucket(bucketName)
planStorage = &utils.PlanStorageGcp{
planStorage = &storage.PlanStorageGcp{
Client: client,
Bucket: bucket,
Context: ctx,
Expand All @@ -279,7 +360,7 @@ func logImpactedProjects(projects []configuration.Project, prNumber int) {
log.Print(logMessage)
}

func logCommands(projectCommands []digger.ProjectCommand) {
func logCommands(projectCommands []models.ProjectCommand) {
logMessage := fmt.Sprintf("Following commands are going to be executed:\n")
for _, pc := range projectCommands {
logMessage += fmt.Sprintf("project: %s: commands: ", pc.ProjectName)
Expand All @@ -292,7 +373,7 @@ func logCommands(projectCommands []digger.ProjectCommand) {
}

func reportErrorAndExit(repoOwner string, message string, exitCode int) {
fmt.Printf(message)
fmt.Println(message)
err := usage.SendLogRecord(repoOwner, message)
if err != nil {
fmt.Printf("Failed to send log record. %s\n", err)
Expand Down
19 changes: 10 additions & 9 deletions cmd/digger/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ package main
import (
"digger/pkg/configuration"
"digger/pkg/digger"
"digger/pkg/models"
"digger/pkg/github"
"digger/pkg/github/models"
"digger/pkg/utils"
"fmt"
"testing"
Expand Down Expand Up @@ -863,7 +864,7 @@ var githubInvalidContextJson = `{

func TestGitHubNewPullRequestContext(t *testing.T) {

context, err := digger.GetGitHubContext(githubContextNewPullRequestJson)
context, err := github.GetGitHubContext(githubContextNewPullRequestJson)
assert.NoError(t, err)
if err != nil {
fmt.Println(err)
Expand All @@ -876,9 +877,9 @@ func TestGitHubNewPullRequestContext(t *testing.T) {
prManager := &utils.MockPullRequestManager{ChangedFiles: []string{"dev/test.tf"}}
planStorage := &utils.MockPlanStorage{}

impactedProjects, requestedProject, prNumber, err := digger.ProcessGitHubEvent(ghEvent, &diggerConfig, prManager)
impactedProjects, requestedProject, prNumber, err := github.ProcessGitHubEvent(ghEvent, &diggerConfig, prManager)

commandsToRunPerProject, _, err := digger.ConvertGithubEventToCommands(ghEvent, impactedProjects, requestedProject, map[string]configuration.Workflow{})
commandsToRunPerProject, _, err := github.ConvertGithubEventToCommands(ghEvent, impactedProjects, requestedProject, map[string]configuration.Workflow{})
_, _, err = digger.RunCommandsPerProject(commandsToRunPerProject, context.RepositoryOwner, context.Repository, eventName, prNumber, prManager, lock, planStorage, "")

assert.NoError(t, err)
Expand All @@ -899,9 +900,9 @@ func TestGitHubNewCommentContext(t *testing.T) {
lock := &utils.MockLock{}
prManager := &utils.MockPullRequestManager{ChangedFiles: []string{"dev/test.tf"}}
planStorage := &utils.MockPlanStorage{}
impactedProjects, requestedProject, prNumber, err := digger.ProcessGitHubEvent(ghEvent, &diggerConfig, prManager)
impactedProjects, requestedProject, prNumber, err := github.ProcessGitHubEvent(ghEvent, &diggerConfig, prManager)

commandsToRunPerProject, _, err := digger.ConvertGithubEventToCommands(ghEvent, impactedProjects, requestedProject, map[string]configuration.Workflow{})
commandsToRunPerProject, _, err := github.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, "")
Expand All @@ -921,7 +922,7 @@ func TestInvalidGitHubContext(t *testing.T) {
}

func TestGitHubNewPullRequestInMultiEnvProjectContext(t *testing.T) {
context, err := digger.GetGitHubContext(githubContextNewPullRequestJson)
context, err := github.GetGitHubContext(githubContextNewPullRequestJson)
assert.NoError(t, err)
ghEvent := context.Event
pullRequestNumber := 11
Expand Down Expand Up @@ -965,9 +966,9 @@ func TestGitHubNewPullRequestInMultiEnvProjectContext(t *testing.T) {
// PullRequestManager Mock
prManager := &utils.MockPullRequestManager{ChangedFiles: []string{"dev/test.tf"}}
lock := &utils.MockLock{}
impactedProjects, requestedProject, prNumber, err := digger.ProcessGitHubEvent(ghEvent, &diggerConfig, prManager)
impactedProjects, requestedProject, prNumber, err := github.ProcessGitHubEvent(ghEvent, &diggerConfig, prManager)
assert.NoError(t, err)
commandsToRunPerProject, _, err := digger.ConvertGithubEventToCommands(ghEvent, impactedProjects, requestedProject, workflows)
commandsToRunPerProject, _, err := github.ConvertGithubEventToCommands(ghEvent, impactedProjects, requestedProject, workflows)
spew.Dump(lock.MapLock)
assert.Equal(t, pullRequestNumber, prNumber)
assert.Equal(t, 1, len(commandsToRunPerProject))
Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ require (
github.com/caarlos0/env/v7 v7.1.0
github.com/google/go-github/v51 v51.0.0
github.com/google/uuid v1.3.0
github.com/microsoft/azure-devops-go-api/azuredevops v1.0.0-b5
github.com/stretchr/testify v1.8.4
github.com/xanzy/go-gitlab v0.84.0
gopkg.in/yaml.v3 v3.0.1
Expand Down
5 changes: 3 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ github.com/google/go-github/v51 v51.0.0/go.mod h1:kZj/rn/c1lSUbr/PFWl2hhusPV7a5X
github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8=
github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU=
github.com/google/martian/v3 v3.3.2 h1:IqNFLAmvJOgVlpdEBiQbDc2EwKW77amAycfTuWKdfvw=
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
Expand All @@ -109,6 +110,8 @@ github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
github.com/microsoft/azure-devops-go-api/azuredevops v1.0.0-b5 h1:YH424zrwLTlyHSH/GzLMJeu5zhYVZSx5RQxGKm1h96s=
github.com/microsoft/azure-devops-go-api/azuredevops v1.0.0-b5/go.mod h1:PoGiBqKSQK1vIfQ+yVaFcGjDySHvym6FM1cNYnwzbrY=
github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 h1:KoWmjvw+nsYOo29YJK9vDA65RGE3NrOnUtO7a+RF9HU=
github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8/go.mod h1:HKlIX3XHQyzLZPlr7++PzdhaXEj94dEiJgZDTsxEqUI=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
Expand Down Expand Up @@ -231,10 +234,8 @@ google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQ
google.golang.org/protobuf v1.29.1 h1:7QBf+IK2gx70Ap/hDsOmam3GE0v9HicjfEdAxE62UoM=
google.golang.org/protobuf v1.29.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
Expand Down
Loading