I have a very simple script which spits out environment variables like this:
Write-Host "SYSTEM_TEAMPROJECT: $ENV:SYSTEM_TEAMPROJECT"
My build has one step, the PowerShell task. The task script filename is set to the path to the script in TFSVC e.g. $/Main/BuildProcessTemplates/AllProps.ps1.
When I queue a new build it fails reporting the following error: "The term 'C:\Builds\agent_work\cb535ea3\Main' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again."
Have I configured the task incorrectly?
-- UPDATE: Here's a copy of the powershell task
Under the repository tab you need to include the script like below. If you have a directory of scripts you can select the folder instead.
Related
I'm trying to execute msbuild on Azure Devops. Because of that I cannot use the MSBuild task provided.
When I use a Command Line task the command is not recognised. On my local machine I load vcvarsall.bat before I use msbuild. But I've not been unable to work out how to obtain that path in Azure Devops. Doesn't appear to be a Develop Command Prompt task for Azue Devops either.
Any ideas on how I can use msbuild from a Command Line task or Batch Script task? Using their Hosted VS agent.
The best way to do this in a supported way is to use vswhere. The following bit of script will install vswhere (using chocolatey) and then query the installer registry where msbuild can be found. Replace -latest with a more specific version if you need that:
choco install vswhere
for /f "tokens=*" %%i in ('vswhere -latest -requires Microsoft.Component.MSBuild -find MSBuild\**\Bin\MSBuild.exe -nologo') do set msbuildpath="%%i"
echo "##vso[task.setvariable variable=msbuildpath]%msbuildpath%"
This will save the path to msbuild to the environment variable %msbuildpath% as well as the pipeline variable (for this stage) $(msbuildpath).
You can then either use a second run commandline task and pass in $(msbuildpath) or you can simply call MsBuild from the same piece of script mentioned above by calling:
%msbuildpath%
This will make sure your script will remain working, even if Microsoft upgrades their images and moves some things around (which does happen).
You can also get vswhere using wget or invoke-webrequest -outfile from the following location:
https://github.com/Microsoft/vswhere/releases/latest/download/vswhere.exe
Other samples for vswhere syntax can be found on the project wiki, including the syntax for PowerShell.
If you use Hosted Agent 2017 you can run the msbuild.exe from the Command Line task in this way:
Command Line version 1:
Command Line version 2:
Results:
If you are interested in seeing how the built-in Microsoft task resolves the path, all the Azure Devops tasks are provided open-source. These are the path functions you probably care to review.
Here is the solution I came up with using only built-in pipeline tasks which makes the MSBuild bin directory available on the path environment variable.
Create a PowerShell task to generate an MSBuild project to capture and output to a file the variables you are interested in (ex. MSBuildBinPath)
PowerShell script
"<Project DefaultTargets=`"DetectMsBuild`">
<ItemGroup>
<OutFile Include=`"`$(MsBuildDetectionFile)`" />
<OutFile Condition=`"'`$(OutFile)' == ''`" Include=`"msbuildInfo.json`" />
</ItemGroup>
<Target Name=`"DetectMsBuild`">
<PropertyGroup>
<MsBuildPaths>
[{
`"Name`": `"BinPath`",
`"Value`": `"`$(MSBuildBinPath.Replace('\', '\\'))`"
}]
</MsBuildPaths>
</PropertyGroup>
<WriteLinesToFile
File=`"#(Outfile)`"
Lines=`"`$(MsBuildPaths)`"
Overwrite=`"true`"
Encoding=`"UTF-8`" />
</Target>
</Project>" | Out-File -FilePath "msbuilddetect.proj" -Encoding utf8
Set the working directory and any variables accordingly.
PowerShell task settings screenshot:
Create an MSBuild task to run the project file generated by the previous task. Ensure the MSBuild version is set to the version you want to use.
MSBuild task settings screenshot:
Last, create another PowerShell task that will parse the outputted JSON file of the extracted variables and sets environment variables accordingly.
PowerShell script
Write-Host "Current path: $($env.Path)`n`n"
$msBuildVariables = Get-Content -Path msbuildInfo.json | ConvertFrom-Json
$Path = "$($msBuildVariables[0].Value);$($env:Path)"
Write-Host "##vso[task.setvariable variable=Path;]$Path"
PowerShell task settings screenshot:
Here is a screenshot of the task order in the build pipeline.
I'm trying to build a deploy package from a Publish Profile using msbuild. I use the command from https://stackoverflow.com/a/15079260/492336:
msbuild.exe MyProject.csproj /p:DeployOnBuild=true;PublishProfile=MyProfile
But I am getting this error:
C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v14.0\Web\Microsoft.Web.Publishing.targets(3683,5): error MSB4044: The "CheckPathAttributes" task was not given a value for the required parameter "Path". [c:\Workspace\MyProject\MyProject.csproj]
How should I go about fixing it?
The reason seems to be related to this line inside my *.pubxml file:
<DesktopBuildPackageLocation>$(SolutionDir)/WebSite1.zip</DesktopBuildPackageLocation>
It works from VisualStudio because $(SolutionDir) is defined there, but it obviously is not defined when I execute msbuild from the command line (maybe it would be defined if I used the solution instead of the csproj file).
Edit: Changing it to $(ProjectDir)/WebSite1.zip works as well.
I have a SQL Server Database Project in Visual Studio 2015. This project is being used by the CI/CD tool to publish to the target databases using msbuild with a SqlPublishTask and an associated publish profile.
The msbuild command looks something like:
"C:\Program Files (x86)\MSBuild\14.0\Bin\msbuild.exe" "c:\pathto\MySqlProj\MySql.sqlproj" /t:Publish /p:SqlPublishProfilePath="c:\pathto\MySqlProj\MyProfile.publish.xml" /p:UpdateDatabase=True /p:PublishScriptFileName="MySqlProj.ssdt-artefact.sql" /m /nr:false
Any schema related changes are successfully published.
However, the pre-build sql script is not run. I can see this because old data that should be removed by the pre-build script is not. I have also tested the pre-build script separately and it works fine.
I have checked and the pre-build script has a Build Action of PreDeploy. The location of the pre-build script in the project is:
c:\pathto\MySqlProj\Scripts\Pre-Deploy\Script.PreDeployment.sql
Any idea why the pre-deploy script is not running?
Managed to solve this. From experimentation it looks like even though a pre-deployment script is created using the Pre-Deployment Script template this doesn't mark the file as being a pre-deployment script.
Instead, it appears that MSBuild is looking for a specific comment section at the start of the file in order to determine if it is a pre-deployment script:
/*
Pre-Deployment Script Template
--------------------------------------------------------------------------------------
This file contains SQL statements that will be executed before the build script.
Use SQLCMD syntax to include a file in the pre-deployment script.
Example: :r .\myfile.sql
Use SQLCMD syntax to reference a variable in the pre-deployment script.
Example: :setvar TableName MyTable
SELECT * FROM [$(TableName)]
--------------------------------------------------------------------------------------
*/
In my case, those comments had been removed. Adding them back resulted in the script being run. The same is true for post-deployment scripts.
In a TFS2013 build, in the Post-build path of the build definition, I call a PowerShell script which need to get the path of the Solution built just before.
But the SolutionPath varibale is not provided in the Environment Variables and we can't pass this variable in the Post-Build Arguments in the Definition Build.
Have you a tip for that without modify the build template ?
Thank you.
The reason there isn't a SolutionPath variable in the tfbuild , in my opinion, is because there aren't any obligation you will only build one solution in your build process.
In order to run the script after the solution done with the build you could add an After..sln.targets and specify a task to do as you please (powershell task inside msbuild)
http://sedodream.com/2010/10/22/MSBuildExtendingTheSolutionBuild.aspx
MSBuild - Project-specific targets for solution does not work
Another option is: in case you want the relative path under your root folder, you could just use the $env:TF_BUILD_SOURCESDIRECTORY inside your script, which will lead you to the \src folder of your build
Get-ChildItem $env:TF_BUILD_SOURCESDIRECTORY | Where-Object FullName -Like "*.sln" | foreach {$_.FullName}
I'm calling an external tool to do some post processing in my build sequence using the Exec task in MSBuild. When I update the tool to a new version the name of the directory of the executable changes, but the directory is added to the system PATH variable. Is it possible to use the system PATH variable in MSBuild? I tried the following code but it does not work:
<Exec Command=""$(PATH)\mytool.exe" />
If the directory has been added to the PATH variable, I would expect that the file path would be resolved automatically. I.e. you should be able to use:
<Exec Command="mytool.exe"/>
Maybe first check if the resolution is working ok by opening up a command prompt, cd'ing to some root directory that is different to where the 'mytool.exe' lives, and see if it is resolved when you simply enter "mytool.exe" at the prompt.