Who approved the deployment in VSTS? - deployment

I am using VSTS to deploy to remote machines. Before deployment, VSTS asks for PreDeployment approval.
Is there any variable or any way to get the name of the approver?
I can get it from history but then it is too late.
I know how to get the name of the person who triggered the deployment
$(Release.Deployment.RequestedFor)
Microsoft doesn't seem to mention anything

It seems you want to get the pre-deployment approval during the deployment.
And the pre-defined variables $(Release.Deployment.RequestedFor) is not used for your situation since it’s the variable shows the display name who create the release (not the user who approve the release before deployment).
To get the pre-deployment approval, you can use the REST API Get release:
GET https://{account}.vsrm.visualstudio.com/{project}/_apis/release/releases/{releaseId}?api-version=4.1-preview.2
For the release id, you can use the predefined variable $( Release.ReleaseId). And you can get the per-deployment approval from the response as below:
"preApprovalsSnapshot": {
"approvals": [
{
"rank": 1,
"isAutomated": false,
"isNotificationOn": false,
"approver": {
"displayName": "marina liu",
"url": "https://app.vssps.visualstudio.com/A2336cdc9-ffd7-41bb-a6cf-19002c9a9d5f/_apis/Identities/18cb43b4-0b0d-43ad-94dc-c8e2b56704c0",
"_links": {
"avatar": {
"href": "https://marinaliu.visualstudio.com/_apis/GraphProfile/MemberAvatars/msa.YjE2YzFlOWUtNWJkYy03NzU1LWJjNWEtNDU4M2Q5ZThlMjk0"
}
},
"id": "18cb43b4-0b0d-43ad-94dc-c8e2b56704c0",
"uniqueName": "****#****.com",
"imageUrl": "https://marinaliu.visualstudio.com/_api/_common/identityImage?id=18cb43b4-0b0d-43ad-94dc-c8e2b56704c0",
"descriptor": "msa.YjE2YzFlOWUtNWJkYy03NzU1LWJjNWEtNDU4M2Q5ZThlMjk0"
},
"id": 0
}
],
"approvalOptions": {
"requiredApproverCount": null,
"releaseCreatorCanBeApprover": true,
"autoTriggeredAndPreviousEnvironmentApprovedCanBeSkipped": false,
"enforceIdentityRevalidation": false,
"timeoutInMinutes": 0,
"executionOrder": "beforeGates"
}
}

Related

Azure DevOps KeyVault Linked Variable group "Value cannot be null. Parameter name: variableGroupParameters" - how do i fix this?

