I have a very simple variable substitution in my release pipeline, but it's not working. I have the variable in the connectionStrings.config file as such:
<?xml version="1.0"?>
<connectionStrings>
<add name="ExpenseDBConnectionString" connectionString="__ProdConnString__" providerName="System.Data.SqlClient" />
</connectionStrings>
I then have the variable defined in the release pipeline:
I also have the XML Variable Substitution enabled in the Deploy Task:
But I run the release, and the variable doesn't get substituted. I get this message in the logs:
2020-02-28T19:57:26.1262198Z Initiated variable substitution in config file : D:\a\_temp\temp_web_package_875508750741006\Content\D_C\a\1\s\Expenses.Web\obj\Release\Package\PackageTmp\App_Config\ConnectionStrings.config
2020-02-28T19:57:26.1312311Z Processing substitution for xml node : connectionStrings
2020-02-28T19:57:26.1321602Z Skipped Updating file: D:\a\_temp\temp_web_package_875508750741006\Content\D_C\a\1\s\Expenses.Web\obj\Release\Package\PackageTmp\App_Config\ConnectionStrings.config
This should be pretty simple, so not sure what setting I am missing. Help!
You should define your variable name as ExpenseDBConnectionString in the release pipeline. Below is the description of the setting XML variable substitution. The variables are matched against the key or name entries
Variables defined in the build or release pipeline will be matched against the 'key' or 'name' entries in the appSettings, applicationSettings, and connectionStrings sections of any config file and parameters.xml. Variable Substitution is run after config transforms.
So the variable defined should be like below:
Below screenshot is the result from my test release, you can see the connectionString was replaced.
For more information about XML variable substitution, please check it out here.
There are also some third party substitution tools(ie. Magic Chunks) that you can use to replace your config settings. Please check out the example for this thread.
XML transformation will be run on the *.config file for transformation configuration files named *.Release.config or *.<stage>.config
https://learn.microsoft.com/en-us/azure/devops/pipelines/tasks/transforms-variable-substitution?view=azure-devops&tabs=Classic#xml-transformation
That should be your answer? Your file name is not like that.
Related
In the code below, the output of "echo ${{variables.myvariable}}" is always test.
I was expecting it to be test then uat.
How can I edit the variable value from the yaml file?
The format: ${{variables.myvariable}} will be expanded at compile time.
When you use command to update the variable, it will be updated at runtime.
This is the root cause of the issue.
I was expecting it to be test then uat. How can I edit the variable value from the yaml file?
To solve this issue, you need to modify the format to $(myvariable) or $[variables.myvariable]
For more detailed info, you can refer to this doc: Runtime expression syntax
I want to substitute the key "DevConnectionString" before deployment to serve from Release pipeline.
<appSettings>
<add key="DevConnectionString" value="xyz"/>
</appSettings>
I have checked XML variable substitution
XML variable substitution
And also created a release variable "DevConnectionString"
Release variable
But after deployment "DevConnectionString" value not getting changed. Its showing old value.
I valve checked log. Its showing Skipped Updating file web.congif
Initiated variable substitution in config file : ...\obj\Release\Package\PackageTmp\Web.config
Processing substitution for xml node : appSettings
Processing substitution for xml node : connectionStrings
Processing substitution for xml node : configSections
Skipped Updating file: ...\obj\Release\Package\PackageTmp\Web.config
Why web.config not getting updated with new value? Where I am doing mistake?
In Azure Pipelines, I see that you can access the environment variables from scripts in node.js during a pipeline run. However, I want to actually return a value and then capture/use it.
Does anyone know how to do this? I can't find any references on how to do this in documentation.
For consistency's sake it'd be nice to use node scripts for everything and not go back and forth between node and bash.
Thanks
Okay I finally figured this out. Azure documentation is a bit confusing on the topic, but my approach was what follows. In this example, I'm going to make a rather pointless simple script that sets a variable whose value is the name of the source branch, but all lower case.
1) Define your variable
Defining a variable can be done simply (though there is a lot of depth to how variables are used and I suggest consulting Azure documentation on variable creation for more). However, at the top of your pipeline yaml file you can define it as such:
variables
lowerCaseBranchName: ''
This creates an empty variable for use across your jobs. We'll use this variable as our example.
2) Create your script
"Returning a value" from your script simply means outputting it via node's stdout, the output of which will be consumed by the task to set it as a pipeline variable.
An important thing to remember is that any environment variables from the pipeline can be used within node, they are just reformatted and moved under node's process.env global. For instance, the commonly used Build.SourceBranchName environment variable in azure pipelines is accessible in your node script via its alias process.env.BUILD_SOURCEBRANCHNAME. This uppercase name transformation should be uniform across all environment variables.
Here's an example node.js script:
const lowerCaseBranchName = process.env.BUILD_SOURCEBRANCHNAME.toLowerCase();
process.stdout.write(lowerCaseBranchName);
3) Consume the output in the relevant step in azure pipelines
To employ that script in a job step, call it with a script task. Remember that a script task is, in this case, a bash script (though you can use others) that runs node as a command as it sets the value of our variable:
- script: |
echo "##vso[task.setvariable variable=lowerCaseBranchName]$(node path/to/your/script)"
displayName: 'Get lower case branch name'
Breaking down the syntax
Using variable definition syntax is, in my opinion extremely ugly, but pretty easy to use once you understand it. The basic syntax for setting a variable in a script is the following:
##vso[task.setvariable variable=SOME_VARIABLE_NAME]SOME_VARIABLE_VALUE
Above, SOME_VARIABLE_NAME is the name of our variable (lowerCaseBranchName) as defined in our azure pipeline configuration at the beginning. Likewise, SOME_VARIABLE_VALUE is the value we want to set that variable to.
You could do an additional line above this line to create a variable independently that you can then use to set the env variable with, however I chose to just inline the script call as you can see in the example above usign the $() syntax.
That's it. In following tasks, the environment variable lowerCaseBranchName can be utilized using any of the variable syntaxes such as $(lowerCaseBranchName),
Final result
Defining our variable in our yaml file:
variables
lowerCaseBranchName: ''
Our nodejs script:
const lowerCaseBranchName = process.env.BUILD_SOURCEBRANCHNAME.toLowerCase();
process.stdout.write(lowerCaseBranchName);
Our pipeline task implementation/execution of said script:
- script: |
echo "##vso[task.setvariable variable=lowerCaseBranchName]$(node path/to/your/script)"
displayName: 'Get lower case branch name'
A following task using its output:
- script: |
echo "$(lowerCaseBranchName)"
displayName: 'Output lower case branch name'
This will print the lower-cased branch name to the pipline console when it runs.
Hope this helps somebody! Happy devops-ing!
I'm working on Release pipeline, which will perform transformation on App Service Worker configs, then will publish workers + web application.
My input package is a zip package produced out of MsBuild publish (from ASP.NET build pipeline).
...\PackageTmp\app_data\jobs\triggered\BillingWorker\App.Prod.config
...\PackageTmp\app_data\jobs\triggered\BillingWorker\App.Test.config
...\PackageTmp\app_data\jobs\triggered\BillingWorker\BillingWorker.exe.config
...\PackageTmp\app_data\jobs\triggered\EtlWorker\App.Prod.config
...\PackageTmp\app_data\jobs\triggered\EtlWorker\App.Test.config
...\PackageTmp\app_data\jobs\triggered\EtlWorker\EtlWorker.exe.config
...\PackageTmp\Web.config
...\PackageTmp\Web.Test.config
...\PackageTmp\Web.Prod.config
...\PackageTmp\many other files
Transformation of Web.config is done correctly by Publish to Azure Web App task. However, workers configs aren't transformed automatically, so I added a File Transform task with following config:
This step doesn't work and here is the output:
2019-08-14T15:41:01.1435779Z ##[section]Starting: File Transform: config
2019-08-14T15:41:01.1576716Z ==============================================================================
2019-08-14T15:41:01.1576853Z Task : File transform
2019-08-14T15:41:01.1576932Z Description : Replace tokens with variable values in XML or JSON configuration files
2019-08-14T15:41:01.1576994Z Version : 1.156.0
2019-08-14T15:41:01.1600786Z Author : Microsoft Corporation
2019-08-14T15:41:01.1600885Z Help : https://learn.microsoft.com/azure/devops/pipelines/tasks/utility/file-transform
2019-08-14T15:41:01.1600986Z ==============================================================================
2019-08-14T15:41:01.6339900Z ##[warning]Unable to apply transformation for the given package. Verify the following.
2019-08-14T15:41:01.6351367Z ##[warning]Unable to apply transformation for the given package. Verify the following.
2019-08-14T15:41:01.8369297Z Initiated variable substitution in config file :
...
... many lines about variable subsitution
...
This output looks wrong, as it produces warning without declared explanation. How to workaround this warning?
The problem is that File Transform task strongly relies on names of both files - the one being transformed and the one containing transformation rules. Strict naming convention is required which can be described in following words:
A template named Name.xml can be transformed only by files named Name.Debug.xml, Name.Release.xml, and more general - Name.{anything-here}.xml.
What's happening here is that App.config file is renamed to {YourApplicationName}.exe.config during build thus the tranformation using App.Debug.config fails.
I see 2 workarounds:
1. Preserve the original name App.config
a. In a project file, set App.config file's property to Copy to output directory: Copy always
b. Setup "File Transform task" with args -transform *.Debug.config -xml *.config -result {YourApplicationName}.exe.config
c (optional). If you didn't specify -result in task, you need to setup another task to rename App.config to {YourApplicationName}.exe.config after the transformation has finished (for example a Command Line task with command copy App.config {YourApplicationName}.exe.config /Y)
2. Write custom transformator script
a. Unzip package into temp folder
b. Transform file using Powershell (make use of Microsoft.Web.XmlTransform.dll installed on agent)
c. Zip again and replace the original zip.
The native step in the official task doesn't support transformation in zip files. You can use another task for do it before the deploy task.
I used this and it worked fine to me:
https://marketplace.visualstudio.com/items?itemName=solidify-labs.vsts-task-tokenize-in-archive
I am attempting to learn puppet, and so far so good.
What I am having an issue with is using a variable that I have set for a node or group in the web console.
I created a variable called myCustomSetting, and then in a manifest:
file {/var/tmp/myfile.txt
ensure => file,
content => $::myCustomSetting,
}
When I apply the manifest with puppet apply mytest.pp, there are no errors, but the file is empty? What am I missing?
The double semi colon indicate that you wish to reach the top level scope, where you supposedly declared your variable. Check that your variable has not been declared in a local scope.