Use special character in custom VSTS PowerShell script task - powershell

I am currently facing the problem that I would like to set the Copyright of my AssemblyInfo dynamically during the VSTS build to something like this:
© 2012-2018 Company Name
but the 2018 should be set dynamically representing the current year.
Therefor I tried to set a global build variable to something like this:
© 2012-$(Date:yyyy) Company Name
Here the copyright special character works fine but the date does not work at this place so the next thing I tried was to make a custom PowerShell script build task with an inline script.
I set again my global variable ("Copyright") this time to
-set during build-
and in the inline script I tried to replace the value like this:
$date=$(Get-Date -Format yyyy);
$_Copyright = "© 2012-$date Company Name";
Write-Host "##vso[task.setvariable variable=Copyright]$_Copyright";
Now I got my dynamic date working but on my shipped dlls I get
"c 2012-2018 Company Name"
with a 'c' instead of the '©'.
So I replaced it with [char]0x00A9:
$date=$(Get-Date -Format yyyy);
$_Copyright = [char]0x00A9 + " 2012-$date Company Name";
Write-Host "##vso[task.setvariable variable=Copyright]$_Copyright";
But nothing changes in the result:
"c 2012-2018 Company Name"
Although on my local machine my PowerShell gives me for [char]0x00A9 the '©' sign.
Any suggestions?

I can reproduce this issue.
Seems the logging command cannot recognize the symbol ©. So we cannot set the variable which including the © as the value by below command:
Write-Host "##vso[task.setvariable variable=Copyright]$_Copyright"
In your scenario you can try below workarounds:
1, Using Copyright (c) instead of Copyright ©, the logging command can recognize the string (c):
$date=$(Get-Date -Format yyyy);
$_Copyright = "(c) 2012-$date Company Name";
Write-Host "##vso[task.setvariable variable=Copyright]$_Copyright";
2, Combine variables:
1) Set a global build variable e.g.: $(Symbol) and set © as the value
2) Set a date variable using logging command :
$date=$(Get-Date -Format yyyy);
$Company= "2012-$date Company Name";
Write-Host "##vso[task.setvariable variable=Company]$Company";
3) Use the variable $(Symbol)$(Company) together to get the entire Copyright string.
Alternately you can directly use ©$(Company) to check if that works.

Related

Executing sql file with sqlplus in windows 10 powershell

I have created a .bat file to export csv file regulary through windows task scheduling which works fine.
But not working when I switch to Powershell. It returns (both in ISE and right click .ps1 "Run with Powershell") with:
SQL*Plus: Release 19.0.0.0.0 - Production on Sun May 2 14:05:52 2021
Version 19.10.0.0.0
Copyright (c) 1982, 2020, Oracle. All rights reserved.
ERROR: ORA-12154: TNS:could not resolve the connect identifier specified
So.I'm not sure what I'm doing wrong. The variable input are dummies.
In my .bat contains:
SET NLS_LANG=.AL32UTF8
SET hostIp="123.123.1.12"
SET username="user1"
SET password="pass1"
SET port="1521"
SET service="myDBname"
SET sqlPath="C:\My script\TEST_EXPORT.sql"
sqlplus %username%/%password%#%hostIp%:%port%/%service% #"%sqlPath%"
In my .ps1 contains:
cls
$hostIp="123.123.1.12"
$username="user1"
$password="pass1"
$port="1521"
$service="myDBname"
$sqlPath="C:\My script\TEST_EXPORT.sql"
echo "$username/$password#$hostIp`:$port/$service #$sqlPath"
sqlplus "$username/$password#$hostIp`:$port/$service #$sqlPath"
Try using composite formatting to build the parameter string. The upside is that one can build the string and not to worry about quotation issues. Note that there is no need to escape the colon `: in the string, as it is not interpreted as scope operator.
# A variable that contains double quote
$quote = '"'
$("{0}/{1}#{2}:{3}/{4} #{5}{6}{5}" -f $username, $password, $hostIp, $port, $service, $quote, $sqlPath,$quote)
user1/pass1#123.123.1.12:1521/myDBname #"C:\My script\TEST_EXPORT.sql"
Another an alternative for building complex strings is string interpolation. Here are three versions that contain different techniques to include double-quotes. The same works in composite fomatting too.
# Double-doublequote version. I'd avoid this, as multiple double quotes are hard to read
"${username}/${password}#{$hostIp}:${port}/${service} #""${sqlPath}"""
user1/pass1#{123.123.1.12}:1521/myDBname #"C:\My script\TEST_EXPORT.sql"
# Backtick-escape version
"${username}/${password}#{$hostIp}:${port}/${service} #`"${sqlPath}`""
user1/pass1#{123.123.1.12}:1521/myDBname #"C:\My script\TEST_EXPORT.sql"
# Quote in a variable version
"${username}/${password}#{$hostIp}:${port}/${service} #${quote}${sqlPath}${quote}"
user1/pass1#{123.123.1.12}:1521/myDBname #"C:\My script\TEST_EXPORT.sql"