I have a need to automate the creation of KeyVault linked variable groups in ADO as part of a pipeline task. I can actually create the var groups after a bit of experimenting. However, using the az devops invoke method one is unable to specify the Azure Subscription and this has to be done manually, after the event - however when I do this in the web interface and attempt to save I get the error:
Value cannot be null. Parameter name: variableGroupParameters
This means any subsequent editing of the created KeyVault linked var group is pointless as it is unable to save it.
The JSON I am submitting is as follows:
{
"authorized": true,
"description": "$description",
"name": "$name",
"type": "AzureKeyVault",
"variableGroupProjectReferences": [{
"projectReference": {
"id": "$adoProjectID",
"name": "$ProjectName"
},
"name": "$name",
"description": "$description"
}],
"providerData": {
"serviceEndpointId": "$AdoSvcConnId",
"vault": "$KeyVaultNM"
},
"variables": {
"SOMETHINGSECRET": {
"isSecret": true,
"value": null,
"enabled": true,
"contentType": ""
},
"variables": {
"ANOTHERSECRET": {
"isSecret": true,
"value": null,
"enabled": true,
"contentType": ""
}
}
}
}
Where the $tokenized values are replaced during the powershell/az cli task
The command (which works but results in broken var group that can't be edited or saved) is as follows:
az devops invoke --http-method post --area distributedtask --resource variablegroups --in-file "vgroup_azure_rm.json" --encoding utf-8 --route-parameters project=$ProjectName --api-version 5.0-preview
Anyone have an insight in how to fix this please?
I was experiencing the same problem, and the message had nothing to do with the real issue.
I had the following variables:
"variables": {
"SECRET_1": {
"contentType": "",
"isSecret": true,
"value": "",
"expires": null,
"enabled": true
},
"SECRET_2": {
"contentType": "",
"isSecret": true,
"value": "",
"expires": null,
"enabled": true
},
"SECRET_3": {
"contentType": "",
"isSecret": true,
"value": "",
"expires": null,
"enabled": true
}
}
And was receiving the same error as you. I removed the expires property and the issue was solved! So my thinking is that the validation checks for any null value and returns the error you are receiving.
Try changing the property value to an empty string ("") instead of null and see whether that solves the problem.

Azure DevOps server import pipeline functionality ignores Approvers definition

I have the following definition in my pipeline that I am running on Azure DevOps Server Version Dev17.M153.3
After saving the change I can see the following content has been added to pipeline definition
"approvals": [
{
"rank": 1,
"isAutomated": false,
"isNotificationOn": false,
"approver": {
"displayName": "Aouslender, Alexey",
"url": "http://tdc1tfsapp01:8080/tfs/DefaultCollection/_apis/Identities/2d86d86b-fe02-4e22-aa53-4315cdb3821c",
"_links": {
"avatar": {
"href": "http://tdc1tfsapp01:8080/tfs/DefaultCollection/_apis/GraphProfile/MemberAvatars/win.Uy0xLTUtMjEtMzMwNDk4NzQ2Ni0xODkxMDA3NDIzLTI5MjUxNTc3OTctNDU4NDA1"
}
},
"id": "2d86d86b-fe02-4e22-aa53-4315cdb3821c",
"uniqueName": "DOMAIN\\PXXXXXX",
"imageUrl": "http://tdc1tfsapp01:8080/tfs/DefaultCollection/_apis/GraphProfile/MemberAvatars/win.Uy0xLTUtMjEtMzMwNDk4NzQ2Ni0xODkxMDA3NDIzLTI5MjUxNTc3OTctNDU4NDA1",
"descriptor": "win.Uy0xLTUtMjEtMzMwNDk4NzQ2Ni0xODkxMDA3NDIzLTI5MjUxNTc3OTctNDU4NDA1"
},
"id": 3546
}
]
Now I am exporting pipeline, using export option. Then I am deleting pipeline and importing it using exported json file.
The imported pipeline missing the Approvers definition, nevertheless I can see the definition in exported json.
"preDeployApprovals": {
"approvals": [
{
"rank": 1,
"isAutomated": false,
"isNotificationOn": false,
"approver": {
"displayName": "Aouslender, Alexey",
"url": "http://tdc1tfsapp01:8080/tfs/DefaultCollection/_apis/Identities/2d86d86b-fe02-4e22-aa53-4315cdb3821c",
"_links": {
"avatar": {
"href": "http://tdc1tfsapp01:8080/tfs/DefaultCollection/_apis/GraphProfile/MemberAvatars/win.Uy0xLTUtMjEtMzMwNDk4NzQ2Ni0xODkxMDA3NDIzLTI5MjUxNTc3OTctNDU4NDA1"
}
},
"id": "2d86d86b-fe02-4e22-aa53-4315cdb3821c",
"uniqueName": "DOMAIN\\PXXXXXX",
"imageUrl": "http://tdc1tfsapp01:8080/tfs/DefaultCollection/_apis/GraphProfile/MemberAvatars/win.Uy0xLTUtMjEtMzMwNDk4NzQ2Ni0xODkxMDA3NDIzLTI5MjUxNTc3OTctNDU4NDA1",
"descriptor": "win.Uy0xLTUtMjEtMzMwNDk4NzQ2Ni0xODkxMDA3NDIzLTI5MjUxNTc3OTctNDU4NDA1"
},
"id": 3535
}
],
"approvalOptions": {
"requiredApproverCount": null,
"releaseCreatorCanBeApprover": true,
"autoTriggeredAndPreviousEnvironmentApprovedCanBeSkipped": false,
"enforceIdentityRevalidation": false,
"timeoutInMinutes": 0,
"executionOrder": 1
}
}
Am I missing something here or is it actually a Microsoft bug?
It's by design. Following properties in the release definition are not imported: Agent Queues, Deployment Groups, Deployment Group Tags, Approvals, Variable Groups and values of secret variables.
Generally if in the same team project you can Clone the release definition directly.

Azure DevOps Pipeline - Release API - Update Release Definition add and remove a templated stage

We have a Azure DevOps Pipeline Release Definition, and i am looking at putting in place some automation for a new 'Stage' to be created from a template when a pull request is triggered on branch x, and the stage to be removed when the branch is deleted. i will be using github actions for this.
The API doc's are not super easy to follow.
My question are:
is this possible, dose the API support making such adding and removing of stage's to a _releaseDefinition ?
if so is there any examples on how to do this ?
Doc's
https://learn.microsoft.com/en-us/rest/api/azure/devops/release/releases/update%20release?view=azure-devops-rest-5.1#releasedefinitionshallowreference
The api you should use is Update-definition api:
PUT https://vsrm.dev.azure.com/{org name}/{project name}/_apis/release/definitions?api-version=5.1
For the request body of adding stage/removing stage, it in fact only made changes into environments parameter:
One stage definition corresponds to one grey code block.
Adding stage: Add a template JSON code block of stage definition(the grey one display in my left screenshots). This code structure is fixed.
Removing stage: Remove the complete corresponding stage definition.
Here is the one complete stage definition sample:
{
"id": -1,
"name": "Stage 3",
"rank": 3,
"variables": {},
"variableGroups": [],
"preDeployApprovals": {
"approvals": [
{
"rank": 1,
"isAutomated": true,
"isNotificationOn": false,
"id": 7
}
],
"approvalOptions": {
"requiredApproverCount": null,
"releaseCreatorCanBeApprover": false,
"autoTriggeredAndPreviousEnvironmentApprovedCanBeSkipped": false,
"enforceIdentityRevalidation": false,
"timeoutInMinutes": 0,
"executionOrder": "beforeGates"
}
},
"deployStep": {
"id": 8
},
"postDeployApprovals": {
"approvals": [
{
"rank": 1,
"isAutomated": true,
"isNotificationOn": false,
"id": 9
}
],
"approvalOptions": {
"requiredApproverCount": null,
"releaseCreatorCanBeApprover": false,
"autoTriggeredAndPreviousEnvironmentApprovedCanBeSkipped": false,
"enforceIdentityRevalidation": false,
"timeoutInMinutes": 0,
"executionOrder": "afterSuccessfulGates"
}
},
"deployPhases": [
{
"deploymentInput": {
"parallelExecution": {
"parallelExecutionType": "none"
},
"agentSpecification": {
"identifier": "vs2017-win2016"
},
"skipArtifactsDownload": false,
"artifactsDownloadInput": {
"downloadInputs": []
},
"queueId": 247,
"demands": [],
"enableAccessToken": false,
"timeoutInMinutes": 0,
"jobCancelTimeoutInMinutes": 1,
"condition": "succeeded()",
"overrideInputs": {}
},
"rank": 1,
"phaseType": "agentBasedDeployment",
"name": "Agent job",
"refName": null,
"workflowTasks": []
}
],
"environmentOptions": {
"emailNotificationType": "OnlyOnFailure",
"emailRecipients": "release.environment.owner;release.creator",
"skipArtifactsDownload": false,
"timeoutInMinutes": 0,
"enableAccessToken": false,
"publishDeploymentStatus": true,
"badgeEnabled": false,
"autoLinkWorkItems": false,
"pullRequestDeploymentEnabled": false
},
"demands": [],
"conditions": [],
"executionPolicy": {
"concurrencyCount": 1,
"queueDepthCount": 0
},
"schedules": [],
"owner": {
"displayName": "{user name}",
"id": "{user id}",
"isContainer": false,
"uniqueName": "{creator account}",
"url": "https://dev.azure.com/{org name}/"
},
"retentionPolicy": {
"daysToKeep": 30,
"releasesToKeep": 3,
"retainBuild": true
},
"processParameters": {},
"properties": {
"BoardsEnvironmentType": {
"$type": "System.String",
"$value": "unmapped"
},
"LinkBoardsWorkItems": {
"$type": "System.String",
"$value": "False"
}
},
"preDeploymentGates": {
"id": 0,
"gatesOptions": null,
"gates": []
},
"postDeploymentGates": {
"id": 0,
"gatesOptions": null,
"gates": []
},
"environmentTriggers": [],
"badgeUrl": "https://vsrm.dev.azure.com/{org}/_apis/{project name}/Release/badge/3c3xxx6414512/2/3"
},
Here has some key parameters you need pay attention: id, owner, rank and conditions.
id: This is the stage id you specified to stage, its value must less than 1. Any value that less than 1 is okay here.
owner: This is required. Or you will receive the message that notify you the stage must has owner.
rank: The natural numbers greater than 1. Here I suggest you increment it based on other stages.
conditions: This is the one which you can configure which stage the current new one will depend on. The nutshell is it used to specify stage execution location of release.
When you updating release, you must pack and set the whole release definition as request body. Get the original one, add new customized stage definition part into it. Then update to api.
In fact, I suggest you do adding a stage with UI for test. Then go History tab of release definition page. Then choose Compare difference of three dots.
We provided you the difference of definition in the panel(left panel is the original, the right is updated), and you can clearly get what you should focus on to apply your idea.

API POST not applied to branch with Azure DevOps Server (2019 Update 1)

I'm puzzled with the Azure DevOps API POST. I've successfully created a policy for "Minimum number of reviewers" but it's not being created against the branch I'm specifying. I've done this in Fiddler for the moment, here's my request (private values obfuscated):
POST http://our-tfs-server:8080/tfs/TheCollection/TheProject/_apis/policy/configurations?api-version=5.1 HTTP/1.1
Content-Type: application/json; charset=utf-8
Host: our-tfs-server:8080
Authorization: Basic MyBase64EncodedToken
{
"IsBlocking": true,
"IsEnabled": true,
"Settings": {
"MinimumApproverCount": 2,
"Scope": [
{
"RefName": "refs/heads/master",
"MatchKind": "exact",
"RepositoryId": "7718333c-044e-423a-baa1-45e6a1f0ff41"
}
]
},
"Type": {
"Id": "fa4e907d-c16b-4a4c-9dfa-4906e5d171dd"
}
}
and here's the response body:
{
"createdBy": {
"displayName": "Surname, Firstname",
"url": "http://our-tfs-server:8080/tfs/TheCollection/_apis/Identities/SomeString",
"_links": { "avatar": { "href": "http://our-tfs-server:8080/tfs/TheCollection/_apis/GraphProfile/MemberAvatars/win.SomeString" } },
"id": "7b40f8ab-a933-4b43-bdf8-bf0b179d28e6",
"uniqueName": "MyUsername",
"imageUrl": "http://our-tfs-server:8080/tfs/TheCollection/_api/_common/identityImage?id=SomeString",
"descriptor": "win.SomeOtherString"
},
"createdDate": "2020-01-23T02:09:34.4738854",
"isEnabled": true,
"isBlocking": true,
"isDeleted": false,
"settings": {
"minimumApproverCount": 2,
"creatorVoteCounts": false,
"allowDownvotes": false,
"resetOnSourcePush": false,
"scope": [ { "repositoryId": "7718333c-044e-423a-baa1-45e6a1f0ff41" } ]
},
"_links": {
"self": { "href": "http://our-tfs-server:8080/tfs/TheCollection/8b7e65ed-1136-4b0f-9780-de2a3860447a/_apis/policy/configurations/254" },
"policyType": { "href": "http://our-tfs-server:8080/tfs/TheCollection/8b7e65ed-1136-4b0f-9780-de2a3860447a/_apis/policy/types/fa4e907d-c16b-4a4c-9dfa-4906e5d171dd" }
},
"revision": 1,
"id": 254,
"url": "http://our-tfs-server:8080/tfs/TheCollection/8b7e65ed-1136-4b0f-9780-de2a3860447a/_apis/policy/configurations/254",
"type": {
"id": "fa4e907d-c16b-4a4c-9dfa-4906e5d171dd",
"url": "http://our-tfs-server:8080/tfs/TheCollection/8b7e65ed-1136-4b0f-9780-de2a3860447a/_apis/policy/types/fa4e907d-c16b-4a4c-9dfa-4906e5d171dd",
"displayName": "Minimum number of reviewers"
}
}
Note that "scope": [ { "repositoryId": "7718333c-044e-423a-baa1-45e6a1f0ff41" } ] only has the repositoryId.
In the UI on the policies for the branch the Minimum Number of reviewers option is not ticked and there's no version of the question at a full Repository level. If I call /_apis/policy/configurations then I see the new policy so it has been created. Perhaps this will now guard all branches with the policy, but we don't want it at a global level and given there's no tooling in the DevOps web ui for it I'm pretty sure it's not intended to be like that anyway.
So, is this an oversight in the way the API functions or is the branch to apply the policy configuration to set using another technique?
So...the answer lay in the capitalisation of property names on the json request body. Whilst json is not case sensitive and the request I was making was returning 200 and a valid body internally, the server was falling apart on the setting of the branch to apply the Policy Configuration to. NewtonSoft was serialising property names with capital letters at the beginning and I found that using lowercase fixed the original issue and the returned object which was created then had the refName and matchKind assigned and the MinimumNumberOfReviewers check box was ticked and the number set to 2. Why MS have failed to serialise only one or 2 properties is a little weird, at any rate I applied JsonSerializationSettings globally to avoid the need for adding JsonPropertyAttribute everywhere as well as ignoring null properties.

TFS/VSTS vNext Build and Release Logs Location

Are the build and release logs saved locally on the Build Agent machine? I know that I can manually click on the "Download all logs as zip" link for each build and release, but if I want to automatically send these logs to someone else (or bulk send them), is there another way to find them (either on the Build Agent machine or in the database somewhere)?
Thanks!
Both for TFS and VSTS, the build/release logs are located in TFS/VSTS server (no business with what the agent is used).
In build/release retention, you can set the policies to keep the builds/releases. And it default keep the latest 30 days' builds and releases.
Except the way to click "Download all logs as zip" button to get a build/release logs, you can also get build/release logs by REST API. Such as below example:
GET https://account.visualstudio.com/DefaultCollection/Git2/_apis/build/builds/2373/timeline?api-version=2.0
And you can get each build step log in the response, such as:
{
"records": [
{
"id": "d2c6b274-40fe-4727-85b6-eb92fb4f6009",
"parentId": "ff7265dc-abe3-5e6a-6194-76bb88f00044",
"type": "Task",
"name": "Initialize Job",
"startTime": "2018-01-15T05:30:25.6Z",
"finishTime": "2018-01-15T05:30:26.0233333Z",
"currentOperation": null,
"percentComplete": null,
"state": "completed",
"result": "succeeded",
"resultCode": null,
"changeId": 8,
"lastModified": "0001-01-01T00:00:00",
"workerName": "V-myPC",
"order": 2,
"details": null,
"errorCount": 0,
"warningCount": 0,
"url": null,
"log": {
"id": 2,
"type": "Container",
"url": "https://account.visualstudio.com/DefaultCollection/f7855e29-6f8d-429d-8c9b-41fd4d7e70a4/_apis/build/builds/2373/logs/2"
},
"task": null
},
...
],
"lastChangedBy": "00000002-0000-8888-8000-000000000000",
"lastChangedOn": "2018-01-15T05:30:40.947Z",
"id": "4b4280d4-5358-4238-ab95-d44475c92bc9",
"changeId": 19,
"url": "https://account.visualstudio.com/DefaultCollection/f7855e29-6f8d-429d-8c9b-41fd4d7e70a4/_apis/build/builds/2373/Timeline/4b4280d4-5358-4238-ab95-d44475c92bc9"
}
As the above response, you can find the Initialized Job step by the url https://account.visualstudio.com/DefaultCollection/f7855e29-6f8d-429d-8c9b-41fd4d7e70a4/_apis/build/builds/2373/logs/2.