Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[TEP-0143] Concise Parameters and Results - proposed #1071

Merged
merged 1 commit into from
Nov 9, 2023

Conversation

Yongxuanzhang
Copy link
Member

@Yongxuanzhang Yongxuanzhang commented Sep 20, 2023

This commit adds the proposal of concise parameters and results.

Signed-off-by: Yongxuan Zhang [email protected]

@tekton-robot tekton-robot added the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Sep 20, 2023
@tekton-robot tekton-robot added the size/XL Denotes a PR that changes 500-999 lines, ignoring generated files. label Sep 20, 2023
@Yongxuanzhang Yongxuanzhang force-pushed the tep-143-results-params branch 3 times, most recently from 3e10b78 to de6e695 Compare September 20, 2023 15:41
@Yongxuanzhang Yongxuanzhang marked this pull request as ready for review September 20, 2023 15:45
@tekton-robot tekton-robot removed the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Sep 20, 2023
teps/0143-concise-parameters-results.md Outdated Show resolved Hide resolved
teps/0143-concise-parameters-results.md Outdated Show resolved Hide resolved
teps/0143-concise-parameters-results.md Outdated Show resolved Hide resolved
teps/0143-concise-parameters-results.md Outdated Show resolved Hide resolved
teps/0143-concise-parameters-results.md Outdated Show resolved Hide resolved
teps/0143-concise-parameters-results.md Outdated Show resolved Hide resolved
teps/0143-concise-parameters-results.md Outdated Show resolved Hide resolved
teps/0143-concise-parameters-results.md Outdated Show resolved Hide resolved
teps/0143-concise-parameters-results.md Outdated Show resolved Hide resolved
teps/0143-concise-parameters-results.md Outdated Show resolved Hide resolved
@Yongxuanzhang
Copy link
Member Author

Hi @tektoncd/core-maintainers, ptal at this proposal, looking forward to your thoughts! Thanks!

@Yongxuanzhang
Copy link
Member Author

Yongxuanzhang commented Sep 20, 2023

cc @khrm @pritidesai
would you be interested in reviewing this?

@jerop jerop changed the title [TEP-0143] Concise params and results - proposed [TEP-0143] Concise Parameters and Results Sep 20, 2023
@chitrangpatel
Copy link
Member

/kind tep

@tekton-robot tekton-robot added the kind/tep Categorizes issue or PR as related to a TEP (or needs a TEP). label Sep 20, 2023
@dibyom
Copy link
Member

dibyom commented Sep 25, 2023

/assign @pritidesai
/assign @dibyom

Copy link
Member

@vdemeester vdemeester left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like the idea of that proposal (@abayer knows how often I bugged him about this param/result syntax 😛), but I don't see a way to have it in v1. I would see this as the basis of a v2 API work.

teps/0143-concise-parameters-results.md Outdated Show resolved Hide resolved

Tekton is a cloud-native platform that aims to be the industry standard for CI/CD. However, its syntax is complex and verbose, making it tedious to use. This is one of the barriers to its adoption. To make Tekton more user-friendly, we need to simplify and concise its syntax. This will make it easier to author, read and adopt Tekton.

This document proposes improving the syntax for `Parameters` and `Results`. Take a look at the release `Pipeline` as an example. Users need to repeatedly write name and value for the `Parameters` and `Results`, which is not necessary and very lengthy.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"Users need to repeatedly write name and value […]" applies on PipelineRun am I right ?

Copy link
Member Author

@Yongxuanzhang Yongxuanzhang Sep 27, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes! The proposal includs pipelinerun, taskrun, and pipeline, task


#### Parameters

At authoring time, users declare string, array and object `Parameters` for `Tasks` and `Pipelines`. It is tedious to specify these fields because they are defined as sub-objects. We propose using maps instead of sub-objects to declare `Parameters`. The new syntax of `Params` will go under a new api field `Inputs.Params`. This is because we cannot modify the existing `Params` field because of our [Go compatibility policy][cp].
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We used to have inputs as well, so I would be very caution re-introducing it.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we will introduce them back in #1044, cc @jerop @afrittoli to confirm.
The main reason is that we can not change the current params and results, and we need to put them under a new api field, and tep-0139 will introduce artifacts with input and output, so it makes sense to add params and results there

Comment on lines 798 to 800
### Create v2alpha1 API

