Is it possible to manually update the build variable $(Build.BuildId) - azure-devops

I am helping a friend with their VSTS build and we are using both build identifiers
$(Build.BuildId)
$(Build.BuildNumber)
This is specific to a Xamarin.iOS build where we are using the new VSTS Build tasks for updating the Info.Plist. We need to use the $(Build.BuildId) for the version code which is just a number that increments. Then we want to use the $(Build.BuildNumber) for the actual Version Name. If was to format this into the build string it would look like this:
$(Build.BuildNumber) = 1.0.0
$(Build.BuildId) = 148
Result = 1.0.0 (148)
The problem is we have already submitted our app to the app store with a larger build ID then what our current build is at. Instead of running the build X number of times to sync it up we would like to manually update the BuildId so we can start using this for our full workflow.

No, it’s impossible.
The predefined variable Build.BuildId value is unique to record echo build in the VSTS account.
Even you can change the value by logging command, but it can only work for the current build, when you queue next the build, the build ID will continue increased without any effect.
Such as current Build.BuildId is 148, even if you use the value to 100 by Write-Host "##vso[task.setvariable variable=Build.BuildId]2148" in a build, but when another build is queued, the Build.BuildId will be 149.
The work around is using a user defined variable instead Build.BuildId:
Add a user defined variable such as custom.BuildId and set the value with ($(Build.BuildID)+GapNumber).
Such as if the current Build.BuildID is 148, while the build ID you submitted in app store is 2148, so you can use the custom.BuildId with the value ($(Build.BuildID)+2000). Then use the variables $(custom.BuildId) and $(Build.BuildNumber) for your app.
For next build. The custom.BuildId value will be 1149.

I'm using the counter expression:
MyAppVersion $[counter('my-counter-prefix', 500)]
With MyAppVersion being 500, 501, 502...
This function can only be used in an expression that defines a variable. It cannot be used as part of a condition for a step, job, or stage.
Evaluates a number that is incremented with each run of a pipeline.
Parameters: 2. prefix and seed.
Prefix is a string expression. A separate value of counter is tracked for each unique value of prefix
Seed is the starting value of the counter
You can create a counter that is automatically incremented by one in each execution of your pipeline. When you define a counter, you provide a prefix and a seed.

This is not possible to update Build.BuildId but you can set Build.BuildNumber as it is shown here using logging commands:
Write-Host "##vso[build.updatebuildnumber]my-new-build-number"

Related

Azure Pipeline - Get associated git TAG?

On my pipeline, I can retrieve the build number using the variable RELEASE.ARTIFACTS.MyPipeline_BUILDID. But I was wondering, how can I get the TAG associated with the build.
It is visible within the pipeline like:
is there a way to capture it in a variable within the yml so I properly concatenate it like:
You can use the variable SourceBranch:
The branch of the triggering repo the build was queued for.
When your pipeline is triggered by a tag: refs/tags/your-tag-name
So, in the release the variable will be RELEASE.ARTIFACTS.MyPipeline_SOURCEBRANCH.

Can I programmatically set an overridable default value for a variable in an Azure DevOps Release Pipeline?

I have a variable called some_var in an Azure DevOps release pipeline. I'd like to set the default at release time. But I want to set it programmatically based on the contents of a file in the artifact drop folder. But I still want the user to be able to overwrite the dynamically set value at the time they're creating the release.
So the end-user behavior would be that they (1) navigate to the Release and (2) click "Create New". The dialog comes up with the some_var variable already set to a value stored in a text file. But, because the variable is set to be settable at runtime, they can also modify the variable value before they click the button to create the release.
Is there any way I can dynamically populate (before the release is created) the some_var value and still make it editable by the person creating the release at crate-time.
The dialog comes up with the some_var variable already set to a value
stored in a text file.
We don't support this out-of-box feature. The release pipeline variable can't dynamically
populate the some_var value before the release is created.
Possible workaround:
Your original purpose is to set it programmatically based on the contents of a file in the artifact drop folder. So I assume you may have a build pipeline which this release depends on, and your actual need is to:
Once the build pipeline is finished, the default value of some_var in release pipeline should set as the value from build pipeline.
You can consider adding a powershell task in the end of build pipeline that release depends on, calling the Definitions-Update rest api in ps script to set the default value of some_var in Release pipeline depending on content of Build pipeline. Similar issue you can check this one.
And if the pipeline variable some_var is settable at release time:
The whole behavior would be (assuming we want to pass the buildID in Build to the some_var in Release):
1.The build pipeline executes well, its last Powershell task updates the some_var to some_var = 15.
2.When I click the Create release button, the dialog comes up with some_var variable already set to a value from Build pipeline 15.
3.Now, because the some_var enables settable at release time, we can easily modify it before clicking the Create button.
Hope it helps :)

