How to set deployment group in release Pipeline by api - azure-devops

I try to create a release pipeline via Azure devops api. As phaseType I want to use machineGroupBasedDeployment (Deployment Group). But how can I set the Deployment group in the deployment phase? If I use the json below as request the deployment group is always empty. Has anybody an idea or an sample how I can set the deployment group?
"deployPhases": [
{
"deploymentInput": {
"healthPercent": 0,
"deploymentHealthOption": "Custom",
"tags": [],
"skipArtifactsDownload": false,
"artifactsDownloadInput": {
"downloadInputs": [
{
"alias": "_xxx ch",
"artifactType": "Build",
"artifactDownloadMode": "All",
"artifactItems": []
}
]
},
"queueId": 129,
"demands": [],
"enableAccessToken": false,
"timeoutInMinutes": 10,
"jobCancelTimeoutInMinutes": 1,
"condition": "succeeded()",
"overrideInputs": {}
},
"rank": 1,
"phaseType": 4,
"name": "IIS Deployment111",
"refName": null,
"workflowTasks": [
{
"environment": {},
"taskId": "1b2aec60-dc49-11e6-9b76-63056e018cac",
"version": "0.*",
"name": "IIS Web App Manage",
"refName": "",
"enabled": true,
"alwaysRun": false,
"continueOnError": false,
"timeoutInMinutes": 10,
"retryCountOnTaskFailure": 0,
"definitionType": null,
"overrideInputs": {},
"condition": "succeeded()",
"inputs": {
....

how can I set the Deployment group in the deployment phase?
In the RequestBody, you can define the Deployment Group Id in the queueId field and the phaseType is machineGroupBasedDeployment.
For example:
"deployPhases": [
{
"deploymentInput": {
"healthPercent": 0,
"deploymentHealthOption": "Custom",
"tags": [],
"skipArtifactsDownload": false,
"artifactsDownloadInput": {
"downloadInputs": []
},
"queueId": {DeploymentGroupID},
"demands": [],
"enableAccessToken": false,
"timeoutInMinutes": 0,
"jobCancelTimeoutInMinutes": 1,
"condition": "succeeded()",
"overrideInputs": {}
},
"rank": 1,
"phaseType": "machineGroupBasedDeployment",
"name": "Deployment1 group job",
"refName": null,
"workflowTasks": [
{
"environment": {},
"taskId": "e213ff0f-5d5c-4791-802d-52ea3e7be1f1",
"version": "2.*",
"name": "PowerShell Script",
"refName": "",
"enabled": true,
"alwaysRun": false,
"continueOnError": false,
"timeoutInMinutes": 0,
"retryCountOnTaskFailure": 0,
"definitionType": "task",
"overrideInputs": {},
"condition": "succeeded()",
"inputs": {
"targetType": "inline",
"filePath": "",
"arguments": "",
"script": "# Write your PowerShell commands here.\n\nWrite-Host \"Hello World\"\n",
"errorActionPreference": "stop",
"warningPreference": "default",
"informationPreference": "default",
"verbosePreference": "default",
"debugPreference": "default",
"failOnStderr": "false",
"showWarnings": "false",
"ignoreLASTEXITCODE": "false",
"pwsh": "false",
"workingDirectory": "",
"runScriptInSeparateScope": "false"
}
}
]
}
],
To get the Deployment Group ID, you can navigate to Pipelines -> Deployment Groups -> Target Deployment Group and check the mgid in the url.
On the other hand, you can also use this Rest API: Definitions - Get to get the definition of an existing release pipeline and check the response to get the required request body content

Related

azure pipelines create a build and release pipeline for a python script

At the moment got build and deployment of python script in the same pipeline. I want to separate this out and have the deployment in a release pipeline. how do I do this? do I use artifacts in build pipeline which is consumed in the release pipeline?
trigger:
none
pool:
vmImage: "windows-latest"
steps:
# Set the version of Python which the build agent should use
- task: UsePythonVersion#0
displayName: Use Python 3.8
inputs:
versionSpec: '3.8'
addToPath: true
# Run Pip installer for any prerequisite libraries
- bash: pip3 install -r requirements.txt
displayName: Install pip package requirements
workingDirectory: project-requirements
#run script using azure cli
- task: AzureCLI#2
inputs:
azureSubscription: 'sub'
scriptType: 'batch'
scriptLocation: 'inlineScript'
inlineScript: 'python etl.py'
workingDirectory: src/scripts
Write a sample for you:
Build Pipeline:
trigger:
- none
pool:
vmImage: windows-latest
variables:
- name: system.debug
value: true
steps:
- task: CmdLine#2
inputs:
script: |
python -m venv tutorial-env
call tutorial-env\Scripts\activate.bat
pip install -r requirements.txt
- task: PublishPipelineArtifact#1
inputs:
targetPath: '$(System.DefaultWorkingDirectory)'
artifact: 'drop'
publishLocation: 'pipeline'
Release Pipeline:
{
"source": 2,
"revision": 8,
"description": null,
"variables": {},
"variableGroups": [],
"environments": [
{
"id": 14,
"name": "Stage 2",
"rank": 1,
"owner": {
"displayName": "Bowman Zhu",
"url": "https://spsprodsea2.vssps.visualstudio.com/A64545e3d-c12d-4c81-b77f-4de83783d9bd/_apis/Identities/af91e22a-cc35-4c8e-8af3-f49c4a1b9b6a",
"_links": {
"avatar": {
"href": "https://dev.azure.com/BowmanCP/_apis/GraphProfile/MemberAvatars/aad.ZGU3N2NiY2YtZTgzYy03ZDkwLWI0YTYtOTk3Nzg3NDczMzBl"
}
},
"id": "af91e22a-cc35-4c8e-8af3-f49c4a1b9b6a",
"uniqueName": "xxx",
"imageUrl": "https://dev.azure.com/BowmanCP/_apis/GraphProfile/MemberAvatars/aad.ZGU3N2NiY2YtZTgzYy03ZDkwLWI0YTYtOTk3Nzg3NDczMzBl",
"descriptor": "aad.ZGU3N2NiY2YtZTgzYy03ZDkwLWI0YTYtOTk3Nzg3NDczMzBl"
},
"variables": {},
"variableGroups": [],
"preDeployApprovals": {
"approvals": [
{
"rank": 1,
"isAutomated": true,
"isNotificationOn": false,
"id": 40
}
],
"approvalOptions": {
"requiredApproverCount": null,
"releaseCreatorCanBeApprover": false,
"autoTriggeredAndPreviousEnvironmentApprovedCanBeSkipped": false,
"enforceIdentityRevalidation": false,
"timeoutInMinutes": 0,
"executionOrder": 1
}
},
"deployStep": {
"id": 41
},
"postDeployApprovals": {
"approvals": [
{
"rank": 1,
"isAutomated": true,
"isNotificationOn": false,
"id": 42
}
],
"approvalOptions": {
"requiredApproverCount": null,
"releaseCreatorCanBeApprover": false,
"autoTriggeredAndPreviousEnvironmentApprovedCanBeSkipped": false,
"enforceIdentityRevalidation": false,
"timeoutInMinutes": 0,
"executionOrder": 2
}
},
"deployPhases": [
{
"deploymentInput": {
"parallelExecution": {
"parallelExecutionType": 0
},
"agentSpecification": null,
"skipArtifactsDownload": false,
"artifactsDownloadInput": {
"downloadInputs": []
},
"queueId": 13,
"demands": [],
"enableAccessToken": false,
"timeoutInMinutes": 0,
"jobCancelTimeoutInMinutes": 1,
"condition": "succeeded()",
"overrideInputs": {}
},
"rank": 1,
"phaseType": 1,
"name": "Agent job",
"refName": null,
"workflowTasks": [
{
"environment": {},
"taskId": "61f2a582-95ae-4948-b34d-a1b3c4f6a737",
"version": "2.*",
"name": "Download Pipeline Artifact",
"refName": "",
"enabled": true,
"alwaysRun": false,
"continueOnError": false,
"timeoutInMinutes": 0,
"retryCountOnTaskFailure": 0,
"definitionType": "task",
"overrideInputs": {},
"condition": "succeeded()",
"inputs": {
"source": "specific",
"project": "c6358b04-e91a-4bd1-a894-1adb543134d6",
"pipeline": "347",
"preferTriggeringPipeline": "false",
"runVersion": "latest",
"runBranch": "refs/heads/master",
"runId": "",
"tags": "",
"allowPartiallySucceededBuilds": "false",
"allowFailedBuilds": "false",
"artifact": "",
"patterns": "**",
"path": "$(System.DefaultWorkingDirectory)"
}
},
{
"environment": {},
"taskId": "d9bafed4-0b18-4f58-968d-86655b4d2ce9",
"version": "2.*",
"name": "This step will show the packages that has been installed. You can also do other things here",
"refName": "",
"enabled": true,
"alwaysRun": false,
"continueOnError": false,
"timeoutInMinutes": 0,
"retryCountOnTaskFailure": 0,
"definitionType": "task",
"overrideInputs": {},
"condition": "succeeded()",
"inputs": {
"script": "echo You can do something here.\n\ndir\n\ncd drop/tutorial-env/Lib/site-packages\n\ndir\n\n\n",
"workingDirectory": "",
"failOnStderr": "false"
}
}
]
}
],
"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": [
{
"name": "ReleaseStarted",
"conditionType": 1,
"value": ""
}
],
"executionPolicy": {
"concurrencyCount": 1,
"queueDepthCount": 0
},
"schedules": [],
"currentRelease": {
"id": 60,
"url": "https://vsrm.dev.azure.com/BowmanCP/c6358b04-e91a-4bd1-a894-1adb543134d6/_apis/Release/releases/60",
"_links": {}
},
"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/BowmanCP/_apis/public/Release/badge/c6358b04-e91a-4bd1-a894-1adb543134d6/14/14"
}
],
"artifacts": [],
"triggers": [],
"releaseNameFormat": "Release-$(rev:r)",
"tags": [],
"properties": {
"DefinitionCreationSource": {
"$type": "System.String",
"$value": "ReleaseNew"
},
"IntegrateBoardsWorkItems": {
"$type": "System.String",
"$value": "False"
},
"IntegrateJiraWorkItems": {
"$type": "System.String",
"$value": "false"
}
},
"id": 14,
"name": "Python_Virtual_Env_Release",
"path": "\\",
"projectReference": null,
"url": "https://vsrm.dev.azure.com/BowmanCP/c6358b04-e91a-4bd1-a894-1adb543134d6/_apis/Release/definitions/14",
"_links": {
"self": {
"href": "https://vsrm.dev.azure.com/BowmanCP/c6358b04-e91a-4bd1-a894-1adb543134d6/_apis/Release/definitions/14"
},
"web": {
"href": "https://dev.azure.com/BowmanCP/c6358b04-e91a-4bd1-a894-1adb543134d6/_release?definitionId=14"
}
}
}
This release pipeline JSON definition is just a demo for you to refer, you need to create a release pipeline with your own configurations.
This is my reprository structure:
You can see that the dependencies are all been prepared on Release pipeline side:

deploy web apps /create Stages by api to run new deployments

It’ possible to create a deploment stage by Azure DevOps API? We want to create a new stage and want to deploy a web app on the webserver. What is the best approach to release a new web app including the configuration of iis by azure devops API?
Kind Regards,
Dominik
If you mean creating release definition with stages and specific tasks, then you can call the Definitions - Create REST API.
For example to add a stage with the IIS Web App Deploy task:
POST : https://vsrm.dev.azure.com/{organization}/{project}/_apis/release/definitions?api-version=6.0
Request Body: (Of course, you need to replace the parameters accordingly. You can also capture the Request Body(Payload) by pressing F12 when creating a release definition from the UI)
{
"id": 0,
"name": "RESTAPI-WEB",
"source": 2,
"comment": "",
"createdOn": "2022-04-20T08:36:03.598Z",
"createdBy": null,
"modifiedBy": null,
"modifiedOn": "2022-04-20T08:36:03.598Z",
"environments": [
{
"id": -3,
"name": "Stage 1",
"rank": 1,
"variables": {},
"variableGroups": [],
"preDeployApprovals": {
"approvals": [
{
"rank": 1,
"isAutomated": true,
"isNotificationOn": false,
"id": 0
}
],
"approvalOptions": {
"executionOrder": 1
}
},
"deployStep": {
"tasks": [],
"id": 0
},
"postDeployApprovals": {
"approvals": [
{
"rank": 1,
"isAutomated": true,
"isNotificationOn": false,
"id": 0
}
],
"approvalOptions": {
"executionOrder": 2
}
},
"deployPhases": [
{
"deploymentInput": {
"parallelExecution": {
"parallelExecutionType": 0
},
"agentSpecification": null,
"skipArtifactsDownload": false,
"artifactsDownloadInput": {},
"queueId": 158,
"demands": [],
"enableAccessToken": false,
"timeoutInMinutes": 0,
"jobCancelTimeoutInMinutes": 1,
"condition": "succeeded()",
"overrideInputs": {},
"dependencies": []
},
"rank": 1,
"phaseType": 1,
"name": "Agent job",
"refName": null,
"workflowTasks": [
{
"name": "Deploy IIS Website/App: ",
"refName": null,
"enabled": true,
"timeoutInMinutes": 0,
"inputs": {
"WebSiteName": "TestSite",
"VirtualApplication": "",
"Package": "$(System.DefaultWorkingDirectory)\\**\\*.zip",
"SetParametersFile": "",
"RemoveAdditionalFilesFlag": "true",
"ExcludeFilesFromAppDataFlag": "true",
"TakeAppOfflineFlag": "false",
"AdditionalArguments": "",
"XmlTransformation": "false",
"XmlVariableSubstitution": "false",
"JSONFiles": ""
},
"taskId": "1b467810-6725-4b6d-accd-886174c09bba",
"version": "0.*",
"definitionType": "task",
"alwaysRun": false,
"continueOnError": false,
"overrideInputs": {},
"condition": "succeeded()",
"environment": {},
"retryCountOnTaskFailure": 0
}
],
"phaseInputs": {}
}
],
"runOptions": {},
"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": [
{
"conditionType": 1,
"name": "ReleaseStarted",
"value": ""
}
],
"executionPolicy": {
"concurrencyCount": 1,
"queueDepthCount": 0
},
"schedules": [],
"properties": {
"LinkBoardsWorkItems": false,
"BoardsEnvironmentType": "unmapped"
},
"preDeploymentGates": {
"id": 0,
"gatesOptions": null,
"gates": []
},
"postDeploymentGates": {
"id": 0,
"gatesOptions": null,
"gates": []
},
"retentionPolicy": {
"daysToKeep": 30,
"releasesToKeep": 3,
"retainBuild": true
},
"processParameters": {}
}
],
"artifacts": [
{
"type": "Build",
"definitionReference": {
"IsMultiDefinitionType": {
"name": "False",
"id": "False"
},
"project": {
"name": "AzureFunction",
"id": "4da2f07a-ac7b-43a0-b764-459af8a4d9df"
},
"repository": {
"name": "",
"id": ""
},
"definitions": {
"name": "",
"id": ""
},
"definition": {
"name": "AzureFunctions_CI",
"id": "172"
},
"defaultVersionType": {
"name": "Latest",
"id": "latestType"
},
"defaultVersionBranch": {
"name": "",
"id": ""
},
"defaultVersionTags": {
"name": "",
"id": ""
},
"defaultVersionSpecific": {
"name": "",
"id": ""
}
},
"alias": "_AzureFunctions_CI",
"isPrimary": true,
"sourceId": "",
"isRetained": false
}
],
"variables": {},
"variableGroups": [],
"triggers": [],
"lastRelease": null,
"tags": [],
"path": "\\",
"properties": {
"DefinitionCreationSource": "ReleaseNew",
"IntegrateJiraWorkItems": "false",
"IntegrateBoardsWorkItems": false
},
"releaseNameFormat": "Release-$(rev:r)",
"description": ""
}
To deploy the webapp, please refer to Deploy your Web Deploy package to IIS servers using WinRM and Deploy an Azure Web App for details.

Commit Status not working with Continuous Deployment Trigger in Azure Release via API

We have an Azure Repository which triggers a Release-Pipeline every time something is pushed to the main branch.
When a Release is triggered it shows its status (succeeded) on the right side in the commits in Azure Repos like on the following Picture:
It even shows which stage is already promoted etc. which is awesome. This all works fine when configuring the Release Pipeline Manually with the following CD-Trigger Configuration:
Even when exporting the Pipeline JSON file and reimporting it everything works as expected.
However, when creating the Release with the exact same Settings via API i don't see the Status of the Release. The trigger itself works as expected but the status in the commits is simply not there:
Does someone know which exact Setting in the Release-Pipeline.json is responsible for this status?
Here are some parts of the json body I send via API which might be missing something?
Edit: A few more information needed i guess. I use a cli-tool to create the body and send the api request. The values are templated.
The template gets its values either from previous api calls or from user inputs. Here is the complete template. I created it based on the manually configured relase-pipeline JSON (Which works fine and shows the status i want).
{
"name": "{{.BuildProjectName}}/{{.BuildServiceName}}",
"path": "\\",
"isDeleted": false,
"source": "restApi",
"releaseNameFormat": "{{.BuildServiceName}}-$(rev:r)",
"properties": {
"DefinitionCreationSource": {
"$type": "System.String",
"$value": "ReleaseNew"
},
"IntegrateBoardsWorkItems": {
"$type": "System.String",
"$value": "False"
},
"IntegrateJiraWorkItems": {
"$type": "System.String",
"$value": "false"
}
},
"artifacts": [
{
"sourceId": "{{.BuildProjectID}}:{{.BuildRepoID}}",
"type": "Git",
"alias": "BuildRepo",
"definitionReference": {
"branches": {
"id": "{{.BuildRepoDefaultBranch}}",
"name": "{{.BuildRepoDefaultBranch}}"
},
"checkoutNestedSubmodules": {
"id": "True",
"name": "Any nested submodules within"
},
"defaultVersionType": {
"id": "latestFromBranchType",
"name": "Latest from the default branch"
},
"definition": {
"id": "{{.BuildRepoID}}",
"name": "{{.BuildServiceName}}"
},
"project": {
"id": "{{.BuildProjectID}}",
"name": "{{.BuildProjectName}}"
}
},
"isPrimary": true,
"isRetained": false
},
{
"type": "Git",
"alias": "FluxDeployScript",
"definitionReference": {
"branches": {
"id": "master",
"name": "master"
},
"checkoutNestedSubmodules": {
"id": "True",
"name": "Any nested submodules within"
},
"defaultVersionType": {
"id": "latestFromBranchType",
"name": "Latest from the default branch"
},
"definition": {
"id": "black-washed",
"name": "azure-pipeline-templates"
},
"project": {
"id": "black-washed",
"name": "Operations"
}
},
"isRetained": false
},
{
"type": "Build",
"alias": "BuildPipeline",
"definitionReference": {
"defaultVersionType": {
"id": "latestType",
"name": "Latest"
},
"definition": {
"id": "{{.BuildPipelineID}}",
"name": "{{.BuildServiceName}}"
},
"IsMultiDefinitionType": {
"id": "False",
"name": "False"
},
"project": {
"id": "{{.BuildProjectID}}",
"name": "{{.BuildProjectName}}"
}
},
"isRetained": false
}
],
"environments": [
{
"name": "dev",
"rank": 1,
"conditions": [
{
"name": "ReleaseStarted",
"conditionType": 1,
"value": ""
}
],
"deployPhases": [
{
"rank": 1,
"phaseType": 1,
"name": "Agent job",
"refName": null,
"deploymentInput": {
"queueId": "{{.QueueID}}",
"agentSpecification": {
"identifier": "ubuntu-20.04"
}
},
"workflowTasks": [
{
"environment": {},
"taskId": "2a6ca863-f2ce-4f4d-8bcb-15e64608ec4b",
"version": "1.*",
"name": "Download flux creds",
"refName": "fluxCreds",
"enabled": true,
"alwaysRun": false,
"continueOnError": false,
"timeoutInMinutes": 0,
"definitionType": "task",
"overrideInputs": {},
"condition": "succeeded()",
"inputs": {
"secureFile": "black-washed",
"retryCount": "8",
"socketTimeout": ""
}
},
{
"environment": {
"USER_EMAIL": "{{.ApproverMail}}",
"ENVIRONMENT": "$(Release.EnvironmentName)",
"DESCRIPTION": "$(Release.ReleaseDescription)",
"URL": "$(Release.ReleaseWebURL)",
"PROJECT": "{{.BuildProjectName}}",
"CONTAINER": "{{.BuildServiceName}}",
"TAG": "$(Release.Artifacts.BuildPipeline.BuildNumber)",
"REPOSITORY": "finodigital.azurecr.io",
"WORKLOAD_TYPE": "deployment",
"NAMESPACE": "{{.BuildProjectName}}",
"WORKLOAD_NAME": "{{.BuildProjectName}}-{{.BuildServiceName}}",
"USER_NAME": "{{.ApproverName}}",
"FLUX_CREDS": "$(fluxCreds.secureFilePath)"
},
"taskId": "6c731c3c-3c68-459a-a5c9-bde6e6595b5b",
"version": "3.*",
"name": "Bash Script",
"refName": "",
"enabled": true,
"alwaysRun": false,
"continueOnError": false,
"timeoutInMinutes": 0,
"definitionType": "task",
"overrideInputs": {},
"condition": "succeeded()",
"inputs": {
"targetType": "filePath",
"filePath": "$(System.DefaultWorkingDirectory)/FluxDeployScript/flux-release.sh",
"arguments": "",
"workingDirectory": "",
"failOnStderr": "false",
"noProfile": "true",
"noRc": "true"
}
}
]
}
],
"retentionPolicy": {
"daysToKeep": 30,
"releasesToKeep": 3,
"retainBuild": true
},
"preDeployApprovals": {
"approvals": [
{
"rank": 1,
"isAutomated": true,
"isNotificationOn": false
}
],
"approvalOptions": {
"requiredApproverCount": null,
"releaseCreatorCanBeApprover": false,
"autoTriggeredAndPreviousEnvironmentApprovedCanBeSkipped": false,
"enforceIdentityRevalidation": false,
"timeoutInMinutes": 0,
"executionOrder": 1
}
},
"postDeployApprovals": {
"approvals": [
{
"rank": 1,
"isAutomated": true,
"isNotificationOn": false
}
],
"approvalOptions": {
"requiredApproverCount": null,
"releaseCreatorCanBeApprover": false,
"autoTriggeredAndPreviousEnvironmentApprovedCanBeSkipped": false,
"enforceIdentityRevalidation": false,
"timeoutInMinutes": 0,
"executionOrder": 2
}
}
},
{
"name": "test",
"rank": 2,
"conditions": [
{
"name": "dev",
"conditionType": 2,
"value": "4"
}
],
"deployPhases": [
{
"rank": 1,
"phaseType": 1,
"name": "Agent job",
"refName": null,
"deploymentInput": {
"queueId": "{{.QueueID}}",
"agentSpecification": {
"identifier": "ubuntu-20.04"
}
},
"workflowTasks": [
{
"environment": {},
"taskId": "2a6ca863-f2ce-4f4d-8bcb-15e64608ec4b",
"version": "1.*",
"name": "Download flux creds",
"refName": "fluxCreds",
"enabled": true,
"alwaysRun": false,
"continueOnError": false,
"timeoutInMinutes": 0,
"definitionType": "task",
"overrideInputs": {},
"condition": "succeeded()",
"inputs": {
"secureFile": "black-washed",
"retryCount": "8",
"socketTimeout": ""
}
},
{
"environment": {
"USER_EMAIL": "{{.ApproverMail}}",
"ENVIRONMENT": "$(Release.EnvironmentName)",
"DESCRIPTION": "$(Release.ReleaseDescription)",
"URL": "$(Release.ReleaseWebURL)",
"PROJECT": "{{.BuildProjectName}}",
"CONTAINER": "{{.BuildServiceName}}",
"TAG": "$(Release.Artifacts.BuildPipeline.BuildNumber)",
"REPOSITORY": "finodigital.azurecr.io",
"WORKLOAD_TYPE": "deployment",
"NAMESPACE": "{{.BuildProjectName}}",
"WORKLOAD_NAME": "{{.BuildProjectName}}-{{.BuildServiceName}}",
"USER_NAME": "{{.ApproverName}}",
"FLUX_CREDS": "$(fluxCreds.secureFilePath)"
},
"taskId": "6c731c3c-3c68-459a-a5c9-bde6e6595b5b",
"version": "3.*",
"name": "Bash Script",
"refName": "",
"enabled": true,
"alwaysRun": false,
"continueOnError": false,
"timeoutInMinutes": 0,
"definitionType": "task",
"overrideInputs": {},
"condition": "succeeded()",
"inputs": {
"targetType": "filePath",
"filePath": "$(System.DefaultWorkingDirectory)/FluxDeployScript/flux-release.sh",
"arguments": "",
"workingDirectory": "",
"failOnStderr": "false",
"noProfile": "true",
"noRc": "true"
}
}
]
}
],
"retentionPolicy": {
"daysToKeep": 30,
"releasesToKeep": 3,
"retainBuild": true
},
"preDeployApprovals": {
"approvals": [
{
"rank": 1,
"isAutomated": false,
"isNotificationOn": false,
"approver": {
"displayName": null,
"id": "{{.ApproverID}}"
}
}
],
"approvalOptions": {
"requiredApproverCount": null,
"releaseCreatorCanBeApprover": false,
"autoTriggeredAndPreviousEnvironmentApprovedCanBeSkipped": false,
"enforceIdentityRevalidation": false,
"timeoutInMinutes": 0,
"executionOrder": 1
}
},
"postDeployApprovals": {
"approvals": [
{
"rank": 1,
"isAutomated": true,
"isNotificationOn": false
}
],
"approvalOptions": {
"requiredApproverCount": null,
"releaseCreatorCanBeApprover": false,
"autoTriggeredAndPreviousEnvironmentApprovedCanBeSkipped": false,
"enforceIdentityRevalidation": false,
"timeoutInMinutes": 0,
"executionOrder": 2
}
}
},
{
"name": "prod",
"rank": 3,
"conditions": [
{
"name": "test",
"conditionType": 2,
"value": "4"
}
],
"deployPhases": [
{
"rank": 1,
"phaseType": 1,
"name": "Agent job",
"refName": null,
"deploymentInput": {
"queueId": "{{.QueueID}}",
"agentSpecification": {
"identifier": "ubuntu-20.04"
}
},
"workflowTasks": [
{
"environment": {},
"taskId": "2a6ca863-f2ce-4f4d-8bcb-15e64608ec4b",
"version": "1.*",
"name": "Download flux creds",
"refName": "fluxCreds",
"enabled": true,
"alwaysRun": false,
"continueOnError": false,
"timeoutInMinutes": 0,
"definitionType": "task",
"overrideInputs": {},
"condition": "succeeded()",
"inputs": {
"secureFile": "black-wahsed",
"retryCount": "8",
"socketTimeout": ""
}
},
{
"environment": {
"USER_EMAIL": "{{.ApproverMail}}",
"ENVIRONMENT": "$(Release.EnvironmentName)",
"DESCRIPTION": "$(Release.ReleaseDescription)",
"URL": "$(Release.ReleaseWebURL)",
"PROJECT": "{{.BuildProjectName}}",
"CONTAINER": "{{.BuildServiceName}}",
"TAG": "$(Release.Artifacts.BuildPipeline.BuildNumber)",
"REPOSITORY": "finodigital.azurecr.io",
"WORKLOAD_TYPE": "deployment",
"NAMESPACE": "{{.BuildProjectName}}",
"WORKLOAD_NAME": "{{.BuildProjectName}}-{{.BuildServiceName}}",
"USER_NAME": "{{.ApproverName}}",
"FLUX_CREDS": "$(fluxCreds.secureFilePath)"
},
"taskId": "6c731c3c-3c68-459a-a5c9-bde6e6595b5b",
"version": "3.*",
"name": "Bash Script",
"refName": "",
"enabled": true,
"alwaysRun": false,
"continueOnError": false,
"timeoutInMinutes": 0,
"definitionType": "task",
"overrideInputs": {},
"condition": "succeeded()",
"inputs": {
"targetType": "filePath",
"filePath": "$(System.DefaultWorkingDirectory)/FluxDeployScript/flux-release.sh",
"arguments": "",
"workingDirectory": "",
"failOnStderr": "false",
"noProfile": "true",
"noRc": "true"
}
}
]
}
],
"retentionPolicy": {
"daysToKeep": 30,
"releasesToKeep": 3,
"retainBuild": true
},
"preDeployApprovals": {
"approvals": [
{
"rank": 1,
"isAutomated": false,
"isNotificationOn": false,
"approver": {
"displayName": null,
"id": "{{.ApproverID}}"
}
}
],
"approvalOptions": {
"requiredApproverCount": null,
"releaseCreatorCanBeApprover": false,
"autoTriggeredAndPreviousEnvironmentApprovedCanBeSkipped": false,
"enforceIdentityRevalidation": false,
"timeoutInMinutes": 0,
"executionOrder": 1
}
},
"postDeployApprovals": {
"approvals": [
{
"rank": 1,
"isAutomated": true,
"isNotificationOn": false
}
],
"approvalOptions": {
"requiredApproverCount": null,
"releaseCreatorCanBeApprover": false,
"autoTriggeredAndPreviousEnvironmentApprovedCanBeSkipped": false,
"enforceIdentityRevalidation": false,
"timeoutInMinutes": 0,
"executionOrder": 2
}
}
}
],
"triggers": [
{
"branchFilters": [
"{{.BuildRepoDefaultBranch}}"
],
"alias": "BuildRepo",
"triggerType": 3
}
]
According to your description, I tested it and everything works as expected.
Steps:
Get the release definition via the REST API Definitions - Get and copy the response body.
GET https://vsrm.dev.azure.com/{organization}/{project}/_apis/release/definitions/{definitionId}?api-version=6.1-preview.4
Create the new release pipeline via the REST API Definitions - Create
POST https://vsrm.dev.azure.com/{organization}/{project}/_apis/release/definitions?api-version=6.1-preview.4
Copy the response body and rename the field name to New release pipeline2, then mark it as request body.
I am using PostMan.
Result:
Update1
It seems that you are missing the field environmentOptions field in the request body, which contains publishDeploymentStatus, which controls the feature you are missing.
If you do not configure it or set the value to false, you will not see the Status of the Release in the commit page.
"environmentOptions": {
"emailNotificationType": "OnlyOnFailure",
"emailRecipients": "release.environment.owner;release.creator",
"skipArtifactsDownload": false,
"timeoutInMinutes": 0,
"enableAccessToken": false,
"publishDeploymentStatus": false,
"badgeEnabled": false,
"autoLinkWorkItems": false,
"pullRequestDeploymentEnabled": false
},
Result:

Azure DevOps REST API to create a release definition

I'm trying to create a release definition by using Azure DevOps REST API. I've created a json file which has configuration details for the request. I'm getting the below error, while creating the release definition.
{
"$id": "1",
"innerException": null,
"message": "Workflow of deploy job 'Run on the agent' in release pipeline stage 'development' is invalid. Add valid tasks and try again.",
"typeName": "Microsoft.VisualStudio.Services.ReleaseManagement.Data.Exceptions.InvalidRequestException, Microsoft.VisualStudio.Services.ReleaseManagement2.Data",
"typeKey": "InvalidRequestException",
"errorCode": 0,
"eventId": 3000
}
I'm using the below request body to create a new release definition in Azure cloud.
{
"name": "myreleasedefn1",
"artifacts": [{
"type": "DockerHub",
"alias": "_dockerusername_mydockerimage",
"definitionReference": {
"connection": {
"id": "dd986f4a-123k-45d5-b8e6-fc4fds23rce",
"name": "dockerservice"
},
"defaultVersionType": {
"id": "selectDuringReleaseCreationType",
"name": "Specify at the time of release creation"
},
"definition": {
"id": "dockerusername/mydockerimage",
"name": "dockerusername/mydockerimage"
},
"namespaces": {
"id": "dockerusername",
"name": "dockerusername"
}
},
"isPrimary": true,
"isRetained": false
}],
"releaseNameFormat": "Release-$(rev:r)",
"environments": [{
"name": "development",
"rank": 1,
"retentionPolicy": {
"daysToKeep": 30,
"releasesToKeep": 3,
"retainBuild": true
},
"preDeployApprovals": {
"approvals": [
{
"rank": 1,
"isAutomated": true,
"isNotificationOn": false,
"id": 10
}
],
"approvalOptions": {
"requiredApproverCount": null,
"releaseCreatorCanBeApprover": false,
"autoTriggeredAndPreviousEnvironmentApprovedCanBeSkipped": false,
"enforceIdentityRevalidation": false,
"timeoutInMinutes": 0,
"executionOrder": "beforeGates"
}
},
"postDeployApprovals": {
"approvals": [
{
"rank": 1,
"isAutomated": true,
"isNotificationOn": false,
"id": 12
}
],
"approvalOptions": {
"requiredApproverCount": null,
"releaseCreatorCanBeApprover": false,
"autoTriggeredAndPreviousEnvironmentApprovedCanBeSkipped": false,
"enforceIdentityRevalidation": false,
"timeoutInMinutes": 0,
"executionOrder": "afterSuccessfulGates"
}
},
"deployPhases": [{
"deploymentInput": {
"parallelExecution": {
"parallelExecutionType": "none"
},
"agentSpecification": {
"identifier": "ubuntu-16.04"
},
"skipArtifactsDownload": false,
"artifactsDownloadInput": {
"downloadInputs": []
},
"queueId": 9,
"demands": [],
"enableAccessToken": false,
"timeoutInMinutes": 0,
"jobCancelTimeoutInMinutes": 1,
"condition": "succeeded()",
"overrideInputs": {}
},
"rank": 1,
"phaseType": "agentBasedDeployment",
"name": "Run on the agent",
"workflowTasks": [{
"version": "4.*",
"name": "Deploy Azure App Service",
"refName": "",
"enabled": true,
"alwaysRun": false,
"continueOnError": false,
"timeoutInMinutes": 0,
"overrideInputs": {},
"condition": "succeeded()",
"inputs": {
"ConnectionType": "AzureRM",
"WebAppKind": "webAppContainer",
"WebAppName": "azureappservice1",
"DeployToSlotOrASEFlag": "false",
"ResourceGroupName": "",
"SlotName": "production",
"DockerNamespace": "dockerusername",
"DockerRepository": "mydockerimage",
"DockerImageTag": "10"
}
}]
}]
}]
}
It would be very helpful if you share an example template for the same request.
Please help!!!
Azure DevOps REST API to create a release definition
According to the error message:
"Workflow of deploy job 'Run on the agent' in release pipeline stage 'development' is invalid.
We could to know the task Deploy Azure App Service in the workflowTasks is invalid, we need to provide the correct request body for that task.
As I answered your previous post How to create new build pipeline using Azure DevOps REST API, this is very difficult and error-prone, if we add a huge request body completely manually. Usually, we use REST API Definitions - Get to get the Response Body from the similar release pipeline, then we update the corresponding properties by modifying the Response Body.
As test, I add the task Deploy Azure App Service in my release pipeline, then I use the REST API:
GET https://vsrm.dev.azure.com/{organization}/{project}/_apis/release/definitions/{definitionId}?api-version=5.0
to get the Response Body:
"workflowTasks": [
{
"environment": {},
"taskId": "497d490f-eea7-4f2b-ab94-48d9c1acdcb1",
"version": "4.*",
"name": "Azure App Service Deploy: xxxx",
"refName": "",
"enabled": true,
"alwaysRun": false,
"continueOnError": false,
"timeoutInMinutes": 0,
"definitionType": "task",
"overrideInputs": {},
"condition": "succeeded()",
"inputs": {
"ConnectionType": "AzureRM",
"ConnectedServiceName": "xxxxx",
"PublishProfilePath": "$(System.DefaultWorkingDirectory)/**/*.pubxml",
"PublishProfilePassword": "",
"WebAppKind": "webApp",
"WebAppName": "xxxx",
"DeployToSlotOrASEFlag": "false",
"ResourceGroupName": "",
"SlotName": "production",
"DockerNamespace": "",
"DockerRepository": "",
"DockerImageTag": "",
"VirtualApplication": "",
"Package": "$(System.DefaultWorkingDirectory)/**/*.zip",
"RuntimeStack": "",
"RuntimeStackFunction": "",
"StartupCommand": "",
"ScriptType": "",
"InlineScript": ":: You can provide your deployment commands here. One command per line.",
"ScriptPath": "",
"WebConfigParameters": "",
"AppSettings": "",
"ConfigurationSettings": "",
"UseWebDeploy": "false",
"DeploymentType": "webDeploy",
"TakeAppOfflineFlag": "true",
"SetParametersFile": "",
"RemoveAdditionalFilesFlag": "false",
"ExcludeFilesFromAppDataFlag": "true",
"AdditionalArguments": "-retryAttempts:6 -retryInterval:10000",
"RenameFilesFlag": "true",
"XmlTransformation": "false",
"XmlVariableSubstitution": "false",
"JSONFiles": ""
}
}
]
You could use this response body, and overwrite those properties you want to change.
Where can I get taskId in Azure portal?
You could check the source code of the task from Github,it is generally on the first line of task.json. Or you can use REST API/F12 to get it.
Can we use 'AzureContainerRegistry' as artifact type in the request
body?
The answer should be yes (not test it by a sample). You could add following request body in the body:
"artifacts": [
{
"sourceId": "xxxxxxxxxxxxxxx",
"type": "AzureContainerRepository",
"alias": "xxx",
"definitionReference": {
"connection": {
"id": "xxxxxx",
"name": "xxxx"
},
"defaultVersionType": {
"id": "latestType",
"name": "Latest"
},
"definition": {
"id": "xx",
"name": "xx"
},
"registryurl": {
"id": "22",
"name": "22"
},
"resourcegroup": {
"id": "xx",
"name": "xx"
}
},
"isPrimary": true,
"isRetained": false
}
],
Hope this helps.
I can help here. In workflowTasks You need to include the "taskId": "497d490f-eea7-4f2b-ab94-48d9c1acdcb1" which is id of the AzureRmWebAppDeploymentV4.
"workflowTasks": [
{
"taskId": "497d490f-eea7-4f2b-ab94-48d9c1acdcb1",
"version": "4.*",
"name": "Deploy Azure App Service",
"refName": "",
"enabled": true,
"alwaysRun": false,
"continueOnError": false,
"timeoutInMinutes": 0,
"definitionType": null,
"overrideInputs": {},
"condition": "succeeded()",
"inputs": {
"ConnectionType": "AzureRM",
"WebAppKind": "webAppContainer",
"WebAppName": "azureappservice1",
"DeployToSlotOrASEFlag": "false",
"ResourceGroupName": "",
"SlotName": "production",
"DockerNamespace": "dockerusername",
"DockerRepository": "mydockerimage",
"DockerImageTag": "10"
}
Once I added that I was able to create the release definition with your request body.

Maintain password for TFS Release Management

I'm developing Release pipeline for our internal LOB applications using TFS 2015 Update2 Release Management. There are various tasks like "Windows Machine File Copy" and "Run PowerShell on Target machines" which needs admin credentials to be passed as input parameters. These admin credentials have Administrative access on target nodes. I'm using Windows service accounts for these. We have an organizational security policy to rotate passwords every year.
With that in mind, it is cumbersome to update hundreds of TFS release definitions for new password every year.
Do you have a better idea to handle this?
Thanks for your help and suggestions.
You can update release definitions programmatically via the REST API, which is well-documented and fairly straightforward.
Ex (note that this is for Update 3 and later, per the documentation, the API in TFS 2015.2 may differ slightly):
PUT https://fabfiber.vsrm.visualstudio.com/DefaultCollection/ff213d65-d61d-447c-b39d-d16f21b18364/_apis/release/definitions/28?api-version=3.0-preview.1
Content-Type: application/json
{
"id": 28,
"name": "Fabrikam.CD",
"createdOn": "2016-04-11T11:04:05.197Z",
"createdBy": {
"id": "52a5bc8d-4730-400a-95c7-7276d4ae5953",
"displayName": "Chuck Reinhart",
"uniqueName": "chuckreinhart#outlook.com",
"url": "https://fabfiber.vssps.visualstudio.com/_apis/Identities/52a5bc8d-4730-400a-95c7-7276d4ae5953",
"imageUrl": "https://fabfiber.visualstudio.com/DefaultCollection/_api/_common/identityImage?id=52a5bc8d-4730-400a-95c7-7276d4ae5953"
},
"environments": [
{
"name": "Dev",
"rank": 1,
"deployStep": {
"tasks": []
},
"owner": {
"id": "52a5bc8d-4730-400a-95c7-7276d4ae5953",
"displayName": "Chuck Reinhart",
"uniqueName": "chuckreinhart#outlook.com",
"url": "https://fabfiber.vssps.visualstudio.com/_apis/Identities/52a5bc8d-4730-400a-95c7-7276d4ae5953",
"imageUrl": "https://fabfiber.visualstudio.com/DefaultCollection/_api/_common/identityImage?id=52a5bc8d-4730-400a-95c7-7276d4ae5953"
},
"queueId": 2,
"demands": [],
"conditions": [],
"variables": {},
"runOptions": {},
"environmentOptions": {
"emailNotificationType": "Always",
"skipArtifactsDownload": false,
"timeoutInMinutes": 0
},
"executionPolicy": {
"concurrencyCount": 0,
"queueDepthCount": 0
},
"preDeployApprovals": {
"approvals": [
{
"rank": 1,
"isAutomated": true,
"isNotificationOn": false
}
],
"approvalOptions": null
},
"postDeployApprovals": {
"approvals": [
{
"rank": 1,
"isAutomated": true,
"isNotificationOn": false
}
],
"approvalOptions": null
}
}
],
"artifacts": [
{
"alias": "FabrikamCI",
"type": "Build",
"definitionReference": {
"project": {
"name": "Fabrikam",
"id": "ff213d65-d61d-447c-b39d-d16f21b18364"
},
"definition": {
"name": "Fabrikam.CI",
"id": "1"
}
},
"isPrimary": false
}
],
"variables": {},
"triggers": [],
"revision": 1,
"releaseNameFormat": "",
"retentionPolicy": {
"daysToKeep": 60
}
}