Is it possible to change the name of a build based on the branch name in Azure Pipelines?

Most of my builds are from either feature branches or develop, and so I tend to use a known build variable to track the build number such as:
variables:
- group: BuildVars
name: $(BuildPrefix)$(Rev:r)
This works and provides me with a nicely formatted build version that I can then follow through into releases, etc:
However, when we're planning a release, we name our branches after the release, for example: release/1.1, and I'd like to have the build name reference that instead of the hardcoded (previous) version.
I know that I can reference the branch name via the Build.SourceBranch variable, but I don't see an obvious way to read and modify that outside of a build step, by which time I believe it's too late? I don't really want to have to manually change the BuildPrefix variable until the release has been deployed out to production.
Building on from this would then be the ability to append appropriate pre-release tags, etc. based on the branch name...
you can always update the build name during the execution of a build using this:
- pwsh: |
Write-Host "##vso[build.updatebuildnumber]value_goes_here"
so you could calculate the value in the same (or previous step) and update the build name with that value
Is it possible to change the name of a build based on the branch name in Azure Pipelines?
The answer is yes.
The solution we currently use is add a Run Inline Powershell task to update build number based on the Build_SourceBranchName:
$branch = $Env:Build_SourceBranchName
Write-Host "Current branch is $branch"
if ($branch -eq "Dev")
{
Write-Host "##vso[build.updatebuildnumber]$DevBuildNumber"
}
elseif ($branch -eq "Beta")
{
Write-Host "##vso[build.updatebuildnumber]$BetaBuildNumber"
}
elseif ($branch -eq "Test")
{
Write-Host "##vso[build.updatebuildnumber]$TestBuildNumber"
}
Check the Logging Command during the build for some more details.
Hope this helps.

Azure DevOps: Getting variable value by concatenating other variables'value as task input

