-
Notifications
You must be signed in to change notification settings - Fork 1.8k
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
Sort the steps of taskrun based on the steps of task #963
Conversation
/assign @hrishin @bobcatfish @vdemeester |
this sounds worthwhile enough to mention in the release note, |
func sortTaskRunSteps(taskRunSteps []v1alpha1.StepState, taskSpecSteps []corev1.Container) { | ||
// Generate the map matching the step name and its index | ||
sorter := constructTaskStepsSorter(taskSpecSteps) | ||
for index, step := range taskRunSteps { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We may be able to use the sort
package here 👼
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tried, but the the sort package is easy to sort the array with a filed or multiple fields in itself. Have not figured out to sort one array by aligning with another array.
|
||
sortTaskRunSteps(taskRunStatusSteps, task.Spec.Steps) | ||
|
||
for index, step := range task.Spec.Steps { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if it would be more clear to do the cmp.Diff
on the taskRunStatusSteps
and an expectedTaskRunStatusSteps
instead 👼
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My question is how to create the fake taskRunStatusSteps and the expectedTaskRunStatusSteps?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
well, expectedTaskRunStatusStep
would be declared as taskRunStatusSteps
but in the right order 👼
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Got it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you @houshengbo 😄 for the PR.
Left few comments, please me know if that makes sense? 🙇♂️
@@ -361,6 +415,12 @@ func updateStatusFromPod(taskRun *v1alpha1.TaskRun, pod *corev1.Pod, resourceLis | |||
}) | |||
} | |||
|
|||
if len(taskSpecSteps) > 0 { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
wondering if this check is really needed? 🤔
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I change the code structure a bit in order to separate the sortTaskRun function.
if len(taskSpecSteps) > 0 { | ||
trt := new(TaskRunWithTask) | ||
trt.Init(taskRun.Status.Steps, taskSpecSteps[0]) | ||
sort.Sort(trt) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wondering if sorting should be done outside of updateStatusFromPod
method? 🤔
In that way
- Writing the unit test would be easy
- Single responsibility: Sorting responsibility could be taken outside of methods scope
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I change the code structure a bit in order to separate the sortTaskRun function.
@hrishin I have changed the structure of the code a bit. In order to separate the sort function, we have to make sure it is done between we get the taskrun and we update the taskrun. |
/retest |
Thank you @houshengbo 🙇♂️ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One nit, otherwise looks good
/lgtm
mapForSort map[string]int | ||
} | ||
|
||
func (trt *TaskRunWithTask) Init(taskRunSteps []v1alpha1.StepState, taskSpecSteps []corev1.Container) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: I feel we don't need this and we could just declare it inline here
trt := &TaskRunWithTask{
taskRunSteps: taskRunSteps,
mapForSort: trt.constructTaskStepsSorter(taskSpecSteps),
}
But it's more a aesthetic thing than anything, so I am ok with both I think 👼
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thx.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for working on this @houshengbo !! I have a couple of requests:
- Could you also add some docs to https://github.com/tektoncd/pipeline/blob/master/docs/taskruns.md#syntax about the states in the status and what order they are expected to be in?
- Could you add a test at the reconciler level as well (https://github.com/tektoncd/pipeline/blob/3d87e2e18174f1d7b088bdd14065d5f06ef86462/pkg/reconciler/v1alpha1/taskrun/taskrun_test.go) and also update an end to end test to verify this? Having this work correctly relies on the sorting function being called in the reconciler and then no more modifications being made to the status order after that, which future contributors might not realize, so adding some more testing around this could save us later :)
// elements of the array in the Swap function. | ||
return true | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can we move this logic out of the reconciler into a separate file / separate package? 🙏 the less code in the reconciler the better :D
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This would include moving sortTaskRunStepOrder
and making it exported in the new package (SortTaskRunStepOrder
)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I thought about it before.
Would you mind we have a new package with a more general name like utils, so that we can put this sorter and maybe further algorithm(TBD) inside it? @bobcatfish
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd like to name a new package utils.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@houshengbo I would definitely advise against utils
😅 generic names like utils
or helpers
do not convey anything of what is inside. This function is about sorting taskrun, so it could either be called sort
(inside taskrun
) or something a tiny bit more general like list
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Forget about my previous comment.
what about stepsorting
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@houshengbo 🤗 as it's related to tasks
I feel it would be better in a package name that has task
in (the path or the name) (tasks.SortBySpecOrder
instead of my previous propositon)
cc @bobcatfish as I am not the greatest to find correct names 😂
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ooo i like both the ideas! stepsorting
is pretty close to what I would have suggested but I think @vdemeester is right, we'd end up with something like stepsorting.Sort
🤔
we have been kind of in need of a status
related package for a while now (we have lots have status stuff in the reconciler) how about something like taskrunstatus
or status
, so we could have taskrunstatus.SortSteps
or status.SortSteps
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ohh I do like the status
package 😻 status.SortSteps
sounds really good to me !
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yep, I think we can agree on that.
trt.mapForSort = trt.constructTaskStepsSorter(taskSpecSteps) | ||
} | ||
|
||
// This function constructTaskStepsSorter constructs a map matching the names of |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the expected format for comments like this i usually for them to start with the name of the function, e.g.:
// constructTaskStepsSorter constructs a map matching the names of ...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done. Thx.
}} | ||
|
||
sortTaskRunStepOrder(taskRunStatusSteps, task.Spec.Steps) | ||
if d := cmp.Diff(taskRunStatusSteps, expectedStepState); d != "" { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is pretty minor but the test would be a bit easier to read if it asserted the names of the names of the steps only, e.g. something like:
actualStepOrder := []string{}
for _, state := range(taskRunStatusSteps) {
actualStepOrder = append(actualStepOrder, state.name)
}
expectedStepOrder := []string{"hello", "exit", "world", "nop"}
if d := cmp.Diff(actualStepOrder, expectedStepOrder); d != "" {
}
Then you can completely get rid of expectedStepState
:D
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(this would also make it a bit easier to add a few more tests cases as well)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done. Thx.
@@ -82,6 +83,58 @@ const ( | |||
imageDigestExporterContainerName = "step-image-digest-exporter" | |||
) | |||
|
|||
type TaskRunWithTask struct { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I got a bit confused about what this type was - it seems to me like the main goal of this type is to sort StepStates, how about calling it something like StepStateSorter
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done. Thx.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/lgtm
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking good! I just have a minor request about docs, otherwise good to go 🙏
docs/taskruns.md
Outdated
If multiple `steps` are defined in the `Task` invoked by the `TaskRun`, we will see the | ||
`status.steps` of the `TaskRun` displayed in the same order as they are defined in | ||
`spec.steps` of the `Task`, when the `TaskRun` is accessed by the `get` command, e.g. | ||
`kubectl get taskrun <name> -o yaml`. Replace \<name\> with the name of the `TaskRun`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thanks for adding this! could you put it in a status
section on it's own, maybe between the syntax
and ordering
sections, and add a link to the new section in the overview at the top of the file? https://github.com/tektoncd/pipeline/blob/master/docs/pipelines.md#pipelines
This will give us a place to start putting more docs about the status in the future as well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a change on the file taskruns.md, not pipeline.md.
Do you actually mean to add a section in taskruns.md?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
whoops my bad! no taskruns is the right place :D
|
||
// The order of the container statuses has been shuffled, not aligning with the order of the | ||
// spec steps of the Task any more. After Reconcile is called, we should see the order of status | ||
// steps in TaksRun has been converted to the same one as in spec steps of the Task. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nice comment!
trt := new(StepStateSorter) | ||
trt.Init(taskRunSteps, taskSpecSteps) | ||
sort.Sort(trt) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nice, thanks for making the new package!
actualStepOrder = append(actualStepOrder, state.Name) | ||
} | ||
|
||
expectedStepOrder := []string{"hello", "exit", "world", "nop"} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nice, i like how the expected order is hardcoded here, very clear!
bah, reopened tektoncd/plumbing#29 /test pull-tekton-pipeline-integration-tests |
whyyyyyyyy |
/test pull-tekton-pipeline-integration-tests |
/lgtm |
In response to this:
Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository. |
@bobcatfish Thank you. |
/lgtm |
/approve |
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: bobcatfish, houshengbo 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 |
Changes
Closes: #942
Submitter Checklist
These are the criteria that every PR should meet, please check them off as you
review them:
See the contribution guide
for more details.
Release Notes