Create v2alpha1 API, change the `Param` and `Results` to use the new syntax without introducing new fields. However, this means that we have to maintain one more API version with minimal change from the current version.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would definitely want to go that way for that proposal (aka going towards a v2… API). If we do not, we are going to make the v1 API more convoluted as we go. And we cannot ever remove fields from v1 so.. having 2 ways to provide the same information on a API is generally not really ideal, and will be very confusing and very tricky to achieve implementation wise (what do we do if both are used, …)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes that's a very good point and we have also discussed it as well!
From the implementation wise, 1) this will be an alpha feature gated by dedicated feature flag, this can make sure that users won't accidentally define both. 2) we will add validation to the webhook to make sure that only one of them is defined.

I agree that it is not ideal that users can define the same thing in 2 places, the way we mitigate it is to use feature flag, documentation.

And the main reason we propose to add in v1 is that v1 users can try out this new syntax and provide early feedback. Another reason is introducing v2alpha1 will introduce more maintaining efforts to tekton pipeline (not sure if this is a valid concern).

I think we're always open change the proposal to what's best for tekton 😄 .

Copy link
Member Author

@Yongxuanzhang Yongxuanzhang Oct 2, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @vdemeester @afrittoli, just want to learn more about your thoughts on getting early feedback from users by adding them in v1 api.
From the implementation perspective, if we add v2alpha1, we will need more efforts, e.g.:

  1. we need to consider conversion among v2alpha1, v1, v1beta1.
  2. developers making api changes to v1 will update v2alpha1.

So I don't think this is a good timing to introduce v2alpha1 considering that we just have v1 this year, and there are not many features we can introduce in v2alpha1.

If you think this proposal is not a good fit to v1(duplicate with current params and results). We may just change this proposal to add it to v2 in the future and don't work on it now.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1 this is not ideal UX in v1. To me, the most valuable part to introduce this feature now but not in v2 is that we can collect some early feedback/data points which can help us make the right decision when moving to v2.

I think gating it under a dedicated feature flag can mitigate the confusion to user. However, we may need to be more careful to promote this feature to beta or stable where the feature will be opted in by default (as part of the reason to support the feature in v1 is to collect early feedback).

We also need clear documentation to explain the context.

Copy link
Member

@vdemeester vdemeester Oct 5, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Having 2 different ways to solve the same problems in the same API is, in my opinion, also not necessarily a good UX.
Looking back, we even moved from inputs.params to params while bumping API version (v1alpha1 to v1beta1) even though we could have done breaking changes in v1alpha1.

The proposal of adding this to v1, and in general to add a lot of new fields in v1 seems like we don't treat v1 as stable, or as complete enough to be considered as is. This is fine, but v1 is there, and is there for a while, and is considered stable from our user's perspective. We have to be very careful when adding new fields to v1.

