In the release pipeline we're making REST call using InvokeRESTAPI@1, and then in the REST service implementation trying to raise "TaskStartedEvent" and the append logs. The problem is -in the azure devops we see task as pending and not started and we do not see our logs. It is strange as TaskCompletedEvent works fine, we were able to fail of successfully complete the task.
Here is the full code - input params are taken from the REST API call that is made this way - in task definition we put information to the headers:
{
"Content-Type":"application/json",
"PlanUrl": "$(system.CollectionUri)",
"ProjectId": "$(system.TeamProjectId)",
"HubName": "$(system.HostType)",
"PlanId": "$(system.PlanId)",
"JobId": "$(system.JobId)",
"TimelineId": "$(system.TimelineId)",
"TaskInstanceId": "$(system.TaskInstanceId)",
"AuthToken": "$(system.AccessToken)"
}
And then read it from headers
[ApiController]
public class DatabaseUpdaterController : ControllerBase
{
[HttpPost("updateDatabase")]
public async Task UpdateDatabase()
{
string projectId = this.Request.Headers["ProjectId"];
string planId = this.Request.Headers["PlanId"];
string jobId = this.Request.Headers["JobId"];
string timelineId = this.Request.Headers["TimelineId"];
string taskInstanceId = this.Request.Headers["TaskInstanceId"];
string hubName = this.Request.Headers["HubName"];
string taskInstanceName = this.Request.Headers["TaskInstanceName"];
string planUrl = this.Request.Headers["PlanUrl"];
string authToken = this.Request.Headers["AuthToken"];
// Ensure projectId, planId, jobId, timelineId, taskInstanceId are proper guids.
var credentials = new VssBasicCredential("", authToken);
var azureDevOpsConnection = new VssConnection(
new Uri(planUrl),
credentials);
var taskClient = azureDevOpsConnection.GetClient<TaskHttpClient>();
// Handover time consuming work to another task. Completion event should be set to "Callback" in pipeline task.
Task.Run(() => MyApp.ExecuteAsync(
taskClient,
projectId,
planUrl,
hubName,
planId,
jobId,
timelineId,
taskInstanceId,
taskInstanceName,
authToken));
}
}
In the Application Insights, I see the calls are actually made and the status code returned is 204
internal static async void ExecuteAsync(
TaskHttpClient taskClient,
string projectId,
string planUri,
string hubName,
string planId,
string jobId,
string timelineId,
string taskInstanceId,
string taskInstanceName,
string authToken)
{
using var httpClient = new HttpClient();
try
{
logger.LogInfo("Azure deploy callback started");
await taskClient.RaisePlanEventAsync(
Guid.Parse(projectId),
hubName,
Guid.Parse(planId),
new TaskStartedEvent(
Guid.Parse(jobId),
Guid.Parse(taskInstanceId)));
await taskClient.AppendTimelineRecordFeedAsync(
Guid.Parse(projectId),
hubName,
Guid.Parse(planId),
Guid.Parse(timelineId),
Guid.Parse(jobId),
Guid.Parse(taskInstanceId),
new[] { "Task Started" });
// Do work
for (int i = 0; i < 10; i++)
{
var logMessage = $"{DateTime.UtcNow:O} Message {i}";
await taskClient.AppendTimelineRecordFeedAsync(
Guid.Parse(projectId),
hubName,
Guid.Parse(planId),
Guid.Parse(timelineId),
Guid.Parse(jobId),
Guid.Parse(taskInstanceId),
new[] { logMessage });
Thread.Sleep(1000);
}
logger.LogInfo("Azure deploy callback: long sleep started");
Thread.Sleep(1000 * 60 * 60 * 4);
logger.LogInfo("Azure deploy callback: long sleep finished");
// Work completed now send task completed event state to mark task completed with succeeded/failed status
await taskClient.RaisePlanEventAsync(
Guid.Parse(projectId),
hubName,
Guid.Parse(planId),
new TaskCompletedEvent(
Guid.Parse(jobId),
Guid.Parse(taskInstanceId),
TaskResult.Succeeded));
}
catch (Exception exception)
{
logger.LogError(exception);
// send task started message feed and log the message. You will see feed messages in task log UI.
await taskClient.AppendTimelineRecordFeedAsync(
Guid.Parse(projectId),
hubName,
Guid.Parse(planId),
Guid.Parse(timelineId),
Guid.Parse(jobId),
Guid.Parse(taskInstanceId),
new[] { exception.ToString() });
// Work completed now send task completed event with status 'failed' to mark task failed
await taskClient.RaisePlanEventAsync(
Guid.Parse(projectId),
hubName,
Guid.Parse(planId),
new TaskCompletedEvent(
Guid.Parse(jobId),
Guid.Parse(taskInstanceId),
TaskResult.Failed));
}
}
Any ideas why TaskStartedEvent might not work and the task stays in the pending state or why log entries are not uploaded/appended are very welcome
question from:
https://stackoverflow.com/questions/65927832/asynchronous-callback-not-working-in-vsts-azure-devops