How can I control my build number with Azure DevOps?

I get so many frustrations with Azure DevOps. In my Build number format I would like to have both
A number that restart to 0 when I update my major an minor version.
But I also would like to have a real build number that is never reset whatever is my build number format. This build number can also be shared by all my build pipeline of my project. Is it possible?
I'm not using YAML format. I use the classic interfaces with the option page to set my build format. At this moment I have this:
It work except each month the r number restart at 0. I want it to continue.
EDIT
I still didn't decided my final format. I would like to understand all the possibilities. Now I discovered the $(BuildID) property I have another question. Is it possible to have something similar to $(Rev:r) variable but that only check the left part of my build number.
Example:
4.16.$(SequenceFor[4.16]).$(BuildID)
In fact I would like to manually set the Major and Minor version and let the system update one by one the Build and use the Revision for the global $(BuildID).
The $(rev:r) is restarted when the build number changes in any character, so this is the reason why it's restarted whenever the major/minor or the sate changed.
So if you want to use an incremental unique number you can't use the $(rev:r) because then it will be restarted each build.
If you want a number that depends on the major and the minor numbers you need to use the counter expression:
Create 2 variables:
major-minor = 4.16
And a variable that depends on his value and also is a counter:
revision = $[ counter(variables['major-minor'],0) ]
The build number will be:
$(major-minor).$(revision).$(Build.BuildId)
Now, if you will change the major-minor (to 4.17 or 5.16) the revision will be again 0.

Can I enumerate a variable group in VSTS?

TL;DR: Search and replace placeholders in a text file with the decrypted values of secrets in a variable group.
I would like to use a PowerShell script to receive a variable group in a release pipeline and then iterate through the list, performing search-and-replace on a file being released.
The variables in the variable list are secrets so I want to overwrite the placeholders in the file with the decrypted value of the variables.
The values of the variables are environment specific, so I do not want to provide the values at build time and do not want to include the decrypted values in a stored artifact.
The file being search-replaced will be used in an execution at release time but will not be deployed to a host, so will be destroyed upon completion of the pipeline execution.
The Tokenization task from the Visual Studio Marketplace does this job well. You'll need to install it into your Azure DevOps organisation, it's available at https://marketplace.visualstudio.com/items?itemName=TotalALM.totalalm-tokenization
By default the Tokenization task uses double underscores to identify the placeholders. It will replace any text that that matches the name of a variable in your release definition as long as it's surrounded by double underscores.
So if you want to write the value of a variable called MySecretVariable into your file you'll need to add a place holder like __MySecretVariable__ into the file where ever you want that value to be written.
The Tokenization task will write any encrypted values into the file in plain text but in the release logs they will be obfuscated.
If you're storing your variables in a variable group just link that to the release definition and set the scope to the appropriate environment.
So, I've found that, as long as I have a Base64 token configured for Variable Groups (click 'Show all scopes' when creating a new PAT) then I can call GET https://dev.azure.com/{organization}/{project}/_apis/distributedtask/variablegroups/{groupId}?api-version=5.1-preview.1 to get the variable group I need.
The above, however, will not return a value for secrets, although there is a hack/workaround for this (involving multiple pipeline steps).
The advisable route is to create a Key Vault in Azure and perform the processing either in Powershell or code.
As I need the decrypted key values passed into my application via a repeated find-replace, I have implemented a Powershell script in one Release pipeline step and consume the output in the next step.

Teamcity SetParameter doesn't seem to be working

As the first step in a build configuration I am trying to dynamically change a parameter and use it in the subsequent steps. Reading online, it seems that the way to do this is to call ##teamcity[setParameter. But this doesn't seem to be working. It doesn't even change the value in the same step.
For example, I have created a test parameter and set it's default value to '1'. Inside a powershell script, I tried to change it to 2, as shown below.
But the output remains unchanged as can be seen below
I am currently using TeamCity 8.0.3 (build 27540). What am I doing wrong?
EDIT: I think the problem might be the command you're using to set the parameter. Try:
Write-Host "##teamcity[setParameter name='TestParameter' value='2']"
--
We've experienced the same behavior. The key here is 'subsequent steps.' You must modify the parameter in a separate build step that is run before the step in which you want to use the new parameter.
It's my understanding that all parameters in a build step are evaluated immediately before the execution of that step. The tokens will be replaced with the unmodified values of those parameters. Thus, what actually gets executed by the build agent is:
Write-Host "TestParameter value is 1"
Write-Host "##teamcity[setParameter name='TestParameter' value='2']"
Write-Host "TestParameter value is 1"