I have an MSBuild/C# project having a target trying to access `%build.counter% parameter supposed to be set by TeamCity.
<Target Name="TraceBuildParameters" BeforeTargets="BeforeBuild">
<Message Text="Build.Counter=$(build_counter)" />
</Target>
I can access it in TeamCity project build settings but none of this work in the script:
build.counter // msbuild error
build_counter // null
system_build_counter // null
teamcity_system_build_counter // null
teamcity_build_counter // null
Is it possible to access this parameter at all, is it exposed?
TeamCity will send any system parameters to your MSBuild script (not configuration parameters). If you explicitly want the %build.counter% value, the easiest approach would be to set a system parameter as follows:
system.BuildCounter = %build.counter%
Then you should be able to reference it as $(BuildCounter).
Alternatively, the build.number is already sent to MSBuild as $(build_number). Depending on whether or not you've customised the build number on the Configuration -> General Settings tab, this may save the need for the extra parameter.
Related
I have the following msbuild arguments:
/m /p:DeployOnBuild=true;PublishProfile="$(PublishProfile).pubxml"
I've added a project that is a shared .NET Web Application that should not be deployed, and does not need publish profiles. However when my build agent runs, it fails because my project does not have publish profiles.
Is there a way to exclude a project or somehow work around this without having to specify individual projects to include?
Is there a way to exclude a project or somehow work around this without having to specify individual projects to include?
AFAIK, I am afraid there is no such way or property we could exclude a project to be deployed on the Azure DevOps directly.
If you do not want to specify individual projects to include.
As a workaround, you could define the property DeployOnBuild in the projects that you want to publish, and pass a value to the property in msbuild arguments to make only this(those) project(s) can be built.
Details:
Edited project(s) which you want to publish and added the following property group before the Import statements in the .csproj file:
<PropertyGroup>
<DeployOnBuild Condition=" '$(DeployProjOrNot)'!='' ">$(DeployProjOrNot)</DeployOnBuild>
</PropertyGroup>
Then the msbuild arguments:
/m /p:DeployProjOrNot=true /p:PublishProfile="$(PublishProfile).pubxml"
In this case, those projects will be published, and the shared .NET Web Application (should not add above Property) will not be published due to the value of the property DeployOnBuild is not set to be true.
Hope this helps.
I have an asp.net core web appication (Visual Studio 2017) and in the .csproj file there is a PrepublishScript Target that is being executed when (before) I publish the application to a location.
I have two different publish profiles, each one publishing the application to a different location and with different settings.
How can I have different PrepublishScript Targets for each publish profile (or at least have conditional execution in this target depending on the publish profile I am publishing)? I don't want to execute the same steps for all publish profiles.
Is there a way to set a variable from each publish profile, that can be read from msbuild and execute tasks conditionally depending on that value?
There are a few different options:
Move the targets to the publish profile.
Publish profiles are just MSBuild files and contain everything that a project file can. If the profiles are so different that you can't really share logic between profiles or managing conditions will get messy, adding the targets to the publish profiles is a good way to maintain profile-specific logic.
Define properties in the publish profiles
Since they are MSBuild files and already contain a PropertyGroup element, you can define any custom property inside this file and use it inside a target or as a condition on the target.
E.g. in the my.pubxml file:
<PropertyGroup>
<PublishFooConfigFile>true</PublishFooConfigFile>
</PropertyGroup>
Then this can be used in the main csproj file:
<Target Name="IncludeFooConfig" AfterTargets="ComputeFilesToPublish" Condition="'$(PublishFooConfigFile)' == 'true'">
<ItemGroup>
<ResolvedFileToPublish Include="config" RelativePath="%(Identity)" CopyToPublishDirectory="PreserveNewest" />
</ItemGroup>
</Target>
Use the PublishProfile property as condition
When you are building with e.g. /p:PublishProfile=Foo, you could also use $(PublishProfile) for MSBuild conditions, but this is a bad practice because it hard-codes a profile name that might not have to do anything with the actual logic and there are additional ways to specify a publish profile which would break this logic.
I'm trying to build a solution with custom configuration "Staging" using MSBuild command parameter /p:Configuration=Staging, but I always getting the current configuration from solution properties and the parameter is ignored.
When I set the first project to Release and pass /p:Configuration=Staging, I still getting Release instead of Staging.
I'm using VS2017.
I print the message using
<Target Name="temp" BeforeTargets="PrepareForBuild">
<Message Text="Custom message Current configuration: $(Configuration)" />
</Target>
And I got the message Custom message Current configuration: Release
When I change the Configuration to Debug from solution property pages and build using MSBuild /p:Configuration=Staging, I got Custom message Current configuration: Debug
How can I override solution configuration when using MSBuild?
Update:
Here is the solution configuration
I'm trying to use the InstallShield MSBuild task to produce an installer on our build machine and put the output in the drop folder. I can produce the installer but it remains located in the source tree.
I tried using OutDir in the task. This worked on my local machine but it changes the actual .ism file; thus, failing on the build machine.
Next, I tried using TaggedOutputs ItemGroup. I'm just not sure how to make it work. I don't see any changes in my output. Here's my script:
<ItemGroup>
<!-- The TaggedOutputs items allow you to explicitly add extra files to output groups. Each item must include both Name and OutputGroup, as well as TargetPath metadata values. -->
<TaggedOutputs Include="P:\">
<Name>AvApp</Name>
<OutputGroup>Primary output</OutputGroup>
<TargetPath>My Test Exe.exe</TargetPath>
</TaggedOutputs>
</ItemGroup>
<!-- Run interactive InstallShield on the developer machine -->
<InstallShield Project="R:\src\Setup\AvSetup\AvSetup.ism"
ProductConfiguration="Product Configuration 1"
ReleaseConfiguration="Release 1"
OutputGroups="$(TaggedOutputs)"
/>
where P is mapped to the target location.
Is my syntax incorrect or is there another tag I can use?
InstallShield version is 2012.
InstallShield's Targets file has this built in but it's not designed correctly and only works based on certain assumptions that may not be true.
The way I like to do it is:
1) Define a Path Variable in the ISM called ISBUILDDIR and give it a defined value of
<ISProjectDataFolder>
2) Under Product Configurations, Release Configuration, set the Build Release location to \ProductName
This essentially gives you an abstraction that by default behaves like before but can be overridden during the build.
3) In your .ISPROJ (MSBuild) create the following item group:
<ItemGroup>
<InstallShieldPathVariableOverrides Include="$(OutDir)">
<PathVariable>ISBUILDDIR</PathVariable>
</InstallShieldPathVariableOverrides>
</ItemGroup>
Now the $(OutDir) property will be assigned to the ISBUILD path variable and the product/release configuration will output to $(OutDir)\ProductName In the case of TFS Builds $(OutDir) gets assigned $(BinariesRoot) so your build output will get picked up and placed in the drop location archive.
World's simplest task (see below) is not being executed after I publish my web application project. Any idea why?
<Target Name="AfterPublish">
<Copy SourceFiles="C:\A.txt" DestinationFiles="C:\B.txt" />
</Target>
Note: The following applies to VS2010 and publishing web-application projects with the "Web Deploy" publish method selected in the 'Build/Publish {projectname}' dialog.
Julien Hoarau's correct in that "Publish" is NOT the name of the msbuild target invoked in the above case; the actual target name is "MSDeployPublish".
Therefore, you have to define a "Target" element whose "AfterTarget" attribute's value is set to "MSDeployPublish" - the "Name" attribute's value does not matter (as long as it's unique among target names).
Here's how to do it:
Open the project file (e.g. *.csproj) in a text/XML editor and, just before the closing </Project> tag, add a <Target Name="CustomPostPublishAction" AfterTargets="MSDeployPublish"> element; pick a name of your choice for "CustomPostPublishAction".
Add a so-called Task child element that performs the desired action; for instance, to add a command to be passed to cmd.exe, use an <Exec Command="..." /> element.
Example:
<Target Name="CustomPostPublishActions" AfterTargets="MSDeployPublish" >
<Exec Command="echo Post-PUBLISH event: Active configuration is: $(ConfigurationName)" />
</Target>
Note:
In command strings, use XML entity(?) references in place of characters that would break XML parsing, e.g. ">" in place of "<".
For documentation of the <Target> element in general, see http://msdn.microsoft.com/en-us/library/t50z2hka.aspx
Task-elements reference here: http://msdn.microsoft.com/en-us/library/7z253716.aspx
In general, if you need to determine the name of the msbuild.exe target that is actually invoked by Visual Studio 2010, do the following:
Go to Tools/Options..., Project and Solutions/Build and Run, select 'Detailed' (or, for even more information, 'Diagnostic') from the dropdown list labeled 'MSBuild project build output verbosity.
After running the build/publish action, e.g. Build/Publish, examine the Output window for the last occurrence of the string "Done building target" to determine the top-level target that was invoked.
Visual Studio 2013. Publish Web application to file system.
<Target Name="Moose" AfterTargets="GatherAllFilesToPublish" >
<Message Importance="high" Text="***Moooooooooooooooose***$(WPPAllFilesInSingleFolder)***$(TargetDir)" />
</Target>
Note: Make sure that build logging is set to at least to Detailed. Look for it under Tools -> Options -> Projects and Solutinos -> Build and Run -> MSBuild output verbosity. Diagnostic is also fine if you want to investigate which build target was last run before actual publish.
This seems to work in Visual Studio 2019
<Target Name="MyCustomTarget" AfterTargets="Publish">
<Copy SourceFiles="C:\A.txt" DestinationFiles="C:\B.txt" />
</Target>
You must define override the target at the end of your file, after <Import ... />
Launch MSBuild with detailed verbosity to see why your target is ignored :
msbuild project.csproj /t:Target_to_Launch /v:d
AfterPublish is called after Publish target, but Publish is not the target called when you publish a web application. Publish is the target for publishing ClickOnce application.
You'll have to find the target used when you call Publish in Visual Studio, it could be Package, WebPublish...
I'm a little lazy right now to figure out the mess of targets to find the right one for a file-based publish (which you might be interested in). What you can do in the meantime is defining an AfterBuild target in the *.pubxml file.
<Target Name="AfterBuild">
...
I recommend also turning off the property "DeleteExistingFiles" because if you copy files into the directories being published, it does a clean somewhere during the publishing process.
<DeleteExistingFiles>False</DeleteExistingFiles>