Unable to update results of a shared test step via Azure Devops REST-api in Postman - azure-devops

I am trying to update the result of a test case via Azure DevOps REST-Api in Postman.
My test case is very simple and consists only of one shared step that has two simple steps inside.
I want to mark these steps of my shared step as "Passed".
Currently I am doing the following steps:
create a new test Run via POST request to {{baseUrlTestApi}}/runs?api-version=7.0
In request's body I pass the test run name, shallow reference to build and owner. Run is successfully created, I can see it on the portal.
create a result of a test case via POST request to {{baseUrlTestApi}}/Runs/{{runId}}/results?api-version=7.0
In request body I pass shallow references to the project, test plan, test suite, test point and test case, outcome ("Passed"), state ("Completed"), testCaseTitle and revision. On the portal I can see that the result is created with the correct outcome and state and is linked to the right test suite and test case.
update the result with actionResults via PATCH request to {{baseUrlTestApi}}/Runs/{{runId}}/results?api-version=7.0
In request body I pass the test result's ID and iteration details, that contains iteration id and an array of action results, where I specify shared step's ID and revision and outcome for each shared step's step. This is the request's body:
[
{
"id": 100000,
"iterationDetails": [
{
"id": 1,
"outcome": "Passed",
"startedDate": "2022-02-16T21:14:14.337Z",
"completedDate": "2022-02-16T21:14:17.057Z",
"durationInMs": 27180000.0,
"actionResults": [
{
"actionPath": "0000000200000001",
"sharedStepModel": {
"id": 18338,
"revision": 2
},
"iterationId": 1,
"stepIdentifier": "1;1",
"outcome": "Passed",
"startedDate": "2022-02-16T21:14:14Z",
"completedDate": "2022-02-16T21:14:14Z",
"url": "{{baseUrlTestApi}}/Runs/{{runId}}/Results/100000/Iterations/1/ActionResults?actionPath=0000000200000001"
},
{
"actionPath": "0000000200000002",
"sharedStepModel": {
"id": 18338,
"revision": 2
},
"iterationId": 1,
"stepIdentifier": "1;2",
"outcome": "Passed",
"startedDate": "2022-02-16T21:14:14Z",
"completedDate": "2022-02-16T21:14:14Z",
"url": "{{baseUrlTestApi}}/Runs/{{runId}}/Results/100000/Iterations/1/ActionResults?actionPath=0000000200000002"
}
],
"parameters": [],
"attachments": [],
"url": "{{baseUrlTestApi}}/Runs/{{runId}}/Results/100000/Iterations/1"
}
]
}
]
Then I go to the portal to see the results. I am expecting to see all three steps of my shared step marked as Passed in the Details section. However, when I go to Runs --> select my run --> test results --> select my result I see this error:
workItemRevision error
I found that what is causing this error is that in the payload of POST request to https://{{organization}}.visualstudio.com/_apis/Contribution/dataProviders/query sent by the portal shared step's work item has an empty string in workItemRevisions.
empty string in workItemRevisions
However, I have explicitly specified the revision ID in step 3 (in sharedStepModel object in each element of actionResults array). If I send a request to this endpoint myself via Postman with the same payload but with "1" instead of empty string, the request is successful.
Before this request, portal sends another one to the same endpoint for the Test Case's workitem and that request is successful, workItemRevisions field is populated correctly, so it is empty string only for the shared step's workitem.
This is the case only if the shared step is involved. If a test case consists of only regular steps, then I am able to mark them as "Passed" with the same flow I described above.
Any ideas what can be causing this? Is this even the right approach to mark the shared step's outcome? Thanks in advance.

After checking the REST API:
You could get a request body (use the Iterations detailsToInclude parameter) and modify the request body. and then to update the result to check if it works.
12.14 Update:
If you manually run the test with shared steps, we can get the actionresults like:
"actionResults": [
{
"actionPath": "00000002",
"iterationId": 1,
"sharedStepModel": {
"id": 142,
"revision": 1
},
"stepIdentifier": "2",
"outcome": "Failed",
"startedDate": "2022-12-14T07:43:03Z",
"completedDate": "2022-12-14T07:43:03Z"
},
{
"actionPath": "0000000200000001",
"iterationId": 1,
"stepIdentifier": "2;1",
"outcome": "Failed",
"startedDate": "2022-12-14T07:43:03Z",
"completedDate": "2022-12-14T07:43:03Z"
}
],
"parameters": [],
"attachments": [],
"url": "https://dev.azure.com/{org}/{project}/_apis/test/Runs/{runId}/Results/100000/Iterations/1"
}
]
And then I change the outcome from "Failed" to "Passed" and then Patch the result to:
https://dev.azure.com/{org}/{project}/_apis/test/Runs/{runId}/results?api-version=7.0
And then I can view the result in the run -> Test results -> The run.
So, I think your problem maybe related to the format of the actionresults, you can try to run a manually test to get the actionresults and then PATCH it to check if it works.

