diff --git a/internal/behavior/models.go b/internal/behavior/models.go index 3649166..7bc6151 100644 --- a/internal/behavior/models.go +++ b/internal/behavior/models.go @@ -7,6 +7,8 @@ type Child struct { // Parent is the flag to indicate whether the program is running in parent mode Parent string + ParentLifecycles []string + // ParentParams is the list of parameters to be passed to the parent ParentParams []string } diff --git a/internal/ci/module_run.go b/internal/ci/module_run.go index 29ecffd..ba6c7f1 100644 --- a/internal/ci/module_run.go +++ b/internal/ci/module_run.go @@ -163,13 +163,28 @@ func (m *Module) run(conductor *Conductor, source string, evalCtx *hcl.EvalConte }) } + var parentLifecycles []string + if cfg.Behavior.Child.ParentLifecycles != nil { + parentLifecycles = cfg.Behavior.Child.ParentLifecycles + } + if m.Lifecycle != nil { + conductor.Eval().Mutex().RLock() + lifecyclePhases, d := m.Lifecycle.Phase.Value(evalCtx) + conductor.Eval().Mutex().RUnlock() + diags = diags.Extend(d) + for _, phase := range lifecyclePhases.AsValueSlice() { + parentLifecycles = append(parentLifecycles, phase.AsString()) + } + } + b := &behavior.Behavior{ Unattended: conductor.Config.Behavior.Unattended, Ci: conductor.Config.Behavior.Ci, Child: behavior.Child{ - Enabled: true, - Parent: "", - ParentParams: nil, + Enabled: true, + Parent: "", + ParentParams: nil, + ParentLifecycles: parentLifecycles, }, DryRun: false, } @@ -194,8 +209,7 @@ func (m *Module) run(conductor *Conductor, source string, evalCtx *hcl.EvalConte conductorOptions = append(conductorOptions, ConductorWithParser(conductor.Parser)) // populate input variables for the child conductor, which would be passed to the module - attrs, d := m.Body.JustAttributes() - diags = diags.Extend(d) + attrs, _ := m.Body.JustAttributes() for _, attr := range attrs { //we need to evaluate the values first within the parent's evaluation context //before sending it to the child goroutine and child conductor diff --git a/internal/ci/run.go b/internal/ci/run.go index 6f0c8fe..9ee8aa1 100644 --- a/internal/ci/run.go +++ b/internal/ci/run.go @@ -112,10 +112,16 @@ func BlockCanRun(runnable Block, conductor *Conductor, runnableId string, depGra ok = false overridden = false - // if the list is empty, we will assume that the runnable is not overridden + // if the list is empty, we will assume that the runnable is not overridden, // and we will run all module blocks. This is so that the child processoe var phases []cty.Value - var phasesDefined bool + + // if the parent config has lifecycles defined, we will append it to the child + for _, phase := range conductor.Config.Behavior.Child.ParentLifecycles { + phases = append(phases, cty.StringVal(phase)) + } + + var phasesDefined bool = len(phases) > 0 stage := runnable.(PhasedBlock) if stage.LifecycleConfig() != nil { evalContext := conductor.Eval().Context() @@ -126,8 +132,8 @@ func BlockCanRun(runnable Block, conductor *Conductor, runnableId string, depGra diags = diags.Extend(d) return false, false, diags } - phasesDefined = !phaseHcl.IsNull() - phases = phaseHcl.AsValueSlice() + phasesDefined = !phaseHcl.IsNull() || len(phases) > 0 + phases = append(phases, phaseHcl.AsValueSlice()...) } if runnable.Type() == blocks.ModuleBlock && len(phases) == 0 && !phasesDefined { diff --git a/tests/togomak.hcl b/tests/togomak.hcl index 0a944d4..2ea4c83 100644 --- a/tests/togomak.hcl +++ b/tests/togomak.hcl @@ -49,6 +49,36 @@ stage "tests" { } } +stage "module_phase_test" { + pre_hook { + stage { + script = "echo ${ansi.fg.green}${each.key}${ansi.reset}: full" + } + } + + for_each = toset([ + "../examples/module-phases-inheritance/togomak.hcl", + ]) + + depends_on = [stage.build, stage.coverage_prepare] + args = [ + "./togomak_coverage", + "-C", dirname(each.key), + "--ci", "-v", "-v", "-v", + "add" + ] + + env { + name = "GOCOVERDIR" + value = local.coverage_data_dir + } + env { + name = "TOGOMAK_VAR_name" + value = "bot" + } + +} + stage "tests_dry_run" { pre_hook {