Any field we add to v1 (even behind a feature-flag) are there to stay (they can't be removed). Any field we add to v1 need to be documented (and would automatically be if we fix tektoncd/pipeline#1461 (and tektoncd/pipeline#3416 at the same time) — and for each "alpha" or experimental ones, we need to make it show as it in the doc, etc..

Other question arrives : kubectl (and Kubernetes in general) is merging objects with kubectl apply for example. This lead to problems between v1alpha1 and v1beta1 as it was merging inputs.params with params. Having both on the same object would also be an issue — I created my object with params, I now want to try that new consice thing, I switch to inputs.params and I apply, it breaks. But because it's on v1, this issue could never be fixed for the v1 API as we cannot remove fields — we would be stuck with this issue until v2 (the stable one) and v1 gone and out of support (which would be.. in a really long time, years and years from now).

Having a v2alpha1 or a feature-flag is similar in that they require the user to do something. But one is way more explicit in its "experimental" nature, as you are using v2alphaX API, so you know you shouldn't use it in production, you know it could break tomorrow.

From the implementation perspective, if we add v2alpha1, we will need more efforts, e.g.:

For me, this is not a concern. The aim is end-user consumption, happyness, etc. If we need to do more effort to make a better user experience, I'll choose this over and over.

  • we need to consider conversion among v2alpha1, v1, v1beta1.
  • developers making api changes to v1 will update v2alpha1.

That's the thing about v2alpha1, it could be "incomplete" in way, as it's alpha, it's there for exploration.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

Having 2 different ways to solve the same problems in the same API is not a good UX.

Yes I agree, even if it is gated by a feature flag, users may get confused.

we need to be very careful to add new api into v1.

Yes I agree. Trusted artifacts is proposing to add inputs.artifacts and outputs.artifacts, so for tep-0143 we just need to add params and results to them.

Having both on the same object would also be an issue ...

I think this can be avoided by how we implement this? My current PoC is using mutation webhook to populate current params with the inputs.params, and we don't need to change the reconciler code. So if there is existing pipelinerun with params, the new object would just have both inputs.params and paramsand won't break.

So I think "having 2 different ways of defining the same thing in api" is a valid reason that we should not add it to v1

Copy link
Member

@afrittoli afrittoli Oct 9, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Having 2 different ways to solve the same problems in the same API is not a good UX.

Yes I agree, even if it is gated by a feature flag, users may get confused.

Indeed, so maybe we shouldn't do it?

we need to be very careful to add new api into v1.

Yes I agree. Trusted artifacts is proposing to add inputs.artifacts and outputs.artifacts, so for tep-0143 we just need to add params and results to them.

That's not the API I proposed for trusted artifacts.
It was later proposed to adopt inputs.artifacts and outputs.artifacts to match this proposal, not the other way around.
I'm still unsure whether we need the extra level of indentation with inputs and outputs. Do you have any more insights on the advantages of that?

I would argue that a v1alpha1 might be more easily adopted by users, because unless operators explicitly disable v1alpha1, users can experiment with it. Feature flags instead are controller by the operator.

Using a different API version would mean that users could try and query existing resources via the v1alpha1 endpoint, to see how existing resources would look like in v1alpha1 format.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! @afrittoli are you suggesting v1alpha1 or v2alpha1?

It was later proposed to adopt inputs.artifacts and outputs.artifacts to match this proposal, not the other way around.
I'm still unsure whether we need the extra level of indentation with inputs and outputs. Do you have any more insights on the advantages of that?

Oh if so, I think we can just don't use inputs and outputs. I will update this PR to propose the change in a new api version

Copy link
Contributor

@khrm khrm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We lose Type safety with this TEP.

@Yongxuanzhang
Copy link
Member Author

Yongxuanzhang commented Sep 27, 2023

We lose Type safety with this TEP.

Thanks! We have discussed this a bit in the thread of this doc. And we have also mentioned that this is a drawback in this proposal, I don't think there is a way to really solve it (e.g. we cannot really tell users that they have defined duplicate params with the map syntax)

We can provide explicit documentation, yaml syntax check tools to mitigate this issue and I believe this is the trade-off we can make.

Or there might be more severe type safety issues we miss? Please let us know, and if the proposal cannot address it, I think we can seek other alternatives.

@khrm
Copy link
Contributor

khrm commented Sep 28, 2023

@Yongxuanzhang Yes, I didn't get time to discuss that further.

# after
inputs:
params:
hello:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is fine and safe. It will be validated easily during the creation. It will be put to

map[string]struct.

# after
inputs:
params:
hello: world
Copy link
Contributor

@khrm khrm Sep 28, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is unsafe. I assume it will be decoded/unmarshal to:

map[string]interface{}

? Isn't it so?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What happens is that we might need to have some reserved keywords for the string key.
What happens if someone mistakenly indents serviceAccountName at the same level? Or some other top elements.

The present API won't let you create these.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

but the all these key: value, fields defined under params right?
serviceAccountName comes under params?

Copy link
Contributor

@khrm khrm Sep 28, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

serviceAccountName doesn't come under params. It's on a different level but here we don't know whether key serviceAccountName is some params or spec.serviceAccountName . So we can't validate. We will need to reserve this.

Copy link
Contributor

@khrm khrm Sep 28, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On a side note, we shouldn't think of this from trying to solve validation via Go code. Is it easier to validate in 1.26+ k8s using CEL Validating admission policies?

Copy link
Member Author

@Yongxuanzhang Yongxuanzhang Sep 28, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is unsafe. I assume it will be decoded/unmarshal to:

map[string]interface{}

? Isn't it so?

We will still use this function to unmarshal it, it will be map[string]ParamValue, so it is not interface{}

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What happens is that we might need to have some reserved keywords for the string key. What happens if someone mistakenly indents serviceAccountName at the same level? Or some other top elements.

The present API won't let you create these.

Are you saying that the proposal won't work with reserved param? Let's say is a "paramA" is reserved, we can just add function to validation webhook to check if the map[string]ParamValue has a key of "paramA"?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@khrm @Yongxuanzhang I'm not 100% I got it right, this is my understanding of the issue.
Current TaskRun spec:

spec:
  params:
  - name: example
    value: foo
  serviceAccountName: default

New TaskRun spec:

spec:
  input:
    params:
      example: foo
  serviceAccountName: default

With the new spec, if serviceAccountName was not indented properly, you could have:

spec:
  input:
    params:
      example: foo
      serviceAccountName: default

Which would not fail validation if the Task in question had a parameter called serviceAccountName.
This could not happen with the current API. This could be prevented in the new syntax by forbidding serviceAccountName as a parameter name.

@Yongxuanzhang
Copy link
Member Author

Yongxuanzhang commented Oct 12, 2023

Thanks for this, it's a very interesting idea!

If you have context on why the current syntax was chosen it would help better understanding what we might be losing with the change.

@afrittoli Thanks!
The issue author suggests using map syntax because it will reduce the verbosity, which is the same motivation for our proposal.
One reason not using map is to avoid confusions for novice users, pointed out in this comment.

This could be a trade off we make and I think we need to collect users feedback as well. We cannot propose something we think good for users but actually causes confusions. So I will change this proposal to proposed status and this could be something we consider for v2. At that time we will collect users' feedback and see if this is a good change?

@Yongxuanzhang Yongxuanzhang changed the title [TEP-0143] Concise Parameters and Results [TEP-0143] Concise Parameters and Results - proposed Oct 12, 2023
@Yongxuanzhang
Copy link
Member Author

Hi @vdemeester, @afrittoli, @pritidesai I have updated the proposal to proposed status, and change it to suggest adding in v2alpha1. Please take a look. Thanks! 🙏

@Yongxuanzhang Yongxuanzhang force-pushed the tep-143-results-params branch 2 times, most recently from 07500ba to 8f9f8e5 Compare October 12, 2023 21:02
@tekton-robot tekton-robot added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Oct 13, 2023
commit: {}
```

At runtime, `Results` are stored in the status of `TaskRuns`, `PipelineRuns` and `CustomRuns` as sub-objects. We propose using maps instead of sub-objects to produce `Results` at runtime. We also propose removing the type field that’s added by default to all `Results` in status.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

About the removal of type, I guess that's because it can be inferred from the format of the result?

Copy link
Member

@afrittoli afrittoli left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the update, it looks good to me.
I still have a couple of comments, but nothing blocking the "proposed" state for me.
/approve

@tekton-robot tekton-robot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Oct 16, 2023
@tekton-robot tekton-robot removed the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Oct 19, 2023
@pritidesai
Copy link
Member

/assign @khrm

@tekton-robot tekton-robot added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Oct 23, 2023
This commit adds the proposal of concise params and results.

Signed-off-by: Yongxuan Zhang [email protected]
@tekton-robot tekton-robot removed the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Oct 24, 2023
@jerop
Copy link
Member

jerop commented Nov 9, 2023

@dibyom @khrm @pritidesai can we please merge this as proposed? we will continue to discuss as we work towards making this proposal implementable

@dibyom
Copy link
Member

dibyom commented Nov 9, 2023

Merging as proposed sounds fine to me
/approve

@khrm
Copy link
Contributor

khrm commented Nov 9, 2023

/approve

Yes.

@tekton-robot
Copy link
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: afrittoli, dibyom, khrm, vdemeester

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@jerop
Copy link
Member

jerop commented Nov 9, 2023

Thank you!

/lgtm

@tekton-robot tekton-robot added the lgtm Indicates that a PR is ready to be merged. label Nov 9, 2023
@tekton-robot tekton-robot merged commit 03469b1 into tektoncd:main Nov 9, 2023
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
approved Indicates a PR has been approved by an approver from all required OWNERS files. kind/tep Categorizes issue or PR as related to a TEP (or needs a TEP). lgtm Indicates that a PR is ready to be merged. size/XL Denotes a PR that changes 500-999 lines, ignoring generated files.
Projects
None yet
Development

Successfully merging this pull request may close these issues.