Related

In TeamCity, trigger build with 2 VCS roots with 2 custom revisions using REST API

looking for collective wisdom on this problem I am tackling.
I need to trigger build using REST API on TeamCity. The build configuration has 2 VCS roots and I need to pass specific revision for both of them. In documentation, I found example for single VCS, but I am stuck on setting revisions for both of them.
I am trying to set up something like this:
{
"buildType": {
"id": "ExampleConfiguration"
},
"defaultBranch": "false",
"lastChanges": {
"change": [
{
"locator": "combination of locators that will set VCS 1 - branch + revision"
},
{
"locator": "combination of locators that will set VCS 2 - branch + revision"
}
]
}
}
In principle, I am simulating execution of the build, where both revisions are manually set - this is possible in the UI.
https://www.jetbrains.com/help/teamcity/rest/start-and-cancel-builds.html#Advanced+Build+Run
TC version: 2022.04.3 (build 108706)
Edit:
I was able to detect the changes and resolve their id on both VCS roots. For the changes field in the body I can now use locator of the form {"id": 123456}. But another obstacle on the road, if I specify pair of these changes:
"lastChanges": { "change": [ {"id": 1}, {"id": 2} ] }
I get error
Responding with error, status code: 400 (Bad Request).
Details: jetbrains.buildServer.server.rest.errors.BadRequestException: Several non-personal changes are submitted, only one can be present
Invalid request. Please check the request URL and data are correct.
Same build with the exact revisions is possible to trigger manually from TC UI.
Finally resolved it. The way to go is to use revisions instead of lastChanges. To pass revisions for 2 VCS roots together with branch names, use this:
"revisions": {
"revision": [
{
"vcs-root-instance": {
"id": "111"
},
"vcsBranchName": "branch-name-111",
"version": "rev_on_vcs_111"
},
{
"vcs-root-instance": {
"id": "222"
},
"vcsBranchName": "branch-name-222",
"version": "rev_on_vcs_222"
}
]
}
To resolve VCS root instance id, use API call /app/rest/vcs-root-instances/vcsRoot:(id:(Project_Vcs_Root))"

how to get a particular field from web activity output in azure data factory