I have my release pipeline Variables tab set like:
I would like to access my123 variable in task's display name by concatenating initialVariable's result.
Outputs
I have tried so far referencing only initialVariable and it returned proper value in Job's display name.
But when I try to create my123 value by using initialVariable(=123), I am not getting proper value (was hoping that $(initialVariable) would convert to 123 and $(my123) would get proper "finalValue").
Azure DevOps: Getting variable value by concatenating other variables'value as task input
This is a known issue. Because the value of nested variables (like $(my$(initialVariable)) are not yet supported in the build/release pipelines.
Check my other thread for some details.
The workaround is add a Run Inline Powershell task to set the variable based on the input pipeline variables, just like Josh answered.
For you case, I test it by following Powershell scripts:
if ($(initialVariable)-eq "123")
{
Write-Host "##vso[task.setvariable variable=my123]finalvalue"
}
else
{
Write-Host "##vso[task.setvariable variable=my123]otherValue"
}
Then we could get the variable my123 based on the value of variable initialVariable in following task, I add command line task to display the value:
In the result, the value in the command line task is correct finalvalue. But the display name is still $(my123):
Important:
That is also the question in your comment. This behavior is expected. That because the variable in the display name is just to get the predefined value. It's static acquisition, not dynamic. The variable my123 is assigned when running powershell. The static variable my123 in the display name does not go in to the environment where the powershell code is running.
So, the variable my123 in the title could not get the value in the task powershell. But other task could use it very well.
Hope this answer clean your puzzle.
It's ugly, but...
Like I mentioned in my comment, I don't think you're going to get this to work in the UI by default.
Luckily you can use PowerShell to hack this together if your REALLY need the ability to address a variable name based on the value of another variable.
All the variables (secrets are handled a little differently) in your build or release pipeline definition are made available to your powershell script FILE (not inline) via environment variables (ie. $env:initialVariable).
Suppose your situation is thus:
selector = selectable1 //this is the value that can change
selectable1 = theFirstSelection
selectable2 = theSecondSelection
selectable3 = theThirdSelection
In this case (assuming I understand your request) you want to be able to change the value of the selector and force tasks to access the appropriate selectable variable.
So...
Define a new variable in your pipeline.
selector = selectable1 //this is the value that can change
selected = "" //this is the variable you use in your tasks
selectable1 = theFirstSelection
selectable2 = theSecondSelection
selectable3 = theThirdSelection
Write a VariableSelection.ps1 script. This powershell script will be what you need to run to assign the value of $(selected) before it gets used.
# VariableSelection.ps1
Write-Host "select variable: $env:selector"
$selectedValue = (gci env:"$env:selector").value
Write-Host "##vso[task.setvariable variable=selected]$selectedValue"
Note: it is my observation that if you write this script inline, it will not work b/c the environment variable functionality is different for scripts run from a file.
Given the value of $(selector) is selectable2, when the script is run, then the value of the $(selected) will be theSecondSelection.
Example in a Pipeline
Powershell
YAML
# Starter pipeline
# Start with a minimal pipeline that you can customize to build and deploy your code.
# Add steps that build, run tests, deploy, and more:
# https://aka.ms/yaml
trigger:
- master
pool:
name: Hosted VS2017
variables:
- name: "selector"
value: "var1"
- name: "selected"
value: ""
- name: "var1"
value: "var1_value"
- name: "var2"
value: "var2_value"
steps:
- task: PowerShell#2
inputs:
filePath: '$(build.sourcesdirectory)/varSelector.ps1'
- task: PowerShell#2
inputs:
targetType: 'inline'
script: |
Write-Host "env:selected: $env:selected"
Write-Host "selected: $(selected)"
Results

How to update AssemblyVersion using Update Assembly Info plugin in VSTS?

I want to update the version number of my .exe file using Update Assembly Info plugin.
I am using the following configuration:
But, I keep getting an error
'$(Date:yyyy.MM.dd)$(Rev:.r)' is not a valid parameter for attribute 'AssemblyVersion'
The $(Date:yyyy.MM.dd) and $(Rev:.r) can’t be used as the build-in variable, it can be used in Build number format (Options tab).
The workaround is that:
Include $(Rev:.r) in Build number format, such as $(date:yyyyMMdd)$(rev:.r)
Add PowerShell task to add a new variable (Arguments: -bn $(Build.BuildNumber)
Script:
param(
[string]$bn
)
$d=Get-Date -Format "yyyyMMdd"
$r=$bn.split("{.}")[-1]
Write-Host "##vso[task.setvariable variable=currentVersion]$d$r"
Then use currentVersion variable in subsequent tasks, such as Update Assembly task.

How to replace variables of JSON file in Team Services?

I'm stuck with a release variable substitution of an angular project. I have a settings.json file which I would like to replace some variables:
{
test : "variable to replace"
}
I tried to find some custom task on the marketplace but all of the tasks seems to work only with xml files for the web.config.
I use the "Replace tokens" from the Marketplace https://marketplace.visualstudio.com/items?itemName=qetza.replacetokens
You define the desired values as variables in the Release Definition and then you add the Replace Tokens task and configure a wildcard path for all target text files in your repository where you want to replace values (for example: **/*.json). The token that gets replaced has configurable prefix and postfix (default are '#{' and '}#'). So if you have a variable named constr you can put in your config.json
{
"connectionstring": "#{constr}#"
}
and it will deploy the file like
{
"connectionstring": "server=localhost,user id=admin,password=secret"
}
The IIS Web App Deploy Task in VSTS Releases has JSON variable substitution under *File Transforms & Variable Substitution Options.
Provide a list of json files and JSONPath expressions for the variables that need replacing
For example, to replace the value of ‘ConnectionString’ in the sample below, you need to define a variable as ‘Data.DefaultConnection.ConnectionString’ in the build/release definition (or release definition’s environment).
{
  "Data": {
    "DefaultConnection": {
      "ConnectionString": "Server=(localdb)\SQLEXPRESS;Database=MyDB;Trusted_Connection=True"
    }
  }
}
You can add a variable in release variables Tab, and then use PowerShell task to update the content of your settings.json.
Assume the original content is
{
test : "old
}
And you want to change it to
{
test : "new"
}
So you can replace the variable in json file with below steps:
1. Add variable
Define a variable in release variable tab with the value you want to replace with (variable test with value new):
2. Add PowerShell task
Settings for powershell task:
Type: Inline Script.
Inline Script:
# System.DefaultWorkingDirectory is the path like C:\_work\r1\a, so you need specify where your appsettings.json is.
$path="$(System.DefaultWorkingDirectory)\buildName\drop\WebApplication1\src\WebApplication1\appsettings.json"
(Get-Content $path) -replace "old",$(test) | out-file $path