feat: Add CEL-based conditional function execution (#4388)#4469
feat: Add CEL-based conditional function execution (#4388)#4469SurbhiAgarwal1 wants to merge 1 commit intokptdev:mainfrom
Conversation
✅ Deploy Preview for kptdocs ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
2037fa3 to
b9a1ab1
Compare
|
Comment from #4391: Closing this PR in favor of a clean rebase. The branch had accumulated 61 commits including upstream commits from other contributors, making it messy to review. All the feedback from this review has been addressed in the new PR which has a single clean commit: Thank you all for the thorough review! |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 31 out of 32 changed files in this pull request and generated 6 comments.
Comments suppressed due to low confidence (1)
thirdparty/kyaml/runfn/runfn.go:1
NewFunctionRunner’s error is discarded andSetConditionis called without validatingopts.CELEnvironment. This can both (a) mask construction failures and (b) silently ignore the condition at runtime whenCELEnvironmentis nil (sinceFilter()only evaluates conditions whencelEnv != nil). Handle theerrfromNewFunctionRunner, and ifr.Conditionis set, return an error whenopts.CELEnvironmentis nil (or makeSetConditionreturn an error and enforce it here).
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 29 out of 30 changed files in this pull request and generated 4 comments.
Comments suppressed due to low confidence (1)
documentation/content/en/book/04-using-functions/_index.md:1
- Two doc mismatches with the implementation: (1) the CEL resource map normalization in
resourceToMapguaranteesapiVersion,kind, andmetadatakeys, but notspec/status—either update the docs or ensure those keys are present; (2) the skipped example says “Successfully executed 1 function(s)” but the new behavior and e2e expectations indicate skipped functions should not count as executed (so this should be0).
---
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
The tests are failing because we have merged the conditions and renederstatus to kpt recently. I thought that by deleting the The following `diff.patch files work for me on the tests locally on my machine: e2e/testdata/fn-render/condition/condition-met/.expected/diff.patch e2e/testdata/fn-render/condition/condition-not-met/.expected/diff.patch Can you try restoring the two Sorry for mucking with your PR 😢 |
abd89dd to
df1189f
Compare
|
Thank you @liamfallon! I've restored both diff.patch files with exactly the contents you provided in commit df1189f. The tests should pass now. Sorry for the confusion! |
df1189f to
ad63ed9
Compare
298cc5d to
6d4aed1
Compare
6d4aed1 to
26362cc
Compare
|
Got it, makes sense. Thanks! |
|
If you have time to look at the copilot comments that would be great. We can move to formally review and merge the PR then. |
liamfallon
left a comment
There was a problem hiding this comment.
Looks good to me.
Could you have a look at that last copilot comment and see if anything needs to be done?
nagygergo
left a comment
There was a problem hiding this comment.
Looks good to me. Thanks for the contribution @SurbhiAgarwal1
| + renderStatus: | ||
| + mutationSteps: | ||
| + - image: ghcr.io/kptdev/krm-functions-catalog/no-op:latest | ||
| + exitCode: 0 |
There was a problem hiding this comment.
It would also be worth capturing the condition field in status.renderStatus, so the skip condition is recorded alongside the render result.
There was a problem hiding this comment.
I agree with @nagygergo and @aravindtga - the render condition should reflect the overall pipeline result, not individual function execution. Since the pipeline completed successfully (just with some functions skipped), keeping status: "True" makes sense.
I can update the reason to RenderedWithSkippedFunctions when at least one function was skipped, so consumers can distinguish between a fully executed render and one with skipped functions. I can also add the condition field to status.renderStatus so the skip reason is recorded alongside the result.
Let me know if you'd like me to go ahead with these changes
There was a problem hiding this comment.
It would also be worth capturing the
conditionfield instatus.renderStatus, so the skip condition is recorded alongside the render result.
A condition field has been introduced in the mutation pipeline configuration:
mutators:
- image: ghcr.io/kptdev/krm-functions-catalog/no-op
condition: resources.exists(r, r.kind == 'ConfigMap' && r.metadata.name == 'app-config')Can you also add the condition field to status.renderStatus.mutationSteps so it gets recorded when the pipeline execution is captured? e.g:
status:
conditions:
- type: Rendered
status: "True"
reason: RenderSuccess
renderStatus:
mutationSteps:
- image: ghcr.io/kptdev/krm-functions-catalog/no-op:latest
condition: resources.exists(r, r.kind == 'ConfigMap' && r.metadata.name == 'app-config')
exitCode: 0
....5101835 to
39f43fb
Compare
39f43fb to
c48c65b
Compare
|
Hi @liamfallon, the condition tests are now passing. The remaining Docker failure is TestFnRender/testdata/fn-render/subpkg-fn-failure which expects "statefulset-filter:4:42: got newline, want primary expression" but gets a different starlark error format. This test file is unchanged from upstream - is this a known flaky test? |
dcc296f to
fbfedca
Compare
fbfedca to
b37a51e
Compare
- Add condition field to Function type in Kptfile pipeline - Add CELEnvironment in pkg/lib/runneroptions/celenv.go - Integrate condition check in FunctionRunner.Filter() - Functions skipped due to condition show [SKIPPED] in CLI output - Add condition field to status.renderStatus.mutationSteps - Add E2E tests for condition-met and condition-not-met (docker+podman verified) - Add unit tests for CEL evaluation - Update documentation - Fix imports after fnruntime moved to pkg/fn/runtime - Add IsEmpty() to Status struct, DisplayName to Renderer struct - Fix symlink test skip on Windows/WSL - Remove apply-setters from internal/kptops (dependency removed upstream) - Apply gofmt formatting fixes - Fix InitCELEnvironment error propagation in get.go - Fix doc: executed count when condition not met is 0 - Fix doc: spec/status fields may be absent in resources - Fix comment: CELEnvironment initialized by InitCELEnvironment not InitDefaults - Update subpkg-fn-failure diff.patch with renderStatus output Signed-off-by: SurbhiAgarwal1 <agarwalsurbhi1807@gmail.com>
b37a51e to
0457465
Compare
Description
This PR adds CEL-based conditional function execution to kpt, implementing #4388.
A new optional
conditionfield is added to theFunctiontype in the Kptfile pipeline. When specified, the CEL expression is evaluated against the current list of KRM resources. If the expression returnsfalse, the function is skipped. If omitted or returnstrue, the function executes normally.Motivation
In many real-world scenarios, you want a pipeline function to run only when certain resources exist or meet specific criteria. Without this feature, users had to maintain separate Kptfiles or manually manage which functions run. The
conditionfield makes pipelines more dynamic and reduces the need for workarounds.Changes
conditionfield toFunctiontype inpkg/api/kptfile/v1/types.goCELEnvironmentinpkg/lib/runneroptions/celenv.gousinggoogle/cel-goFunctionRunner.Filter()ininternal/fnruntime/runner.go[SKIPPED]in CLI outputInitCELEnvironment()method toRunnerOptionsfor proper error handlingInitDefaults()to also callInitCELEnvironment()condition-metandcondition-not-metcasesExample Usage