Feat: name forEach items by a key

Merged
BR
13d ago
+37-0

Description of your changes

Adds an optional key to ForEach, so a loop's steps can be named by each item's values rather than its position.

forEach:
  from: targets            # [{cluster: prod-us, namespace: shop}, ...]
  key: [cluster, namespace]
LoopedWithout keyWith key: [cluster, namespace]
a step deploydeploy-0deploy-prod-us-shop
a group rollout, sub-step verifyrollout-0-verifyrollout-prod-us-shop-verify
  • key is a list of paths into each item, the same dotted syntax as inputs[].from. One field is still a list (key: [name]), so the CRD and the docs have one shape.
  • The values are joined with -. The engine checks each part is a string or an integer, none is missing, the joined key uses step-name characters and is unique in the loop; the schema bounds the list at one to eight paths.
  • The Workflow CRD is regenerated.

This is the API half. The engine is kubevela/workflow#273 and the Application support kubevela/kubevela#7468.

How has this code been tested

  • A round-trip test for key, its omission when unset, and deepcopy independence.
  • The engine and KubeVela changes are built and tested on top of this commit (unit, envtest and lint in both).

Special notes for your reviewer

Merge order: this PR first, then kubevela/workflow#273, then kubevela/kubevela#7468. The other two carry a temporary replace onto this branch until this merges.


Summary by cubic

Adds an optional key to ForEach so loop steps are named by each item's values instead of its position. With key: [cluster, namespace] over items like {cluster: prod-us, namespace: shop}, a step deploy becomes deploy-prod-us-shop instead of deploy-0; the Workflow CRD is regenerated.

  • key takes one to eight dotted paths into each item; values must be strings or integers, be present, and be unique after joining with -.
  • This is the API half only. The engine (kubevela/workflow) and Application (kubevela/kubevela) support land in follow-up PRs, so this PR must merge first.
  • The field is optional and omitted when unset, so existing loops behave as before.