Skip to content

v1.228.0-rc.1

Pre-release
Pre-release

Choose a tag to compare

@cloudposse-releaser cloudposse-releaser released this 28 Aug 04:00
71942cf

🚀 Enhancements

fix: implement MarshalYAML on Condition to make sure it survives marshalling roundtrip Jorrit Elfferich (@jorrite) (#3006) ## what
  • Add Condition.MarshalYAML() to pkg/condition/condition.go so a when: condition survives being marshaled back to YAML.
  • pkg/condition/condition_test.go: add TestConditionYAMLMarshalRoundTrip (predicate/CEL/all/any-not shapes) and TestConditionYAMLEmptyMarshalRoundTrip, asserting the marshaled-then-decoded value matches the expected shape and evaluates identically to the original across representative facts.
  • pkg/project/config/config_baseref_test.go: add TestSaveAndLoadProjectRecord_FieldWhenSurvivesRoundTrip, exercising the real SaveProjectRecord/LoadProjectRecord path with a field-level when: condition (mirroring examples/scaffolding/scaffold.yaml's enable_vendoring/vendor_version pair) and asserting the reloaded condition evaluates correctly.
  • No change to condition.Evaluate, CEL compilation, or the JSON marshal/unmarshal paths — out of scope, and unaffected since the fix reuses the same node.value() reconstruction MarshalJSON already relies on.

why

  • Condition's only field, node *Node, is unexported. Condition already implements UnmarshalYAML, UnmarshalJSON, and MarshalJSON, but had no MarshalYAML. Without one, yaml.Marshal falls back to reflecting the struct, sees zero exported fields, and writes {} — silently discarding the condition instead of erroring.
  • This corrupted atmos scaffold generate's project record (.atmos/scaffold.yaml): a spec.fields[].when CEL string (e.g. "answers.topology == 'multi'") rendered correctly on first generate, but got written back as when: {}. Since --update re-reads that same record on every subsequent run, the project was permanently stuck failing schema validation (expected string, but got object) with no way to self-heal.
  • spec.files[].when never showed the same symptom, but not because that path is correct — SaveProjectRecord never copies templateConfig.Spec.Files into the persisted record at all (only Fields, Delimiters, Source, BaseRef, Values are copied), so there's nothing there to corrupt. Verified this holds with a matrix:-expanded files[] entry too: generation succeeds, but spec.files is simply absent from the written record.
  • The fix reconstructs the original string/list/map form via node.value() — the same method MarshalJSON already uses. This isn't new behavior: cloneCommand (cmd/cmd_utils.go) already JSON round-trips every custom command's Task.When through this exact normalization on every invocation, so a bare CEL string already canonicalizes to !cel <expr> there today. Extending it to MarshalYAML just makes YAML and JSON serialization consistent with each other.

references

  • n/a

Summary by CodeRabbit

  • Bug Fixes

    • Preserved field-level YAML conditions when project records are saved and loaded.
    • Ensured predicate, CEL, compound, and empty conditions retain their values during YAML round trips.
  • Tests

    • Added coverage confirming condition formatting and evaluation remain consistent after serialization and reloading.