Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: forward parent lifecycles to child stages defined on the module #68

Merged
merged 1 commit into from
Mar 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
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 @@
})
}

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 @@
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
Loading