Create Azure Devops/Pipeline release including all meta data like buildNumber via REST - azure-devops

I'am aware of https://learn.microsoft.com/en-us/rest/api/azure/devops/release/releases/create?view=azure-devops-rest-6.0#uri-parameters and i can create releases via REST, but ...
Problem:
The issue with those releases is, that a release triggered via the REST lacks some predefined variables like Build.BuildNumber - or at least, they are not available at all scopes.
It seems like Build.BuildNumber is available in the pipeline stage, but is missing in when the release name format is computed. This means, a release name format Release-$(Build.BuildNumber)($(Release.ReleaseId)) will end up with a blank Build.BuildNumber when created using the payload below.
Details:
My json payload
{
"definitionId": 9,
"description": "Test Release",
"artifacts": [
{
"alias": "My Build Artifact",
"instanceReference": {
"id": "6989",
"name": null
}
}
],
"isDraft": false,
"reason": "none",
"manualEnvironments": null
}
While artifacts.instanceReference.id references a valid build (which of course has a buildNumber) - so that during the release stage Build.BuildNumber is properly populated.
I send the payload via
curl -X POST -u username:redactedPAT -H "Content-Type: application/json" -d #payload.json https://vsrm.dev.azure.com/redactedCompany/redactedProjectId/_apis/release/releases\?api-version\=6.0
Question:
What is the right way to create a release as if this would be created via the GUI including all the META-Data?
Do i miss use the API somehow or do i need to manually set the environment variables for this to work (or even somehow via variables).
Since the buildNumber is available in the stage, could that be rather/even a bug?

The release name is evaluated at the compile time, which means it is populated before the pipeline tasks are executed. You can check out below workarounds to populated the release name.
1, The $(Build.BuildNumber) variable you defined in the release name format will retrieve the name property you pass to the artifacts instanceReference in the request body. So you can pass the BuildNumber value to the name property under instanceReference in the request body. See here.
{
...
"artifacts": [
{
"alias": "My Build Artifact",
"instanceReference": {
"id": "6989",
"name": BuildNumber #set the buildNumber here.
}
}
],
...
}
2, Another workaround is to use logging commands to update the release name in a script task.
You can add a script task in your release pipeline stage. And run below logging command to update the release name during the release pipeline execution.
echo "##vso[release.updatereleasename]Release-$(Build.BuildNumber)($(Release.ReleaseId))"
See below example:
When the task is executed. it will update the release name with your desired format.

Related

Read DevOps Variable as bool in ARM paramters

I am trying to read in a pipeline variable as a bool. I have the following parameters defined in json:
"parameters": {
"disableFunkyFunction": {
"value": "#{myVariables.disableFunkyFunction}#",
"type": "bool"
}...
}
In my Azure DevOps release pipeline, I have a pipeline variable called myVariables.disableFunkyFunction and the value for it is set to true. However, whenever I try and run the pipeline, it fails on the "Azure resource group deployment" step: Template parameter 'disableFunkyFunction' was provided an invalid value. Expected a value of type 'Boolean', but received a value of type 'String'. I have tried using a value of 1 instead, but to no avail.
The following works, but ideally I want to read the value from the DevOps pipeline variable, not hard code it in the parameters file:
"parameters": {
"disableFunkyFunction": {
"value": true,
"type": "bool"
}...
}
Any suggestions?
From the error message, it seems that the pipeline variable value hasn't been passed to ARM template file.
Since you have set the parameter value as #{myVariables.disableFunkyFunction}#, you can try to use the Replace Token task from Replace Tokens Extension.
Here are the steps:
Step1: Keep the parameter value as #{myVariables.disableFunkyFunction}#.
Step2: Use Replace token task to set the value.
Step3: Deploy the ARM template.
For example:
Note: You need to put the Replace token task before the ARM template deployment step.

Azure Batch and API Job ADD: upload file in wd directory with

