Repository navigation
Feat: $( ) conditions in a step's if, and a step's status under steps - #272
Merged
Merged
Conversation
briankane
requested review from
FogDong,
Somefive,
anoop2811,
jerrinfrancis,
jguionnet,
leejanee,
roguepikachu and
wonderflow
as code owners
October 15, 2026 04:58
Merged
3 of 5 tasks
briankane
added a commit
to briankane/velaux
that referenced
this pull request
Oct 15, 2026
…ssion A step's if that is exactly one $( ) expression is now a CEL condition (kubevela/workflow#272): it reads what the step's properties read, must give a bool, and admission types it so (kubevela/kubevela#7465). Any other if is CUE, as it always was. steps.<name> also offers a finished step's status: phase, message, reason, succeeded, failed, skipped, timeout, failedAfterRetries and terminate. The studio's If field opens in the mode its value is in. Where the application reads expressions, a toggle switches between CUE and a $( ) expression, with a hint that a whole $( ) makes it CEL; the expression is edited with completion and checked as it is written. An if is saved exactly as written either way, so existing CUE ifs display and save as before, and a pipeline's if stays CUE. The check takes a condition flag. A condition is typed as admission types it, against a required bool with the has() rule for a read that may be absent, in admission's words; any other if is CUE and is not read. A top-level step's own if is decided once, before its loop, so it reads no each; a looping group's sub-step decides its if per pass and reads each over the group's items. Completion offers every other step's status fields, and the check accepts them wherever step reads are allowed, properties included, with the workflow's hint for any other steps.<name> read. Signed-off-by: Brian Kane <briankane1@gmail.com>
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #272 +/- ##
===========================================
+ Coverage 62.49% 79.56% +17.07%
===========================================
Files 62 82 +20
Lines 4415 6275 +1860
===========================================
+ Hits 2759 4993 +2234
+ Misses 1324 1282 -42
+ Partials 332 0 -332
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
briankane
added a commit
to briankane/velaux
that referenced
this pull request
Oct 15, 2026
…ssion A step's if that is exactly one $( ) expression is now a CEL condition (kubevela/workflow#272): it reads what the step's properties read, must give a bool, and admission types it so (kubevela/kubevela#7465). Any other if is CUE, as it always was. steps.<name> also offers a finished step's status: phase, message, reason, succeeded, failed, skipped, timeout, failedAfterRetries and terminate. The studio's If field opens in the mode its value is in. Where the application reads expressions, a toggle switches between CUE and a $( ) expression, with a hint that a whole $( ) makes it CEL; the expression is edited with completion and checked as it is written. An if is saved exactly as written either way, so existing CUE ifs display and save as before, and a pipeline's if stays CUE. The check takes a condition flag. A condition is typed as admission types it, against a required bool with the has() rule for a read that may be absent, in admission's words; any other if is CUE and is not read. A top-level step's own if is decided once, before its loop, so it reads no each; a looping group's sub-step decides its if per pass and reads each over the group's items. Completion offers every other step's status fields, and the check accepts them wherever step reads are allowed, properties included, with the workflow's hint for any other steps.<name> read. Signed-off-by: Brian Kane <briankane1@gmail.com>
There was a problem hiding this comment.
All reported issues were addressed across 43 files
Reply with feedback, questions, or to request a fix.
View guided diff | Re-trigger cubic
briankane
added a commit
to briankane/velaux
that referenced
this pull request
Oct 15, 2026
…ssion A step's if that is exactly one $( ) expression is now a CEL condition (kubevela/workflow#272): it reads what the step's properties read, must give a bool, and admission types it so (kubevela/kubevela#7465). Any other if is CUE, as it always was. steps.<name> also offers a finished step's status: phase, message, reason, succeeded, failed, skipped, timeout, failedAfterRetries and terminate. The studio's If field opens in the mode its value is in. Where the application reads expressions, a toggle switches between CUE and a $( ) expression, with a hint that a whole $( ) makes it CEL; the expression is edited with completion and checked as it is written. An if is saved exactly as written either way, so existing CUE ifs display and save as before, and a pipeline's if stays CUE. The check takes a condition flag. A condition is typed as admission types it, against a required bool with the has() rule for a read that may be absent, in admission's words; any other if is CUE and is not read. A top-level step's own if is decided once, before its loop, so it reads no each; a looping group's sub-step decides its if per pass and reads each over the group's items. Completion offers every other step's status fields, and the check accepts them wherever step reads are allowed, properties included, with the workflow's hint for any other steps.<name> read. Signed-off-by: Brian Kane <briankane1@gmail.com>
briankane
added a commit
to briankane/velaux
that referenced
this pull request
Oct 15, 2026
…ssion A step's if that is exactly one $( ) expression is now a CEL condition (kubevela/workflow#272): it reads what the step's properties read, must give a bool, and admission types it so (kubevela/kubevela#7465). Any other if is CUE, as it always was. steps.<name> also offers a finished step's status: phase, message, reason, succeeded, failed, skipped, timeout, failedAfterRetries and terminate. The studio's If field opens in the mode its value is in. Where the application reads expressions, a toggle switches between CUE and a $( ) expression, with a hint that a whole $( ) makes it CEL; the expression is edited with completion and checked as it is written. An if is saved exactly as written either way, so existing CUE ifs display and save as before, and a pipeline's if stays CUE. The check takes a condition flag. A condition is typed as admission types it, against a required bool with the has() rule for a read that may be absent, in admission's words; any other if is CUE and is not read. A top-level step's own if is decided once, before its loop, so it reads no each; a looping group's sub-step decides its if per pass and reads each over the group's items. Completion offers every other step's status fields, and the check accepts them wherever step reads are allowed, properties included, with the workflow's hint for any other steps.<name> read. Signed-off-by: Brian Kane <briankane1@gmail.com>
3 of 5 tasks
briankane
force-pushed
the
feat/cel-conditions
branch
2 times, most recently
from
October 15, 2026 10:01
c14b311 to
1e4ff70
Compare
An if that is exactly one $( ) expression is evaluated as CEL when the run resolves expressions, reading what the step's properties may: context, steps, each and the host's roots. Any other if is CUE as before, and so is a $( ) if in a run that does not resolve expressions, so no working condition changes. A condition must be a bool; a read still to be answered holds the step back rather than skipping it. steps.<name> now offers the step's status once it has finished, in any phase: phase, message, reason, and succeeded, failed, skipped, timeout, failedAfterRetries and terminate, as status.<name> does in a CUE if. The executor's pre-check cannot reach the evaluator, so the runners pass the condition in PreCheckOptions.Condition; a loop's own if is decided once for the loop. Signed-off-by: Brian Kane <briankane1@gmail.com>
Admission checks a $( ) if as it does a step's properties: the roots offered where it sits, the steps and outputs it reads, and the order it can wait in. A loop step's own if is decided before any pass, so it cannot read each; a looping group's sub-steps' if can. Its reads of steps are implied dependsOn, as a property's are. A CUE if is not read. Signed-off-by: Brian Kane <briankane1@gmail.com>
A condition true for its run runs the step and a false one skips it; a looping group's sub-step's condition is decided each pass with that pass's each; a CUE if beside them behaves as before; and the conditions' reads are recorded as dependencies. Signed-off-by: Brian Kane <briankane1@gmail.com>
Over every phase and reason a step can end in, each status field, and inputs against the outputs they read, a condition and its CUE equivalent decide the same; a condition waits for a step still to finish. The one difference: CUE's status leaves out an empty reason, so a CUE if reading it fails, where a condition reads it as "". Signed-off-by: Brian Kane <briankane1@gmail.com>
…OnFailure Under that gate a failed step may be resumed, so only a succeeded one counted as finished, and a read of a skipped step's status waited for ever. A skipped step never runs, so its status is read as it is. Signed-off-by: Brian Kane <briankane1@gmail.com>
The group was marked skipped but the skip was not recorded where its sub-steps look for it, so they ran. And a loop's condition is now tested over a run that starts its passes, so being decided once is shown, not only a false one. Signed-off-by: Brian Kane <briankane1@gmail.com>
A status field is a value, so steps.build.succeeded.foo can never resolve; admission now says so instead of the run failing. Signed-off-by: Brian Kane <briankane1@gmail.com>
The feature gate, its chart value, ExpressionOptions and the expression dependency source all cover a step's if as well as its properties. Signed-off-by: Brian Kane <briankane1@gmail.com>
briankane
force-pushed
the
feat/cel-conditions
branch
from
October 15, 2026 10:15
1e4ff70 to
2443bd6
Compare
briankane
added a commit
to briankane/velaux
that referenced
this pull request
Oct 15, 2026
…ssion A step's if that is exactly one $( ) expression is now a CEL condition (kubevela/workflow#272): it reads what the step's properties read, must give a bool, and admission types it so (kubevela/kubevela#7465). Any other if is CUE, as it always was. steps.<name> also offers a finished step's status: phase, message, reason, succeeded, failed, skipped, timeout, failedAfterRetries and terminate. The studio's If field opens in the mode its value is in. Where the application reads expressions, a toggle switches between CUE and a $( ) expression, with a hint that a whole $( ) makes it CEL; the expression is edited with completion and checked as it is written. An if is saved exactly as written either way, so existing CUE ifs display and save as before, and a pipeline's if stays CUE. The check takes a condition flag. A condition is typed as admission types it, against a required bool with the has() rule for a read that may be absent, in admission's words; any other if is CUE and is not read. A top-level step's own if is decided once, before its loop, so it reads no each; a looping group's sub-step decides its if per pass and reads each over the group's items. Completion offers every other step's status fields, and the check accepts them wherever step reads are allowed, properties included, with the workflow's hint for any other steps.<name> read. Signed-off-by: Brian Kane <briankane1@gmail.com>
briankane
added a commit
to briankane/velaux
that referenced
this pull request
Oct 15, 2026
…ssion A step's if that is exactly one $( ) expression is now a CEL condition (kubevela/workflow#272): it reads what the step's properties read, must give a bool, and admission types it so (kubevela/kubevela#7465). Any other if is CUE, as it always was. steps.<name> also offers a finished step's status: phase, message, reason, succeeded, failed, skipped, timeout, failedAfterRetries and terminate. The studio's If field opens in the mode its value is in. Where the application reads expressions, a toggle switches between CUE and a $( ) expression, with a hint that a whole $( ) makes it CEL; the expression is edited with completion and checked as it is written. An if is saved exactly as written either way, so existing CUE ifs display and save as before, and a pipeline's if stays CUE. The check takes a condition flag. A condition is typed as admission types it, against a required bool with the has() rule for a read that may be absent, in admission's words; any other if is CUE and is not read. A top-level step's own if is decided once, before its loop, so it reads no each; a looping group's sub-step decides its if per pass and reads each over the group's items. Completion offers every other step's status fields, and the check accepts them wherever step reads are allowed, properties included, with the workflow's hint for any other steps.<name> read. Signed-off-by: Brian Kane <briankane1@gmail.com>
2 of 4 tasks
briankane
added a commit
to briankane/velaux
that referenced
this pull request
Oct 15, 2026
…ssion A step's if that is exactly one $( ) expression is now a CEL condition (kubevela/workflow#272): it reads what the step's properties read, must give a bool, and admission types it so (kubevela/kubevela#7465). Any other if is CUE, as it always was. steps.<name> also offers a finished step's status: phase, message, reason, succeeded, failed, skipped, timeout, failedAfterRetries and terminate. The studio's If field opens in the mode its value is in. Where the application reads expressions, a toggle switches between CUE and a $( ) expression, with a hint that a whole $( ) makes it CEL; the expression is edited with completion and checked as it is written. An if is saved exactly as written either way, so existing CUE ifs display and save as before, and a pipeline's if stays CUE. The check takes a condition flag. A condition is typed as admission types it, against a required bool with the has() rule for a read that may be absent, in admission's words; any other if is CUE and is not read. A top-level step's own if is decided once, before its loop, so it reads no each; a looping group's sub-step decides its if per pass and reads each over the group's items. Completion offers every other step's status fields, and the check accepts them wherever step reads are allowed, properties included, with the workflow's hint for any other steps.<name> read. Signed-off-by: Brian Kane <briankane1@gmail.com>
jerrinfrancis
approved these changes
Oct 15, 2026
briankane
added a commit
to briankane/kubevela
that referenced
this pull request
Oct 15, 2026
Build against kubevela/workflow 3fc7db6 (kubevela/workflow#272), which decides a step by a $( ) condition. Signed-off-by: Brian Kane <briankane1@gmail.com>
briankane
added a commit
to briankane/velaux
that referenced
this pull request
Oct 15, 2026
…ela fork Pins github.com/oam-dev/kubevela to briankane/kubevela a6aacd0b (feat/cel-conditions, on feat/typed-reads), which exports the kinds admission gives component and loop reads and the loaders it types them with, and checks a step's $( ) condition. Requires github.com/kubevela/workflow at 3fc7db63 (kubevela/workflow#272, merged), as that commit does. Never merge: swap the kubevela pin for an upstream version once kubevela#7464 and kubevela#7465 merge. Signed-off-by: Brian Kane <briankane1@gmail.com>
briankane
added a commit
to briankane/velaux
that referenced
this pull request
Oct 15, 2026
…ssion A step's if that is exactly one $( ) expression is now a CEL condition (kubevela/workflow#272): it reads what the step's properties read, must give a bool, and admission types it so (kubevela/kubevela#7465). Any other if is CUE, as it always was. steps.<name> also offers a finished step's status: phase, message, reason, succeeded, failed, skipped, timeout, failedAfterRetries and terminate. The studio's If field opens in the mode its value is in. Where the application reads expressions, a toggle switches between CUE and a $( ) expression, with a hint that a whole $( ) makes it CEL; the expression is edited with completion and checked as it is written. An if is saved exactly as written either way, so existing CUE ifs display and save as before, and a pipeline's if stays CUE. The check takes a condition flag. A condition is typed as admission types it, against a required bool with the has() rule for a read that may be absent, in admission's words; any other if is CUE and is not read. A top-level step's own if is decided once, before its loop, so it reads no each; a looping group's sub-step decides its if per pass and reads each over the group's items. Completion offers every other step's status fields, and the check accepts them wherever step reads are allowed, properties included, with the workflow's hint for any other steps.<name> read. Signed-off-by: Brian Kane <briankane1@gmail.com>
briankane
added a commit
to briankane/kubevela
that referenced
this pull request
Oct 15, 2026
Build against kubevela/workflow 3fc7db6 (kubevela/workflow#272), which decides a step by a $( ) condition. Signed-off-by: Brian Kane <briankane1@gmail.com>
briankane
added a commit
to briankane/kubevela
that referenced
this pull request
Oct 15, 2026
Build against kubevela/workflow 3fc7db6 (kubevela/workflow#272), which decides a step by a $( ) condition. Signed-off-by: Brian Kane <briankane1@gmail.com>
anoop2811
pushed a commit
to kubevela/kubevela
that referenced
this pull request
Oct 15, 2026
#7465) * Chore: bump kubevela/workflow to the step conditions change Build against kubevela/workflow 3fc7db6 (kubevela/workflow#272), which decides a step by a $( ) condition. Signed-off-by: Brian Kane <briankane1@gmail.com> * Feat(webhook): check a step's $( ) condition at admission A step's if that is a $( ) condition is checked as its properties are: the roots a workflow step offers, so not component; the source bindings it reads; and its type, which must be a bool. A sub-step of a looping group types each from the loop's items. A refusal of a whole-value expression, forEach.items included, shows the expression as the value. Signed-off-by: Brian Kane <briankane1@gmail.com> * Test(e2e): an Application's workflow decided by $( ) conditions Conditions read context, a source, a step's status and outputs, and the loop's index: a true one runs its step, a false one skips it, a looping group's sub-step is decided each pass, a CUE if beside them is unchanged, and a condition's reads are recorded as what its step waits on. One that is not a bool is refused at admission. Signed-off-by: Brian Kane <briankane1@gmail.com> * Test(webhook): a condition on a field some loop items leave out $(each.item.wave > 0) over items not all of which have wave is refused unguarded, since it would fail on those items at run time, and admitted behind has(). Signed-off-by: Brian Kane <briankane1@gmail.com> --------- Signed-off-by: Brian Kane <briankane1@gmail.com>
briankane
added a commit
to briankane/velaux
that referenced
this pull request
Oct 15, 2026
Builds against KubeVela 6c4bab5 (kubevela/kubevela#7464 and #7465), which export the kinds admission gives component and loop reads, the loaders it types them with, and check a step's $( ) condition; and kubevela/workflow 3fc7db6 (kubevela/workflow#272), as that commit requires. Signed-off-by: Brian Kane <briankane1@gmail.com>
briankane
added a commit
to briankane/velaux
that referenced
this pull request
Oct 15, 2026
…ssion A step's if that is exactly one $( ) expression is now a CEL condition (kubevela/workflow#272): it reads what the step's properties read, must give a bool, and admission types it so (kubevela/kubevela#7465). Any other if is CUE, as it always was. steps.<name> also offers a finished step's status: phase, message, reason, succeeded, failed, skipped, timeout, failedAfterRetries and terminate. The studio's If field opens in the mode its value is in. Where the application reads expressions, a toggle switches between CUE and a $( ) expression, with a hint that a whole $( ) makes it CEL; the expression is edited with completion and checked as it is written. An if is saved exactly as written either way, so existing CUE ifs display and save as before, and a pipeline's if stays CUE. The check takes a condition flag. A condition is typed as admission types it, against a required bool with the has() rule for a read that may be absent, in admission's words; any other if is CUE and is not read. A top-level step's own if is decided once, before its loop, so it reads no each; a looping group's sub-step decides its if per pass and reads each over the group's items. Completion offers every other step's status fields, and the check accepts them wherever step reads are allowed, properties included, with the workflow's hint for any other steps.<name> read. Signed-off-by: Brian Kane <briankane1@gmail.com>
briankane
added a commit
to briankane/velaux
that referenced
this pull request
Oct 16, 2026
…ssion A step's if that is exactly one $( ) expression is now a CEL condition (kubevela/workflow#272): it reads what the step's properties read, must give a bool, and admission types it so (kubevela/kubevela#7465). Any other if is CUE, as it always was. steps.<name> also offers a finished step's status: phase, message, reason, succeeded, failed, skipped, timeout, failedAfterRetries and terminate. The studio's If field opens in the mode its value is in. Where the application reads expressions, a toggle switches between CUE and a $( ) expression, with a hint that a whole $( ) makes it CEL; the expression is edited with completion and checked as it is written. An if is saved exactly as written either way, so existing CUE ifs display and save as before, and a pipeline's if stays CUE. The check takes a condition flag. A condition is typed as admission types it, against a required bool with the has() rule for a read that may be absent, in admission's words; any other if is CUE and is not read. A top-level step's own if is decided once, before its loop, so it reads no each; a looping group's sub-step decides its if per pass and reads each over the group's items. Completion offers every other step's status fields, and the check accepts them wherever step reads are allowed, properties included, with the workflow's hint for any other steps.<name> read. Signed-off-by: Brian Kane <briankane1@gmail.com>
briankane
added a commit
to briankane/velaux
that referenced
this pull request
Oct 16, 2026
…ssion A step's if that is exactly one $( ) expression is now a CEL condition (kubevela/workflow#272): it reads what the step's properties read, must give a bool, and admission types it so (kubevela/kubevela#7465). Any other if is CUE, as it always was. steps.<name> also offers a finished step's status: phase, message, reason, succeeded, failed, skipped, timeout, failedAfterRetries and terminate. The studio's If field opens in the mode its value is in. Where the application reads expressions, a toggle switches between CUE and a $( ) expression, with a hint that a whole $( ) makes it CEL; the expression is edited with completion and checked as it is written. An if is saved exactly as written either way, so existing CUE ifs display and save as before, and a pipeline's if stays CUE. The check takes a condition flag. A condition is typed as admission types it, against a required bool with the has() rule for a read that may be absent, in admission's words; any other if is CUE and is not read. A top-level step's own if is decided once, before its loop, so it reads no each; a looping group's sub-step decides its if per pass and reads each over the group's items. Completion offers every other step's status fields, and the check accepts them wherever step reads are allowed, properties included, with the workflow's hint for any other steps.<name> read. Signed-off-by: Brian Kane <briankane1@gmail.com>
briankane
added a commit
to kubevela/velaux
that referenced
this pull request
Oct 16, 2026
…d $( ) conditions in the studio (#979) * Chore: bump KubeVela to the typed reads, step conditions and forEach key changes Builds against KubeVela 28372bb (kubevela/kubevela#7464, #7465 and #7468), which export the kinds admission gives component and loop reads, each.key among them, the loaders it types them with, and check a step's $( ) condition. Signed-off-by: Brian Kane <briankane1@gmail.com> * Refactor: follow KubeVela's move of template parsing to kubevela/pkg KubeVela now parses $( ) values with github.com/kubevela/pkg/cel/template, and its propexpr package keeps the reads' roots as functions over template.Reference. ListApplicationResourceTrackers moved from pkg/resourcetracker to pkg/appkeeper. The calls follow; nothing changes in what they do. Signed-off-by: Brian Kane <briankane1@gmail.com> * Feat(expressions): type component reads in the expression check The check took a value's type from CEL, which has component.<name> as dyn, so "$(component.db.output.data.host)" in an int parameter passed with a warning while the same read of a source was refused. KubeVela's admission now types a component read by what its producer declares, and refuses the mismatch. A value that is exactly one component read now takes that type, from KubeVela's schema.ProducedFor, the loader admission types it with: the component's definition in its namespace then vela-system, at the revision a type@vN names and over its extends chain, the resources its traits add, an untyped workload under a trait that patches it, untyped resources under one with patchOutputs, and a trait that cannot be read treated as doing both. A read the schema has no kind for, such as a status field or one the template does not write, fits anything. Interpolated text is still a string, and an expression doing more than reading keeps its CEL type. Completion and the variables panel still read the schema ConfigMaps. Source schemas come from schema.SourceSchemaText in place of a direct Get, so a pinned source such as atlas@v1 is typed by that revision's schema, and editor and admission find the same definition. The warning on a dyn value said the webhook refuses it until it is converted. It admits it against any parameter; the warning now says the value is not checked and a wrong one fails at render. each reads stay dyn: the check is not given the step's forEach items. Signed-off-by: Brian Kane <briankane1@gmail.com> * Feat(workflow): step expressions in the studio: steps and each, typed like admission KubeVela resolves a workflow step's $( ) values as each step runs (#7458), so a step reads steps.<name>.outputs.<output>, an earlier step's declared output, and, in a forEach body, each.item and each.index. The studio's step forms took no expressions, and the check let either root through anywhere as dyn. Step properties now take expressions in an application's workflow. The env and check requests carry where the step sits, all optional: the step, whether it is a loop body (a step with forEach, or a sub-step of a group with one), the loop's forEach items as written, and the workflow's steps with their declared outputs. Completion lists the other steps' outputs and, in a loop body, each.item with the fields its items have and each.index. The check refuses what admission refuses, in its words: steps or each off a workflow step, each outside a forEach body, and a read of a step or output the workflow does not declare. A value that is one each read is typed as admission types it, with schema.EachReadKind over schema.LoopItemKind: a literal list as written, items read from a source by its schema. A steps read stays dyn, since an output declares no type. component stays refused on a step. The loop's items editor sends the workflow's steps too, so a steps read there is checked. The inputs-based loop wiring is unchanged. Signed-off-by: Brian Kane <briankane1@gmail.com> * Feat(workflow): $( ) step conditions in the studio, checked like admission A step's if that is exactly one $( ) expression is now a CEL condition (kubevela/workflow#272): it reads what the step's properties read, must give a bool, and admission types it so (kubevela/kubevela#7465). Any other if is CUE, as it always was. steps.<name> also offers a finished step's status: phase, message, reason, succeeded, failed, skipped, timeout, failedAfterRetries and terminate. The studio's If field opens in the mode its value is in. Where the application reads expressions, a toggle switches between CUE and a $( ) expression, with a hint that a whole $( ) makes it CEL; the expression is edited with completion and checked as it is written. An if is saved exactly as written either way, so existing CUE ifs display and save as before, and a pipeline's if stays CUE. The check takes a condition flag. A condition is typed as admission types it, against a required bool with the has() rule for a read that may be absent, in admission's words; any other if is CUE and is not read. A top-level step's own if is decided once, before its loop, so it reads no each; a looping group's sub-step decides its if per pass and reads each over the group's items. Completion offers every other step's status fields, and the check accepts them wherever step reads are allowed, properties included, with the workflow's hint for any other steps.<name> read. Signed-off-by: Brian Kane <briankane1@gmail.com> * Fix(expressions): name a map or struct value object, as admission does The check named a value read as a map, or a component's struct, "map", where admission names both "object": "$(source.cfg.labels)" in a string parameter read "this value is map" in the editor and "is object" at deploy. Both now say object. Signed-off-by: Brian Kane <briankane1@gmail.com> * Fix(expressions): refuse component reads as admission does, clusters included The check refused a component read of itself, of a component the application does not have, or on a surface that reads none in its own words, and let a read at an unregistered cluster through, which admission refuses. It now builds the reading component and asks KubeVela's ValidateComponentReads, so those refusals, and a misplaced placement, read as admission's. A read at a cluster is refused when the cluster is not registered, through the same lookup admission makes. A component read on a surface that reads none gets admission's roots refusal, and a hyphenated name read with a dot names the whole expression in index form, as celexpr.Explain does, keeping its quick fix. Signed-off-by: Brian Kane <briankane1@gmail.com> * Fix(expressions): judge source reads by admission's rules The check left a source read to CEL, so every refusal read "undefined field", and two that admission makes were missed: a definition whose consumableFrom leaves out the surface, and a definition that cannot be read. A source read is now judged as admission judges it, in its words: a binding the application does not declare, a source reading one not declared before it, a definition that cannot be read, a consumableFrom that leaves out the surface, and a path the schema does not declare, walked as admission walks it (optional fields, keys of an open map, anything below a value of any type). A chained read's consumableFrom is left to admission, which knows where the outer source is consumed. Signed-off-by: Brian Kane <briankane1@gmail.com> * Fix(expressions): refuse a read that may be absent feeding a required parameter Admission refuses a read that may be missing at render, an optional field or a key of an open map, where it feeds a parameter that must be set, unless has() guards it. The check only did that for a step's $( ) if, so the editor passed "$(source.cfg.labels.team)" in a required parameter that admission refused. The check request takes whether the parameter is required, which the form sends from the parameter's schema and a save works out from the definition's. A read that may be absent feeding one is refused with admission's has() advice. The if and a required parameter share one pass over KubeVela's CheckTypes. Signed-off-by: Brian Kane <briankane1@gmail.com> * Fix(workflow): judge a step's reads with the workflow's own validation The check judged steps and each reads by hand from a flat list of steps, so it missed what the workflow refuses about order: in a workflow run in order, a step reading a later one ("use runs after first, and a workflow run in order cannot wait for it"), a read closing a dependsOn cycle, and an output two steps both declare. The studio now sends the workflow as it runs: each step's outputs, dependsOn and whether it loops, a group's steps under it with their mode, and the workflow's modes. The check builds that workflow with the value in the step being edited, its if or its properties, and refuses what the workflow's Validate refuses there, the call admission makes, so the order rules, the self-read and each outside a loop body come out in the workflow's words. A request without the step or the list keeps the checks it had. The loop items editor sends the list without a step, since its value sits in no step's properties. Signed-off-by: Brian Kane <briankane1@gmail.com> * Fix(expressions): declare a source binding whose definition has no schema A binding was left out of the typed environment when its SourceDefinition declared no schema or could not be loaded, so a read of it was refused as an undefined field, beside the source rules' own refusal of a definition that cannot be loaded. Admission now declares such a binding of any type, and so does the check: its reads fit anything, and a missing definition is reported once. Signed-off-by: Brian Kane <briankane1@gmail.com> * Fix(expressions): judge an each.item read that may be absent as admission does Admission's has() rule now treats an each.item read as possibly absent where some of the loop's literal items leave the field out, have a shorter list, or hold an open map, and, for items read from a source, as the source's schema says. The check judged each reads as always present, so "$(each.item.wave > 0)" passed the editor in a step's if, or in a required parameter, where admission refused it. The check now judges each reads with KubeVela's EachMayBeAbsent over LoopItemMayBeAbsent, composed as admission composes them, for both the if and a required parameter. Signed-off-by: Brian Kane <briankane1@gmail.com> * Test(expressions): equivalence of the check with KubeVela's admission One table of 100 cases, each run through the expression check, with the step scope the studio sends, and through KubeVela's ValidateSources and ValidateWorkflow on the Application the case builds, over one fake client of definitions, KubeVela's shipped daemon, addon and module among them. Both must agree on whether the value is refused, and VelaUX's message must carry admission's. Where the words legitimately differ, the case says why and what both still say: a type mismatch, which the editor words for the field and both name by the type found and wanted, a hyphenated name, and the has() rule for a required parameter. Policies, which VelaUX's forms do not check, record admission's answer only. The cases cover component, source, each and steps reads, an each.item read some items lack, $( ) conditions and CUE ifs, and the roots each surface offers. Signed-off-by: Brian Kane <briankane1@gmail.com> * Feat(workflow): offer each.key in a loop body's expressions A loop body's expression env lists each.key beside each.item and each.index: the item's key from forEach.key, or its index as text. KubeVela types it as a string, so the check refuses it where a number is expected. Signed-off-by: Brian Kane <briankane1@gmail.com> --------- Signed-off-by: Brian Kane <briankane1@gmail.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description of your changes
Merge after #271, which this branch sits on. Only the last three commits are this PR's.
A step's
ifis CUE today. With this PR, anifthat is exactly one$( )expression is CEL, evaluated with the same roots as the step's properties (#271), in a run that resolves expressions.$( )is CEL.always, an emptyif, any CUE expression, and a$(inside a CUE string are unchanged. A whole$(...)never worked as CUE ($is an identifier, so$(x)is a call to something undefined), and in a run without expressions enabled a$( )ifstill fails as it does today.context,steps,eachand the host's roots, as in properties. A condition must be a bool.steps.<name>now offers a finished step's status:phase,message,reason,succeeded,failed,skipped,timeout,failedAfterRetries,terminate, asstatus.<name>does in a CUEif. A read waits while the step has still to finish; it works in properties too.stepsare implieddependsOn, as a property's are (Feat: $( ) expressions in workflow step properties, resolved when each step runs #271), soif: $(steps.build.failed)waits forbuildwithout a writtendependsOn.ifapplies to the loop as a whole, decided once, so it cannot readeach; a looping group's sub-steps'ifis decided each pass, with that pass'seach.$( )ifas it does properties: roots, the steps and outputs it reads, the order it can wait in, cycles,eachplacement.PreCheckOptions.Condition;PreCheckResult.Waitcarries the wait.PropertyEvaluatorgainsCondition.I have:
make reviewableto ensure this PR is ready for review: golangci-lint and staticcheck with Go 1.27, 0 issues.How has this code been tested
Condition(true, false, every root, a host root given the run, not a bool, waiting); each status field in each finished phase, waiting while running or retrying, a loop's status from outside and inside, a step reading its own status; the executor's decision (true, false, wait, error, CUE left to CUE, no condition offered); a group's and a loop's condition (skip, wait, CUE, no expressions; a loop's decided once); validation of conditions and their implied dependencies.e2e/expressions_test.go) on k3d: a WorkflowRun where a true condition runs its step, a false one skips it, a looping group's sub-step is decided each pass, a CUEifbeside them is unchanged, and the reads are recorded as dependencies. With the condition switched off in the executor, the spec fails.Summary by cubic
Step properties,
forEach.items, and a step'sifcan now be$( )CEL expressions, resolved when the step runs with the same roots as its properties (context,steps, the host's roots, andeachinside a loop pass).steps.<name>.outputs.<output>reads an output the step declares;steps.<name>exposes a finished step's status (phase,succeeded,failed,skipped,timeout, and so on). A read waits while the step has still to finish; a failed step fails the read, and a skipped step is read as skipped — its status never changes, and its outputs read as absent.stepsare implieddependsOn, which—unlike a written one—does not skip the reader when the step read is skipped. The run status records what each step waits on and whetherdependsOnor an expression implied it; restarting a step also restarts every step that reads it.$( )ifis CEL only when the run opts in via theEnableCelExpressionsfeature gate and theworkflowrun.oam.dev/cel-expressionsannotation; any otherif, including$( )inside CUE text, stays CUE. An escaped$(still counts as an expression.ifis decided once for the loop and cannot readeach; a looping group's sub-stepifis decided each pass, and a group whose condition errors runs none of its sub-steps.eachoutside a forEach body, or could never be answered (the reader itself, a later step in order, a cycle), plus reads below a status field.forEach.itemsmust be one sole expression; text around it is refused.Written for commit 2443bd6. Summary will update on new commits.