I'm writing an Azure DevOps extension in which I'd like to create a server task to execute a couple of http requests and wait for the completion event from an external source. My problem is that the server task options are almost undocumented and so this became a guess-and-try game from my part.
I've used the following two resources to have some ideas what I can do:
- https://github.com/Microsoft/azure-pipelines-tasks/blob/master/docs/authoring/servertaskauthoring.md
- https://github.com/microsoft/azure-pipelines-task-lib/blob/master/tasks.schema.json
Also I've checked a couple of public extensions with server tasks:
- https://github.com/Microsoft/azure-pipelines-tasks/blob/master/Tasks/InvokeRestApiV1/task.json
- https://github.com/microsoft/azure-pipelines-extensions/blob/master/Extensions/ServiceNow/Src/Tasks/UpdateChangeRequest/UpdateChangeRequestV2/task.json
- https://github.com/microsoft/azure-pipelines-extensions/blob/master/Extensions/ServiceNow/Src/Tasks/CreateAndQueryChangeRequest/CreateAndQueryChangeRequestV2/task.json
Even though there are signs in these that what I'm trying to achieve is possible, so far, none of my attempts have worked.
task.json
"execution": {
"HttpRequestChain": {
"Execute": [
{
"RequestInputs": {
"EndpointUrl": "first-url"
"Method": "first-method",
"Headers": "first-headers",
"Body": "first-body",
"Expression": "first-condition-expression"
},
"ExecutionOptions": {
"OutputVariables": "first-outputs",
"SkipSectionExpression": "first-skip-expression"
}
}
.
.
.
{
"RequestInputs": {
"EndpointUrl": "last-url"
"Method": "last-method",
"Headers": "last-headers",
"Body": "last-body",
"Expression": "last-condition-expression"
},
"ExecutionOptions": {
"OutputVariables": "last-outputs",
"SkipSectionExpression": "last-skip-expression"
}
}
]
}
}
First I tried to add "WaitForCompletion": "true" to the last RequestInputs section as can be seen in servertaskauthoring.md under HttpRequest and in CreateAndQueryChangeRequestV2/task.json.
It did not do anything as far as I could tell, and also found the following community question and its related Github issue which says this:
The 'waitForCompletion' option is currently not available for HttpChainRequest task by design.
So, I changed my approach and wanted to add a prejobexecution section to split my task into two parts: a preparation part and a waiting part.
"prejobexecution": {
"HttpRequestChain": {
"Execute": [
{
"RequestInputs": {
"EndpointUrl": "first-url"
"Method": "first-method",
"Headers": "first-headers",
"Body": "first-body",
"Expression": "first-condition-expression"
},
"ExecutionOptions": {
"OutputVariables": "first-outputs",
"SkipSectionExpression": "first-skip-expression"
}
}
.
.
.
]
}
}
"execution": {
"HttpRequest": {
"Execute": {
{
"EndpointUrl": "last-url"
"Method": "last-method",
"Headers": "last-headers",
"Body": "last-body",
"Expression": "last-condition-expression",
"WaitForCompletion": "true"
}
}
}
}
In this scenario, the prejobexecution part did not show up, only the execution was added to the pipeline run. I guess the prejobexecution is not supported by server tasks, but I could not find any resource explicitly pointing this out.
Currently, I'm experimenting with two separate server tasks, one using the HttpRequestChain without wait and one using the HttpRequest with wait. I haven't tried it out yet, but regardless of the result, I feel having everything in one task is easier to use/setup and way more elegant.
Thus, I'm wondering if it is possible to achieve and if so, how. In addition it would be a huge help if anyone could share with me a complete documentation about server tasks or why my previous attempts were not successful.
Edit: adding details about the goal of the extension
I'd like to provide an easy way to stop a pipeline run at any point and ask for an approval from a specific person or member of a specific group. It'd be different
- from the ManualValidation task, because only the selected person/people could approve, not anyone with queue builds permission, and
- from the approvals and checks, because it could be added to any point of a pipeline run, not just to the start of a stage.
This is definitely a need at my company, but I saw similar feature requests, so I decided to develop it independetly as a public extension and upload it to the marketplace. That is why I'm trying to make it into one task only; I hope that'll make the whole extension more userfriendly, less error-phrone and easier to use overall. And since the plan is to share it with other people, converting it into a template or task group is not working for this case if my understanding is correct.