I'm using API Job Add to create one Job with one Task in Azure Batch.
This is my test code:
{
"id": "20211029-1540",
"priority": 0,
"poolInfo": {
"poolId": "pool-test"
},
"jobManagerTask": {
"id": "task2",
"commandLine": "cmd /c dir",
"resourceFiles": [
{
"storageContainerUrl": "https://linkToMyStorage/MyProject/StartTask.txt"
}
]
}
}
To execute the API I'm using Postman and to monitor the result I'm using BatchExplorer.
The job and it's task are created correctly, but the 'wd' folder generate automatically is empty.
If I understood fine, I should see the linked file in the storage variable, right?
Maybe, some other parameter is needed in the Json of the body?
Thank you!
Task state of completed does not necessarily indicate success. From your json body, you most likely have an error:
"resourceFiles": [
{
"storageContainerUrl": "https://linkToMyStorage/MyProject/StartTask.txt"
}
You've specified a storageContainerUrl with a file. Also ensure you have provided proper permissions (either via SAS or a user managed identity).

How to use Environment Variables in CI/CD Pipeline in Azure

I am creating the CI/CD pipeline in Azure DevOps for .NetCore API, and I have multiple deployment stages like QA, UAT and Production. Every stages has its own setting like database connectionstrings and many other, and I have one appsettings.json file in which I declared these settings, so its very hard work to change appsettings.json file each time in deployment, so my question is that how I can use environment variables in CI/CD pipelines to avoid all this stuff,
As I Just need to define the variables values in variables section and CD pipeline can automatically pick it from my appsetting.json file.
appsetting.json File
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"AllowedHosts": "*",
"SubscriptionClientName": "api",
"MessageBrokerRetryCount": 5,
"ConnectionStrings": {
"CaseDBConnectionString": "Server=db-server;Database=api_db;User ID=user;pwd =Password;"
},
//For Dev
"MessageBrokerConnection": "ip",
"MessageBrokerUserName": "john",
"MessageBrokerPassword": "john"
}
We typically use the "Replace Tokens" task in our releases, and then set the variables in our release pipeline for each environment that will replace the tokens in our appsettings.json file. Very simple to use and set up.
UPDATE:
In your appsettings.json file, you would do something like:
"Username": "#{AccountUser}#"
Then in your pipeline, you would go into your release and create a variable called "AccountUser". Then you use the Replace Tokens task in your release as the first step, and it will replace #{AccountUser}# in your appsettings.json file with whatever the value of the variable is. Set different variables for each Scope (dev, stage, production or whatever you call your environments in your release) so that your appsettings.json file gets the appropriate value per environment.
a more reasonable approach would be to use application settings of you App Service, they would override values in appsettings.json\web.config
https://learn.microsoft.com/en-us/azure/app-service/configure-common
this might require slight code changes on your part:
https://learn.microsoft.com/en-us/azure/app-service/containers/configure-language-dotnetcore#access-environment-variables

Azure Devops - Domain name is invalid

I am trying to create a virtual machine using ARM template.
I have added ARM template in my visual studio and have checked-in into the Azure Repos.
On running release pipeline I am receiving below error:
InvalidDomainNameLabel: The domain name label $(dns) is invalid. It must conform to the following regular expression: ^[a-z][a-z0-9-]{1,61}[a-z0-9]$. []
Below is the parameter.json file:
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"adminUsername": {
"value": "Myadmin"
},
"dnsNameForPublicIP": {
"value": "mynewdevvmbox003"
}
}
}
dns name "mynewdevvmbox003" is matching the regular expression requirement but still, I am getting this error.
InvalidDomainNameLabel: The domain name label $(dns) is invalid.
According to this error message, the value of domain name that this task server got is $(dns), not mynewdevvmbox003.
I think you should specified the override parameter value in Override template parameters of Azure resource group deployment task, such as -dnsNameForPublicIP $(dns).
If you indeed specify like this, the value in parameter.json will not be parsed any more. Because the override content has higher priority than parameter.json. Here, dns is a pipeline varibale.
Please ensure select the parameter.json file in Template parameters:
And, do not specify adminUsername and dnsNameForPublicIP again in Override template parameters of the task.

Pass content from build back into Visual Studio Team Services Build

I am running build on Azure with a custom build agent (using Unity3d to be precise) I generate output of the build within a .txt file on the build machine and would like to include content within work items created during build.
Example:
Unity build fails and an error is logged to Build.log.
New bug is created with reference to build and the error message from the
logfile
Right now I am using a powershell script
$content = [IO.File]::ReadAllText("$(Build.Repository.LocalPath)\BuildProjectPC\Build.log")
Write-Host "##vso[task.setvariable variable=logContent;]$content"
To format the bug i use System.Description = $logContent but the content of the variable from PS does for some reason not end up in the bug item (it just contains "$logContent").
Any idea or direction how to fix this, respectively how to feed info back into vsts?
The variable value that used for creating work item is initialized before running build steps, so you can’t specify a dynamic variable or change the variable value during the build step that used for creating work item.
You can follow up these steps to verify it:
Open your build definition > Variable > Add a new variable (e.g. logContent, value: oldValue)
Select Options > Check Work Item on Failure > Additional Fields > System.Title $(logContent)
Add PowerShell build step: Write-Host "$(logContent)"
Add PowerShell build step: Write-Host "##vso[task.setvariable variable=logContent;]newValue"
Add PowerShell build step: Write-Host "$(logContent)"
Add PowerShell build step: [Environment]::Exit(1)
The log result:
Step 3 output oldValue
Step 5 output newValue
The created work item title oldValue.
The workaround for your requirement is that, you can create a work item and associated to build through PowerShell with Rest API (add PowerShell step at the end of other steps and Check Always run option).
Associate work item to build:
Request Type: Patch
Request URL: https://[your vsts account].visualstudio.com/DefaultCollection/_apis/wit/workitems/[work item id]?api-version=1.0
Content-Type:application/json-patch+json
Body:
[
{
"op": "add",
"path": "/relations/-",
"value": {
"rel": "ArtifactLink",
"url": "vstfs:///Build/Build/[build id]",
"attributes": {
"comment": "Making a new link for the dependency"
}
}
}
]
You can refer to this blog for PowerShell scripts to create and associate work item.
Build association with work Items in vNext
In the Additional Fields you need to reference the build/release definition variable with the following notation: $(logContent)
as shown here below: