huserben / TfsExtensions

Extensions for TFS 2015+ such as custom Widgets (require TFS 2017) and Build Tasks
MIT License
45 stars 22 forks source link

Is that possible to define a "builds chain" and wait for it to finish? #52

Closed Koshak118 closed 6 years ago

Koshak118 commented 6 years ago

HI Benj

Thanks for the great extension, first of all.

We have a chain of build definitions, like Build1->Build2->...->Build5, and we want to make sure that once a "Build1" has been triggered, it won't be possible to trigger any other build in the chain until the last build in a chain, Build5, is finished.

In other words, we want to lock all the chain once the chain started to be built. And we've got only one, default queue for the building jobs.

How can we do that?

Thanks in advance Ilya

huserben commented 6 years ago

Hi @Koshak118

so you want to prevent that anyone would manually queues of the builds in your chain once it's started? Or you don't want any build queued via the task itself?

If it's the first, I'm sorry but I don't know if this is possible. Anyway I think you would need to ask the VSTS/TFS people directly or maybe open a question on StackOverflow.

If you want to achieve the second, then you could use the Conditions of the Task to check whether one of the builds is already in the queue or running at the moment and only queue when none of those builds are currently in the queue.

Koshak118 commented 6 years ago

Hi @huserben

The second. So using Conditions on Build1 I can specify something like "do not start the build if Build2...Build5 are in the queue or running", right? We tried this, but if we have Build3 is running and someone queues the Build1 with the specified conditions it won't start until Build3 is finished indeed, but then the build agent will see the queued Build1 and will start it instead of Build4 in the chain.

That's the behavior has been started to happen quite recently, I have to say, and it literally destroys all our pipeline - since we've remote teams which start the same chain of builds on different branches and overwrites the other's teams artifacts.

huserben commented 6 years ago

I assume Build1 is queued somehow automatically for example as consequence of a Check-In? Or manually? I think its hard to prevent someone from queueing Build 1 as this happens "outside of the scope" of the task.

However what could be a solution is that you just Trigger all the build of the chain from Build 1, then you ensure that they are ran after each other. If you depend on the fact that the previous build of the chain was successful, you could achieve this via the WaitTask that is available.

For example it would somehow like this: Build 1

Build 2 Just run everything as normal, don't queue Build 3 as Build 1 already did this

Build 3 (Depends on Build 2 being successful) Use WaitForBuild to finish Task with the ID specfieid to the build. Set the option that the build should fail if the awaited build failed.

I think with this you could achieve what is intended. However it brings the drawback that you cannot really run anymore the builds 2-5 without having it queued from Build 1. I'm not sure if this would be a problem for your use-case.

Koshak118 commented 6 years ago

HI @huserben

So I've triggered all the builds from the Build1 and it seems like a reasonable solution.

There are still issue I am still messing around - how is it possible to specify Build ID from other project? I mean I can do it specifying "URL to TFS Server (including Collection and Team Project)" in a main configuration section, but how to specify it in "Enable Build in Queue Condition"?

Another one - once I trigger all the builds at a single point of time, specifying Control option "Only when all previous tasks have succeeded" doesn't make sense - since the "Trigger Build" task has succeeded but it says nothing about the relevant build task success.

huserben commented 6 years ago

Hi

so just for my understanding. Build 1 is not in the same Team Project/Server as the other builds? Do you need to fail Build 1 if any of the subsequent Builds in the chain failed or can you just let it finish? You mentioned you only have 1 queue, how many agents do you have? When you wait for builds to be finished but there is no available agent you can easily end up in a deadlock.

So the Build In Queue Condition takes the name of the Build Definition. This means you could specficy "Build2, Build3, Build4" there and it would check if any build of those definitions is currently queued. (This will only work if those builds are actually in the Team Project that was specified in the basic configuration section). So the condition does not check for individual builds themselves, but for any build of a given configuration in general.

If you want to check whether the queued builds were successful, you have two options. You either use the separate WaitTask or you enable the option in the TriggerBuildTask itself. In the advanced configuration you can select the option "Wait for Builds to complete" and optionally make the task fail if the triggered builds have failed.

The wait task is useful if you want to do things in the meantime and just await the builds at the end, or if you want to trigger multiple builds with more than one instance of the build task:

If the WaitTask shall be used, you have to make sure to Store the triggered build id's as part of the TriggerBuildTask so the WaitTask knows which id's to await.

Did this clear up things a bit for you? Otherwise please let me know and I'll try to explain in more detail.

Koshak118 commented 6 years ago

Hi @huserben

Sorry for the delayed answer

So yes, the option I'd like to use is "Wait for Builds to complete" for the use case where Build3 and Build 2 are not in the same project but I do not want Build3 to start if Build2 has been failed. In that case the URL of the team project should be specified in some way but I didn't find a way to do that.

I do not want to use "WaitTask" since it, If I get it right, will wait before triggering the build after itself, and then the whole point of creating atomic chain of builds, which cannot not be interfered, get lost

huserben commented 6 years ago

Hi

ok, so the question is as well if you want to fail Build 1 if any of the other builds in the chain fails. If not, you don't need to await anything in the first build.

So where you need the "WaitForBuild" Task is for your requirement I do not want Build3 to start if Build2 has been failed. You cannot prevent it from being started, so I would just doing it like this:

With this setup, you have achieved that:

Would this be the scenario desired?

huserben commented 6 years ago

Hi @Koshak118

were you able to try out what I suggested in my last reply?

Koshak118 commented 6 years ago

Hi @huserben

Sorry for delayed responses, hectic days

Give me a week or two and I'll look at this issue again

Thanks for the assistance

huserben commented 6 years ago

Hi @Koshak118

did you have any time to look into this?

huserben commented 6 years ago

Closed due to inactivity. In case of any answer it can be reopened.