Skip to content

Commit

Permalink
feat: forward parent lifecycles to child stages defined on the module
Browse files Browse the repository at this point in the history
In scenarios where lifecycles are defined on the module level, there was an issue preventing the same
lifecycle phases from being applied to the child modules. This was very inconvenient when
reusing multiple modules and the caller may have custom lifecycle phases, but the module's
are not owned by the caller to make changes
  • Loading branch information
srevinsaju committed Mar 14, 2024
1 parent aa2632a commit 9fd8308
Show file tree
Hide file tree
Showing 6 changed files with 120 additions and 10 deletions.
30 changes: 30 additions & 0 deletions examples/module-phases-inheritance/calculator/togomak.hcl
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
togomak {
version = 2
}

variable "a" {
type = number
description = "first variable"
}
variable "b" {
type = number
description = "second variable"
}

variable "operation" {
type = string
description = "Operation to perform, any of: [add, subtract, multiply, divide]"
}

stage "add" {
if = var.operation == "add"
script = "echo ${var.a} + ${var.b} is ${var.a + var.b}"
}

stage "paths" {
script = <<-EOT
echo path.module: ${path.module}
echo path.cwd: ${path.cwd}
echo path.root: ${path.root}
EOT
}
28 changes: 28 additions & 0 deletions examples/module-phases-inheritance/togomak.hcl
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
togomak {
version = 2
}

locals {
a = 99
b = 1
}

stage "paths" {
script = <<-EOT
echo path.module: ${path.module}
echo path.cwd: ${path.cwd}
echo path.root: ${path.root}
EOT
}

module "add" {
source = "./calculator"
a = local.a
b = local.b
operation = "add"

lifecycle {
phase = ["add"]
}
}

2 changes: 2 additions & 0 deletions internal/behavior/models.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Expand Down
24 changes: 19 additions & 5 deletions internal/ci/module_run.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}

Check warning on line 169 in internal/ci/module_run.go

View check run for this annotation

Codecov / codecov/patch

internal/ci/module_run.go#L168-L169

Added lines #L168 - L169 were not covered by tests
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,
}
Expand All @@ -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
Expand Down
14 changes: 10 additions & 4 deletions internal/ci/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand All @@ -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 {
Expand Down
32 changes: 31 additions & 1 deletion tests/togomak.hcl
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -82,7 +112,7 @@ stage "fmt" {
}

stage "cache" {
depends_on = [stage.fmt, stage.tests, stage.tests_dry_run]
depends_on = [stage.fmt, stage.tests, stage.tests_dry_run, stage.module_phase_test]
script = "./togomak_coverage cache clean --recursive"
}

Expand Down

0 comments on commit 9fd8308

Please sign in to comment.