feat: Add CEL-based conditional function execution (#4388)#4469
feat: Add CEL-based conditional function execution (#4388)#4469SurbhiAgarwal1 wants to merge 10 commits into
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
dcc296f to
fbfedca
Compare
b37a51e to
0457465
Compare
|
Please rebase. The test flakyness was fixed last week, so tests should work now. |
|
Hi @CsatariGergely, Yes, I'm still working on this. Unfortunately, I've been facing some issues with my computer recently, which has delayed my progress. I'll get the environment set up again, rebase the branch, and update the PR as soon as possible. Thank you for your patience. |
Hi @SurbhiAgarwal1 |
ff7af3a to
cf8ebca
Compare
cf8ebca to
f3a3899
Compare
| assert.NoError(t, err) | ||
| err = os.Symlink(filepath.Join("path", "to", "pkg", "dir"), "foo") | ||
| assert.NoError(t, err) | ||
| if err != nil { |
There was a problem hiding this comment.
If we have issues with running these tests due to Windows permissions, this needs to be addressed somehow.
These should work in WSL though.
| @@ -0,0 +1,160 @@ | |||
| // Copyright 2026 The kpt and Nephio Authors | |||
There was a problem hiding this comment.
All new headers should be:
Copyright 2026 The kpt Authors
4952405 to
ed0f75b
Compare
efiacor
left a comment
There was a problem hiding this comment.
Nice progress made. Please address all comments/suggestions to proceed. Thanks
| actualStripLines: | ||
| - " stderr: 'WARNING: The requested image''s platform (linux/amd64) does not match the detected host platform (linux/arm64/v8) and no specific platform was requested'" | ||
|
|
||
| stdErrStripLines: | ||
| - " Stderr:" | ||
| - " \"WARNING: The requested image's platform (linux/amd64) does not match the detected host platform (linux/arm64/v8) and no specific platform was requested\"" |
There was a problem hiding this comment.
Can these be removed, or does the no-op function throw a compatibility error without them?
| actualStripLines: | ||
| - " stderr: 'WARNING: The requested image''s platform (linux/amd64) does not match the detected host platform (linux/arm64/v8) and no specific platform was requested'" | ||
|
|
||
| stdErrStripLines: | ||
| - " Stderr:" | ||
| - " \"WARNING: The requested image's platform (linux/amd64) does not match the detected host platform (linux/arm64/v8) and no specific platform was requested\"" |
There was a problem hiding this comment.
Can these be removed, or does the no-op function throw a compatibility error without them?
| + renderStatus: | ||
| + mutationSteps: | ||
| + - image: ghcr.io/kptdev/krm-functions-catalog/no-op:latest | ||
| + exitCode: 0 |
There was a problem hiding this comment.
when should be introduced into the pipeline result as suggested here before.
| err = os.Symlink(filepath.Join("path", "to", "pkg", "dir"), "link") | ||
| assert.NoError(t, err) | ||
| if err != nil { | ||
| t.Skipf("skipping test due to symlink creation failure (requires admin/developer mode on Windows): %v", err) |
There was a problem hiding this comment.
This skip should be conditional on Windows only. Skipping unconditionally means we lose the assertion on environments where the error is valid.
| if err != nil { | ||
| t.Skipf("skipping test due to symlink creation failure (requires admin/developer mode on Windows): %v", err) | ||
| } |
There was a problem hiding this comment.
This skip should be conditional on Windows only. Skipping unconditionally means we lose the assertion on environments where the error is valid.
| ) | ||
|
|
||
| const ( | ||
| celCheckFrequency = 100 |
There was a problem hiding this comment.
Yes @efiacor It would be preferable to expose these as configurable options rather than hardcoded constants. Since the when field accepts arbitrary user-written CEL expressions, complex expressions could hit the hardcoded limits today. Having configurable limits would provide the flexibility needed without requiring code changes.
| }) | ||
| defer clean() | ||
|
|
||
| // Skip if the test repo doesn't have real symlinks (e.g. Windows/WSL with |
There was a problem hiding this comment.
WSL natively supports symlinks, so these tests should work fine there. The problem only arises when the repo is cloned on Windows (or with core.symlinks=false) and then accessed from WSL - in that case git stores symlink targets as plain files rather than actual symlinks. The solution for WSL is simply to clone the repo within WSL itself.
For Windows, a runtime.GOOS == "windows" check is the appropriate way to skip these tests. I'd prefer this change to be scoped specifically to Windows rather than using a broader file-inspection approach that could inadvertently skip tests on other platforms.
| if err != nil { | ||
| return nil, err | ||
| } | ||
| if r.CelCondition != "" { |
There was a problem hiding this comment.
nil check for opts.CELEnvironment?
9adb73f to
0debe62
Compare
Signed-off-by: SurbhiAgarwal1 <agarwalsurbhi1807@gmail.com> Signed-off-by: SurbhiAgarwal1 <surbhi.agarwal@example.com>
Signed-off-by: SurbhiAgarwal1 <surbhi.agarwal@example.com>
Signed-off-by: SurbhiAgarwal1 <surbhi.agarwal@example.com>
Signed-off-by: SurbhiAgarwal1 <surbhi.agarwal@example.com>
Signed-off-by: SurbhiAgarwal1 <surbhi.agarwal@example.com>
Signed-off-by: SurbhiAgarwal1 <surbhi.agarwal@example.com>
…eck, configure CEL limits, fix windows skips Signed-off-by: SurbhiAgarwal1 <surbhi.agarwal@example.com>
Signed-off-by: SurbhiAgarwal1 <surbhi.agarwal@example.com>
0debe62 to
5b6eb9b
Compare
Signed-off-by: SurbhiAgarwal1 <SurbhiAgarwal1@example.com>
Signed-off-by: SurbhiAgarwal1 <surbhi.agarwal@example.com>
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