I am trying to create a pipeline where I want to store a particular value from a web activity in azure data factory, in a variable, so that I can pass it to other activities.
I want to get the export ID but I keep running into errors.
The response of the web activity looks like this:
{
"requestId": "----",
"result": [
{
"exportId": "---",
"format": "CSV",
"status": "Created",
"createdAt": "2020-12-15T16:03:01Z"
}
],
"success": true
}
I have tried the following methods but it fails: #string(activity('Web1').output.result.exportId
#string(activity('Web1').output.result[0].exportId
#string(activity('Web1').output.result.[0]
first(#string(activity('Web1').output.result)
enter image description here
enter image description here
I have tried this. Your second expression should work #string(activity('Web1').output.result[0].exportId)
My test
Output of Web activity
These expressions also work fine on my side, you can have a try:
#string(activity('Web1').output['result'][0]['exportId'])
#string(activity('Web1').output.result[0].exportId)
#string(first(activity('Web1').output['result']).exportId)
#string(json(activity('Web1').output.response)[0]['Id'])

Linking multiple existing work items to queued build (from Azure Devops SDK)

In Azure Devops REST API, I want to link a task\bug\story (that already exists) when triggering a build. How do I do that?
checkInTicket might be a solution, but it is not documented.
Payload based on Merlin's response worked:
var payload = new object[] {
new {
op = "add",
path = "/relations/-",
value =
new {
rel = "ArtifactLink",
url = $"vstfs:///Build/Build/{buildId}",
attributes = new
{
name = "Build"
}
}
}
};
1. Approach 1
Same with the UI operation, to link the exists work item to build, just need to update one option in build definition:
This is the api:
https://dev.azure.com/{org name}/{project name}/_apis/build/definitions/{definition id}?api-version=5.0-preview.6
In its request body, please focus on below script part:
"options": [
{
"enabled": true,
"inputs": {
"branchFilters": "[\"+refs/heads/*\"]",
"additionalFields": "{}"
},
"definition": {
"id": "5d58cc01-7c75-450c-be18-a388ddb129ec"
}
}
]
The enabled represent whether it will create links to work items which linked to associated changes after the build completed. To achieve what you want, here, please set the enabled value as true. The id value is fixed and represent this option, so here do not worry about this id value.
When you updating the build definition by this method, do not forget increment the revision in request body. revision increment means update the definition as a new revision. or the update action would not actually succeed.
But, what you should concerned is this update should finished before the build triggered. Thus it will create link to the exists WIT automatically after the build finished.
Also, this would only add this build link to work item which associate with the changes.
2. Approach 2
If the above is not what you want, and you just want to link work item to build while the build is triggered. Afraid to say, there's no such direct API could finish that.
You may need to use 2 APIs: one of it is queue build, and another API is add this build link to work item.
The request body sample of add build link to work item:
[
{
"op": "test",
"path": "/rev",
"value": "2"
},
{
"op": "add",
"path": "/relations/-",
"value":
{
"rel": "ArtifactLink",
"url": "vstfs:///Build/Build/{the build id that you just queued}"
}
}
]
This method need you get the generated BuildId after you queue the build, and then pass it to the workitem API. Different with the approach 1, in this method, you can customize the work item id which you want to add the build link to.

MS Graph REST API checkout user

I've managed to successfully checkout a file using the https://graph.microsoft.com/beta/drives/{driveId}/items/{itemId}/checkout
Now, I'd like to get the information about the user, who actually perform the checkout operation.
It's possible to check if the item is locked:
https://graph.microsoft.com/beta/drives/{driveId}/items/{itemId}?select=*,publication
However, according to DOCs, publication doesn't provide information about the checked user. Without information who locked the file is the whole checkin/checkout logic is useless.
This kind of information could be retrieved via the metadata for an item in a list as demonstrated below:
https://graph.microsoft.com/beta/sites/{site-id}/lists/{list-id}/items/{item-id}?expand=fields(select=CheckoutUserLookupId)
Once you get checkout user id (CheckoutUserLookupId field) , user details could be determined via the following endpoint:
https://graph.microsoft.com/v1.0/sites/{site-id}/lists('User Information List')/items/{CheckoutUserLookupId}
where CheckoutUserLookupId is the user id from the previous request
https://graph.microsoft.com/beta/sites/{site-id}/lists/{list-id}/items/{item-id} can't work with folders.
Anyway, drive endpoint "Allows access to the list as a drive" (according to MS Graph Docs). It works with folders as expected.
So I have
get the drive-id: /sites/${siteId}/drives
list root folder: /drives/{drive-id}/items/root/children?select=name,publication
if an item is locked, it's possible to list the activity on the item:
/drives/${idObj.driveId}/items/${idObj.fileId}?select=id&expand=activities
return list of actions:
"activities": [
{
"#odata.type": "#oneDrive.activityEntity",
"#odata.id": "https://xxxxxxxxxx/v2.0/oneDrive.activityEntity2a3649d6-2xxxxx",
"#odata.editLink": "oneDrive.activityEntity2a3649d6xxxxxx",
"#sharePoint.localizedRelativeTime": "0|July 30",
"action": {
"checkout": {}
},
"actor": {
"user": {
"email": "XXX#XXX",
"displayName": "vladimir",
"self": {},
"userPrincipalName": "XXX#XXX
}
},
"id": "XXXXXXXXXXXXXX",
"times": {
"recordedTime": "2018-07-31T04:59:03Z"
}
},
although no user ID at least a have the email....

Use output from Web Activity call as variable

I'm using ADFv2 to transfer some data. As a part of this operation I need some configuration values to pass into the pipeline.
The config values must be pulled at runtime from a REST service - not as parameters.
I can successfully query the REST service with Web Activity and I can see the output in the debug view.
Now the problem :)
How do I use this output in other activities further in the pipeline?
My Web Activity configuration is like this:
{
"name": "Web1",
"type": "WebActivity",
"policy": {
"timeout": "7.00:00:00",
"retry": 0,
"retryIntervalInSeconds": 30,
"secureOutput": false
},
"typeProperties": {
"url": "https://myazurefunction.azurewebsites.net/api/MyFunction",
"method": "GET",
"headers": {
"Content-Type": "application/json"
}
}
I have tried to access the output after is has executed, but it seems empty:
#activity('Web1').Output
#activity('Web1').output
#string(activity('Web1').Output)
they are all empty. Any suggestions?
Thanks!
I set up an ADF2 and try to get a response.
This works for me:
#string(activity('Post').output)
Have you checked the output in the debugging?
Here is my output:
{
"test": {
"value": 123,
"text": abc
},
"concat": 123abc
}
I use the stored procedure to insert the values into the destination table on a Logical Server.
In ADFv2, you access the output of previous activities using #activity('ActivityName').output.
For the web activity defined, the response from your function should be in JSON format, so you would reference specific JSON values using their attribute names in the response. For example, your defined web activity, named Web1, calls a function that returns a response of:
{
"foo": "bar",
"some": "value"
}
To use the value of foo in a subsequent ADF activity, you would reference #activity('Web1').output.foo. ADFv2 provides multiple type conversion functions, should you need the returned value converted to another type.
If your function is returning an empty JSON response back, you may want to inspect the response from your function using Postman or another tool to ensure you are returning a properly formatted response, and that your function isn't failing for another reason.
Inside your Azure function code, you should be returning a JSON object, along with a success code, similar to return req.CreateResponse(HttpStatusCode.OK, json);.
Also note that if you reference a property of the response and it does not exist, ADF will fail at that point, so you can use an If Condition activity to check for the required values to better handle failures in ADFv2.