From 92f20fc89fa39503b3622f429faaaecdf1633f25 Mon Sep 17 00:00:00 2001 From: Roee Landesman <155578531+ri-roee@users.noreply.github.com> Date: Wed, 6 Mar 2024 09:34:08 -0800 Subject: [PATCH] Add traverse_to_nested_projects flag (#1245) * Adds traverse_to_nested_projects flag, tests, and docs --------- Signed-off-by: Roee Landesman Co-authored-by: Mohamed Habib --- docs/howto/generate-projects.mdx | 10 ++ docs/reference/digger.yml.mdx | 211 +++++++++++------------ libs/digger_config/config.go | 1 + libs/digger_config/converters.go | 7 + libs/digger_config/digger_config.go | 23 ++- libs/digger_config/digger_config_test.go | 43 +++++ libs/digger_config/yaml.go | 1 + 7 files changed, 181 insertions(+), 115 deletions(-) diff --git a/docs/howto/generate-projects.mdx b/docs/howto/generate-projects.mdx index a2b699970..e0dbafd31 100644 --- a/docs/howto/generate-projects.mdx +++ b/docs/howto/generate-projects.mdx @@ -30,5 +30,15 @@ generate_projects: [Demo repo](https://github.com/diggerhq/generate_projects_demo) +# Traversing nested directories +You can optionally set the top-level argument `traverse_to_nested_projects` to generate a project for all sub-directories: +``` +traverse_to_nested_projects: true +generate_projects: + blocks: + - include: "environments/core/**" +``` + +This will create a project for all sub-directories under environments/core. If set to `false`, only the first directory with a .tf file will be evaluated. diff --git a/docs/reference/digger.yml.mdx b/docs/reference/digger.yml.mdx index 76f82b1bb..aa651cd9b 100644 --- a/docs/reference/digger.yml.mdx +++ b/docs/reference/digger.yml.mdx @@ -6,34 +6,35 @@ You can configure Digger by dropping a `digger.yml` file at the root level of yo ```yml projects: -- name: my-first-app - dir: app-one -- name: my-second-app - dir: app-two + - name: my-first-app + dir: app-one + - name: my-second-app + dir: app-two auto_merge: true ``` **Note:** you can also name your Digger configuration file differently, and specify its name using the `digger-filename` input at GitHub Action level. -**** +--- ## Example using all keys ```yml +traverse_to_nested_projects: true auto_merge: false projects: -- name: prod - dir: prod - workspace: default - terragrunt: false - workflow: prod - include_patterns: ["../modules/**"] - exclude_patterns: [] -- name: staging - dir: staging - workflow: staging - include_patterns: ["../modules/**"] - exclude_patterns: [] + - name: prod + dir: prod + workspace: default + terragrunt: false + workflow: prod + include_patterns: ["../modules/**"] + exclude_patterns: [] + - name: staging + dir: staging + workflow: staging + include_patterns: ["../modules/**"] + exclude_patterns: [] generate_projects: include: "../projects/**" exclude: "../.terraform/**" @@ -41,24 +42,24 @@ workflows: staging: env_vars: state: - - name: TF_LOG - value: trace + - name: TF_LOG + value: trace commands: - - name: TF_LOG - value: trace + - name: TF_LOG + value: trace plan: steps: - - init: - extra_args: ["backend-config=../backend.hcl"] - - run: "echo hello world" - - plan + - init: + extra_args: ["backend-config=../backend.hcl"] + - run: "echo hello world" + - plan apply: steps: - - run: "echo hello world" - shell: zsh - - init - - apply: - extra_args: ["-compact-warnings"] + - run: "echo hello world" + shell: zsh + - init + - apply: + extra_args: ["-compact-warnings"] workflow_configuration: on_pull_request_pushed: ["digger plan"] on_pull_request_closed: ["digger unlock"] @@ -66,121 +67,121 @@ workflows: prod: env_vars: state: - - name: AWS_ACCESS_KEY_ID - value_from: PROD_BACKEND_TF_ACCESS_KEY_ID - - name: AWS_SECRET_ACCESS_KEY - value_from: PROD_BACKEND_TF_SECRET__ACCESS_KEY + - name: AWS_ACCESS_KEY_ID + value_from: PROD_BACKEND_TF_ACCESS_KEY_ID + - name: AWS_SECRET_ACCESS_KEY + value_from: PROD_BACKEND_TF_SECRET__ACCESS_KEY commands: - - name: AWS_ACCESS_KEY_ID - value_from: PROD_TF_ACCESS_KEY_ID - - name: AWS_SECRET_ACCESS_KEY - value_from: PROD_TF_SECRET_ACCESS_KEY + - name: AWS_ACCESS_KEY_ID + value_from: PROD_TF_ACCESS_KEY_ID + - name: AWS_SECRET_ACCESS_KEY + value_from: PROD_TF_SECRET_ACCESS_KEY plan: steps: - - run: "checkov -d ." - - init - - plan + - run: "checkov -d ." + - init + - plan apply: steps: - - run: "terraform fmt -check -diff -recursive" - shell: zsh - - init - - apply + - run: "terraform fmt -check -diff -recursive" + shell: zsh + - init + - apply workflow_configuration: on_pull_request_pushed: ["digger plan"] on_pull_request_closed: ["digger unlock"] on_commit_to_default: ["digger unlock"] - ``` ## Reference ### Top-level -| Key | Type | Default | Required | Description | Notes | -| -------------------- | ---------------------------------------------------------------- | ------- | -------- | ------------------------------------------------------ | ----- | -| telemetry | boolean | true | no | allows collecting anonymised usage and debugging data | | -| auto\_merge | boolean | false | no | automatically merge pull requests when all checks pass | | -| projects | array of [Projects](/reference/digger.yml#project) | \[\] | no | list of projects to manage | | -| generate\_projects | [GenerateProjects](/reference/digger.yml#generateprojects) | {} | no | generate projects from a directory structure | | -| workflows | map of [Workflows](/reference/digger.yml#workflows) | {} | no | workflows and configurations to run on events | | +| Key | Type | Default | Required | Description | Notes | +| --------------------------- | ---------------------------------------------------------- | ------- | -------- | ------------------------------------------------------ | ----- | +| telemetry | boolean | true | no | allows collecting anonymised usage and debugging data | | +| auto_merge | boolean | false | no | automatically merge pull requests when all checks pass | | +| projects | array of [Projects](/reference/digger.yml#project) | \[\] | no | list of projects to manage | | +| generate_projects | [GenerateProjects](/reference/digger.yml#generateprojects) | {} | no | generate projects from a directory structure | | +| workflows | map of [Workflows](/reference/digger.yml#workflows) | {} | no | workflows and configurations to run on events | | +| traverse_to_nested_projects | boolean | false | no | enabled traversal of nested directories | | ### Project -| Key | Type | Default | Required | Description | Notes | -| ------------------------ | ---------------------------------------------------- | ------------------- | --------- | ------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------- | -| name | string | | yes | name of the project | must be unique | -| dir | string | | yes | directory containing the project | | -| workspace | string | default | no | terraform workspace to use | | -| workflow_file | string | digger_workflow.yml | no | The digger workflow file to run | This argument only works with orchestrator backend | -| terragrunt | boolean | false | no | whether to use terragrunt | | -| workflow | string | default | no | workflow to use | default workflow will be created for you described in workflow section | -| include\_patterns | array of strings | \[\] | no | list of directory glob patterns to include, e.g. `./modules` | see [Include / Exclude Patterns](/howto/include-exclude-patterns) | -| exclude\_patterns | array of strings | \[\] | no | list of directory glob patterns to exclude, e.g. `.terraform` | see [Include / Exclude Patterns](/howto/include-exclude-patterns) | -| depends\_on | array of strings | \[\] | no | list of project names that need to be completed before the project | it doesn't force terraform run, but affects the order of commands for projects modified in the current PR | -| aws_role_to_assume | [RoleToAssume](/reference/digger.yml#roletoassume) | | no | A string representing the AWS role to assume for this project | | +| Key | Type | Default | Required | Description | Notes | +| ------------------------ | ---------------------------------------------------- | ------- | -------- | ------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------- | +| name | string | | yes | name of the project | must be unique | +| dir | string | | yes | directory containing the project | | +| workspace | string | default | no | terraform workspace to use | | +| terragrunt | boolean | false | no | whether to use terragrunt | | +| workflow | string | default | no | workflow to use | default workflow will be created for you described in workflow section | +| include\_patterns | array of strings | \[\] | no | list of directory glob patterns to include, e.g. `./modules` | see [Include / Exclude Patterns](/howto/include-exclude-patterns) | +| exclude\_patterns | array of strings | \[\] | no | list of directory glob patterns to exclude, e.g. `.terraform` | see [Include / Exclude Patterns](/howto/include-exclude-patterns) | +| depends\_on | array of strings | \[\] | no | list of project names that need to be completed before the project | it doesn't force terraform run, but affects the order of commands for projects modified in the current PR | +| aws_role_to_assume | [RoleToAssume](/reference/digger.yml#roletoassume) | | no | A string representing the AWS role to assume for this project | | ### GenerateProjects | Key | Type | Default | Required | Description | Notes | | ------- | ------ | ------- | -------- | ----------------------------------- | ----- | -| include | string | | no | glob pattern to include directories | | -| exclude | string | | no | glob pattern to exclude directories | | +| include | string | | no | glob pattern to include directories | | +| exclude | string | | no | glob pattern to exclude directories | | ### Workflows -| Key | Type | Default | Required | Description | Notes | -| ----------------------- | -------------------------------------------------------------------------- | ------- | -------- | ------------------------------------------ | ----- | -| env\_vars | [EnvVars](/reference/digger.yml#envvars) | {} | no | environment variables to set for per stage | | -| plan | [Plan](/reference/digger.yml#plan) | {} | no | plan stage configuration | | -| apply | [Apply](/reference/digger.yml#apply) | {} | no | apply stage configuration | | -| workflow\_configuration | [WorkflowConfiguration](/reference/digger.yml#workflowconfiguration) | {} | no | describes how to react to CI events | | +| Key | Type | Default | Required | Description | Notes | +| ---------------------- | -------------------------------------------------------------------- | ------- | -------- | ------------------------------------------ | ----- | +| env_vars | [EnvVars](/reference/digger.yml#envvars) | {} | no | environment variables to set for per stage | | +| plan | [Plan](/reference/digger.yml#plan) | {} | no | plan stage configuration | | +| apply | [Apply](/reference/digger.yml#apply) | {} | no | apply stage configuration | | +| workflow_configuration | [WorkflowConfiguration](/reference/digger.yml#workflowconfiguration) | {} | no | describes how to react to CI events | | ### EnvVars -| Key | Type | Default | Required | Description | Notes | -| -------- | ---------------------------------------------------- | ------- | -------- | --------------------------------------------------------- | ------------------------------------------------------------------------- | +| Key | Type | Default | Required | Description | Notes | +| -------- | ----------------------------------------------- | ------- | -------- | --------------------------------------------------------- | ------------------------------------------------------------------------- | | state | array of [EnvVar](/reference/digger.yml#envvar) | \[\] | no | environment variables to set for terraform init stage | can be use to set different credentials for remote backend for example | | commands | array of [EnvVar](/reference/digger.yml#envvar) | \[\] | no | environment variables to set for other terraform commands | can be use to set different credentials for actual managed infrastructure | ### EnvVar -| Key | Type | Default | Required | Description | Notes | -| ----------- | ------ | ------- | -------- | ------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| name | string | | yes | name of the environment variable | | -| value\_from | string | | yes | name of the other environment variable to get the value from | this can be used for secrets. For example you set a secret from some secret manager (e.g. github secrets) as environment variable and the remap it to another variable. E.g. setting DEV\_TF\_ACCESS\_KEY as a secret in github action, but then remap it into AWS\_ACCESS\_KEY during terraform apply command execution | -| value | string | | yes | value of the environment variable | this value will have a preference over value\_from field if both are set | +| Key | Type | Default | Required | Description | Notes | +| ---------- | ------ | ------- | -------- | ------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| name | string | | yes | name of the environment variable | | +| value_from | string | | yes | name of the other environment variable to get the value from | this can be used for secrets. For example you set a secret from some secret manager (e.g. github secrets) as environment variable and the remap it to another variable. E.g. setting DEV_TF_ACCESS_KEY as a secret in github action, but then remap it into AWS_ACCESS_KEY during terraform apply command execution | +| value | string | | yes | value of the environment variable | this value will have a preference over value_from field if both are set | ### RoleToAssume -| Key | Type | Default | Required | Description | Notes | -| ----------- | ------ | ------- | -------- | ------------------------------------------------------------ | --------------------------------------| -| state | string | | yes | ARN of the role to assume for state backend | | -| command | string | | yes | ARN of the role to assume for commands e.g. plan / apply | | + +| Key | Type | Default | Required | Description | Notes | +| ------- | ------ | ------- | -------- | -------------------------------------------------------- | ----- | +| state | string | | yes | ARN of the role to assume for state backend | | +| command | string | | yes | ARN of the role to assume for commands e.g. plan / apply | | ### Plan -| Key | Type | Default | Required | Description | Notes | -| ----- | ------------------------------------------------ | ------- | -------- | -------------------------------------- | ----- | -| steps | array of [Step](/reference/digger.yml#step) | \[\] | no | list of steps to run during plan stage | | +| Key | Type | Default | Required | Description | Notes | +| ----- | ------------------------------------------- | ------- | -------- | -------------------------------------- | ----- | +| steps | array of [Step](/reference/digger.yml#step) | \[\] | no | list of steps to run during plan stage | | ### Apply -| Key | Type | Default | Required | Description | Notes | -| ----- | ------------------------------------------------ | ------- | -------- | --------------------------------------- | ----- | -| steps | array of [Step](/reference/digger.yml#step) | \[\] | no | list of steps to run during apply stage | | +| Key | Type | Default | Required | Description | Notes | +| ----- | ------------------------------------------- | ------- | -------- | --------------------------------------- | ----- | +| steps | array of [Step](/reference/digger.yml#step) | \[\] | no | list of steps to run during apply stage | | ### WorkflowConfiguration -| Key | Type | Default | Required | Description | Notes | -| ------------------------- | ----------------------------------------------------------------------- | ------- | -------- | ------------------------------------------------------------- | ----- | -| on\_pull\_request\_pushed | array of enums\[digger plan, digger apply, digger lock, digger unlock\] | \[\] | no | list of stages to run when pull request is pushed | | -| on\_pull\_request\_closed | array of enums\[digger plan, digger apply, digger lock, digger unlock\] | \[\] | no | list of stages to run when pull request is closed | | -| on\_commit\_to\_default | array of enums\[digger plan, digger apply, digger lock, digger unlock\] | \[\] | no | list of stages to run when commit is pushed to default branch | | +| Key | Type | Default | Required | Description | Notes | +| ---------------------- | ----------------------------------------------------------------------- | ------- | -------- | ------------------------------------------------------------- | ----- | +| on_pull_request_pushed | array of enums\[digger plan, digger apply, digger lock, digger unlock\] | \[\] | no | list of stages to run when pull request is pushed | | +| on_pull_request_closed | array of enums\[digger plan, digger apply, digger lock, digger unlock\] | \[\] | no | list of stages to run when pull request is closed | | +| on_commit_to_default | array of enums\[digger plan, digger apply, digger lock, digger unlock\] | \[\] | no | list of stages to run when commit is pushed to default branch | | ### Step -| Key | Type | Default | Required | Description | Notes | -| ----- | -------------------------------------------------------------------- | ------- | -------- | -------------------- | -------------------------------------------------- | +| Key | Type | Default | Required | Description | Notes | +| ----- | --------------------------------------------------------------- | ------- | -------- | -------------------- | -------------------------------------------------- | | init | [Init](/reference/digger.yml#init-apply-plan-as-object)/string | {}/"" | no | terraform init step | if missing from array of steps, it will be skipped | | plan | [Plan](/reference/digger.yml#init-apply-plan-as-object)/string | {}/"" | no | terraform plan step | if missing from array of steps, it will be skipped | | apply | [Apply](/reference/digger.yml#init-apply-plan-as-object)/string | {}/"" | no | terraform apply step | if missing from array of steps, it will be skipped | @@ -188,15 +189,15 @@ workflows: ### Init/Apply/Plan as object -| Key | Type | Default | Required | Description | Notes | -| ----------- | ---------------- | ------- | -------- | ---------------------------------------------------- | ----- | -| extra\_args | array of strings | \[\] | no | extra arguments to pass to terraform init/plan/apply | | +| Key | Type | Default | Required | Description | Notes | +| ---------- | ---------------- | ------- | -------- | ---------------------------------------------------- | ----- | +| extra_args | array of strings | \[\] | no | extra arguments to pass to terraform init/plan/apply | | ### Run as object | Key | Type | Default | Required | Description | Notes | | ----- | ------ | ------- | -------- | ------------------------------- | ------------- | -| shell | string | | yes | shell to use to run the command | zsh/bash etc. | +| shell | string | | yes | shell to use to run the command | zsh/bash etc. | ### Default workflow @@ -213,12 +214,11 @@ workflow_configuration: Workflow configuration describes how to react to CI events. It has 3 sections: -* on\_pull\_request\_pushed - describes what to do when pull request is created or updated +- on_pull_request_pushed - describes what to do when pull request is created or updated -* on\_pull\_request\_closed - describes what to do when pull request is closed - -* on\_commit\_to\_default - describes what to do when pull request is merged into default branch +- on_pull_request_closed - describes what to do when pull request is closed +- on_commit_to_default - describes what to do when pull request is merged into default branch ## Projects @@ -229,4 +229,3 @@ You can run plan / apply in a specified project by using the -p option in Github ```bash digger apply -p my-second-app ``` - diff --git a/libs/digger_config/config.go b/libs/digger_config/config.go index e3fa04d25..11f60a13c 100644 --- a/libs/digger_config/config.go +++ b/libs/digger_config/config.go @@ -7,6 +7,7 @@ type DiggerConfig struct { Telemetry bool Workflows map[string]Workflow MentionDriftedProjectsInPR bool + TraverseToNestedProjects bool } type DependencyConfiguration struct { diff --git a/libs/digger_config/converters.go b/libs/digger_config/converters.go index 38738cf79..bef40ceb2 100644 --- a/libs/digger_config/converters.go +++ b/libs/digger_config/converters.go @@ -3,6 +3,7 @@ package digger_config import ( "errors" "fmt" + "github.com/dominikbraun/graph" ) @@ -161,6 +162,12 @@ func ConvertDiggerYamlToConfig(diggerYaml *DiggerConfigYaml) (*DiggerConfig, gra diggerConfig.Telemetry = true } + if diggerYaml.TraverseToNestedProjects != nil { + diggerConfig.TraverseToNestedProjects = *diggerYaml.TraverseToNestedProjects + } else { + diggerConfig.TraverseToNestedProjects = false + } + // if workflow block is not specified in yaml we create a default one, and add it to every project if diggerYaml.Workflows != nil { workflows := copyWorkflows(diggerYaml.Workflows) diff --git a/libs/digger_config/digger_config.go b/libs/digger_config/digger_config.go index ccf6fdf9a..305ab7bc1 100644 --- a/libs/digger_config/digger_config.go +++ b/libs/digger_config/digger_config.go @@ -16,7 +16,7 @@ import ( ) type DirWalker interface { - GetDirs(workingDir string) ([]string, error) + GetDirs(workingDir string, config DiggerConfigYaml) ([]string, error) } type FileSystemTopLevelTerraformDirWalker struct { @@ -46,7 +46,7 @@ func GetFilesWithExtension(workingDir string, ext string) ([]string, error) { return files, nil } -func (walker *FileSystemTopLevelTerraformDirWalker) GetDirs(workingDir string) ([]string, error) { +func (walker *FileSystemTopLevelTerraformDirWalker) GetDirs(workingDir string, configYaml *DiggerConfigYaml) ([]string, error) { var dirs []string err := filepath.Walk(workingDir, func(path string, info os.FileInfo, err error) error { @@ -61,7 +61,9 @@ func (walker *FileSystemTopLevelTerraformDirWalker) GetDirs(workingDir string) ( terraformFiles, _ := GetFilesWithExtension(path, ".tf") if len(terraformFiles) > 0 { dirs = append(dirs, strings.ReplaceAll(path, workingDir+string(os.PathSeparator), "")) - return filepath.SkipDir + if configYaml.TraverseToNestedProjects != nil && !*configYaml.TraverseToNestedProjects { + return filepath.SkipDir + } } } return nil @@ -72,7 +74,7 @@ func (walker *FileSystemTopLevelTerraformDirWalker) GetDirs(workingDir string) ( return dirs, nil } -func (walker *FileSystemModuleDirWalker) GetDirs(workingDir string) ([]string, error) { +func (walker *FileSystemModuleDirWalker) GetDirs(workingDir string, configYaml *DiggerConfigYaml) ([]string, error) { var dirs []string err := filepath.Walk(workingDir, func(path string, info os.FileInfo, err error) error { @@ -92,7 +94,7 @@ func (walker *FileSystemModuleDirWalker) GetDirs(workingDir string) ([]string, e return dirs, nil } -func (walker *FileSystemTerragruntDirWalker) GetDirs(workingDir string) ([]string, error) { +func (walker *FileSystemTerragruntDirWalker) GetDirs(workingDir string, configYaml *DiggerConfigYaml) ([]string, error) { var dirs []string err := filepath.Walk(workingDir, func(path string, info os.FileInfo, err error) error { @@ -199,7 +201,7 @@ func HandleYamlProjectGeneration(config *DiggerConfigYaml, terraformDir string) } } else if config.GenerateProjectsConfig != nil { var dirWalker = &FileSystemTopLevelTerraformDirWalker{} - dirs, err := dirWalker.GetDirs(terraformDir) + dirs, err := dirWalker.GetDirs(terraformDir, config) if err != nil { fmt.Printf("Error while walking through directories: %v", err) @@ -410,22 +412,25 @@ func AutoDetectDiggerConfig(workingDir string) (*DiggerConfigYaml, error) { telemetry := true configYaml.Telemetry = &telemetry + TraverseToNestedProjects := false + configYaml.TraverseToNestedProjects = &TraverseToNestedProjects + terragruntDirWalker := &FileSystemTerragruntDirWalker{} terraformDirWalker := &FileSystemTopLevelTerraformDirWalker{} moduleDirWalker := &FileSystemModuleDirWalker{} - terragruntDirs, err := terragruntDirWalker.GetDirs(workingDir) + terragruntDirs, err := terragruntDirWalker.GetDirs(workingDir, configYaml) if err != nil { return nil, err } - terraformDirs, err := terraformDirWalker.GetDirs(workingDir) + terraformDirs, err := terraformDirWalker.GetDirs(workingDir, configYaml) if err != nil { return nil, err } - moduleDirs, err := moduleDirWalker.GetDirs(workingDir) + moduleDirs, err := moduleDirWalker.GetDirs(workingDir, configYaml) var modulePatterns []string for _, dir := range moduleDirs { diff --git a/libs/digger_config/digger_config_test.go b/libs/digger_config/digger_config_test.go index c8c385ad7..5335f189b 100644 --- a/libs/digger_config/digger_config_test.go +++ b/libs/digger_config/digger_config_test.go @@ -97,6 +97,7 @@ func TestNoDiggerYaml(t *testing.T) { assert.Equal(t, 1, len(dg.Projects)) assert.Equal(t, false, dg.AutoMerge) assert.Equal(t, true, dg.Telemetry) + assert.Equal(t, false, dg.TraverseToNestedProjects) assert.Equal(t, 1, len(dg.Workflows)) assert.Equal(t, "default", dg.Projects[0].Name) assert.Equal(t, "./", dg.Projects[0].Dir) @@ -137,6 +138,7 @@ projects: assert.Equal(t, 1, len(dg.Projects)) assert.Equal(t, false, dg.AutoMerge) assert.Equal(t, true, dg.Telemetry) + assert.Equal(t, false, dg.TraverseToNestedProjects) assert.Equal(t, 1, len(dg.Workflows)) assert.Equal(t, "prod", dg.Projects[0].Name) @@ -1114,3 +1116,44 @@ func TestDiggerGenerateProjectsMultipleBlocksDemo(t *testing.T) { } // todo test terragrunt digger_config with terragrunt_parsing block but without terragrunt: true + +// TestDiggerTraverseToNestedProjects test if traverse_to_nested_projects is set to true, digger will traverse to nested projects +func TestDiggerTraverseToNestedProjects(t *testing.T) { + tempDir, teardown := setUp() + defer teardown() + + diggerCfg := ` +traverse_to_nested_projects: true +generate_projects: + blocks: + - include: dev/** + aws_role_to_assume: + state: "arn://abc:xyz:state" + command: "arn://abc:xyz:cmd" +` + deleteFile := createFile(path.Join(tempDir, "digger.yml"), diggerCfg) + defer deleteFile() + dirsToCreate := []string{"dev/test1", "dev/test2", "dev/project", "dev/project/test3", "testtt"} + + for _, dir := range dirsToCreate { + err := os.MkdirAll(path.Join(tempDir, dir), os.ModePerm) + defer createFile(path.Join(tempDir, dir, "main.tf"), "")() + assert.NoError(t, err, "expected error to be nil") + } + + dg, _, _, err := LoadDiggerConfig(tempDir) + assert.NoError(t, err, "expected error to be nil") + assert.NotNil(t, dg, "expected digger digger_config to be not nil") + assert.Equal(t, true, dg.TraverseToNestedProjects) + assert.Equal(t, 4, len(dg.Projects)) + assert.Equal(t, "arn://abc:xyz:cmd", dg.Projects[0].AwsRoleToAssume.Command) + assert.Equal(t, "arn://abc:xyz:state", dg.Projects[0].AwsRoleToAssume.State) + assert.Equal(t, "dev_project", dg.Projects[0].Name) + assert.Equal(t, "dev/project", dg.Projects[0].Dir) + assert.Equal(t, "dev_project_test3", dg.Projects[1].Name) + assert.Equal(t, "dev/project/test3", dg.Projects[1].Dir) + assert.Equal(t, "dev_test1", dg.Projects[2].Name) + assert.Equal(t, "dev/test1", dg.Projects[2].Dir) + assert.Equal(t, "dev_test2", dg.Projects[3].Name) + assert.Equal(t, "dev/test2", dg.Projects[3].Dir) +} diff --git a/libs/digger_config/yaml.go b/libs/digger_config/yaml.go index 823c8711a..b168882af 100644 --- a/libs/digger_config/yaml.go +++ b/libs/digger_config/yaml.go @@ -13,6 +13,7 @@ type DiggerConfigYaml struct { Workflows map[string]*WorkflowYaml `yaml:"workflows"` Telemetry *bool `yaml:"telemetry,omitempty"` GenerateProjectsConfig *GenerateProjectsConfigYaml `yaml:"generate_projects"` + TraverseToNestedProjects *bool `yaml:"traverse_to_nested_projects"` MentionDriftedProjectsInPR *bool `yaml:"mention_drifted_projects_in_pr"` }