Why Unpublishable? - msbuild

We have a solution that contains 17 projects.
Solution has several configurations such as Debug, Release, Test, Publish and etc.
Also team project has several build definitions, each one is specialized for a configuration.
We use Release configuration build for nightly builds and Publish configuration build for publish and deployment.
So these build definitions, build same source code. But there is a problem...
Our nightly build creates obj\Release directories for each project but publish build doesn't.
Because of this publish build doesn't create server publish package.
When I looked to the build logs I saw the differences like below.
Nightly build - Release configuration (for each project)
PrepareForBuild:
Creating directory "obj\Release\".
Publish build - Publish configuration (for each project)
_DeploymentUnpublishable:
Skipping unpublishable project.
But I couldn't understand why?
Which flag controls this?
We are using TFS 2010, so Team Build 2010.

Try adding the following deployment settings to the project file inside the property group for the build configuration you want to publish:
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
...
<FilesToIncludeForPublish>OnlyFilesToRunTheApp</FilesToIncludeForPublish>
<DeployOnBuild>true</DeployOnBuild>
<DeployTarget>Package</DeployTarget>
<PackageAsSingleFile>true</PackageAsSingleFile>
</PropertyGroup>
I was getting a similar error on a web project's CI build. Adding the deployment settings to the web.csproj file corrected it.

Related

Include additional files in build using MSBuild

In the past we have used a combination of TeamCity and MsDeploy to deploy our projects. We've recently moved into using Octopus deploy, and TeamCity purely for the Build. This meant changing the build process in TeamCity and removing any references to MsDeploy.
In the past we've used confiiguration such as the below in our project file which included additional files and directories:
<PropertyGroup>
<CopyAllFilesToSingleFolderForPackageDependsOn>
CustomCollectFiles;
$(CopyAllFilesToSingleFolderForPackageDependsOn);
</CopyAllFilesToSingleFolderForPackageDependsOn>
<Target Name="CustomCollectFiles" BeforeTargets="BeforeBuild">
<ItemGroup>
<UCommerceAssemblies Include="$(MSBuildThisFileDirectory)..\..\Resources\UCommerce\ucommerce\*" />
<FilesForPackagingFromProject Include="%(UCommerceAssemblies.Identity)">
<DestinationRelativePath>bin\uCommerce\%(Filename)%(Extension)</DestinationRelativePath>
</FilesForPackagingFromProject>
</ItemGroup>
However this now doesnt seem to get invoked whatsoever. It appears (to me anyhow) that these pipelines were created for use with Publishing from Visual Studio, or using MSDeploy, however we need to just include these files in the directory either before or after the build has taken place. There seems to be tons of references across the web about doing this, however they all refer to using MSDeploy.
Can anyone shed any light on how I can include additional files/directories in the build without using MSDeploy?
Thanks for your time in advance
dotdev
As you are using Octopus for deployment you only need to include additional files (reference assemblies, etc.) into code package sent to Octopus.
To do this one needs to use OctoPack for project packaging. Then add .nuspec file into the project, for example this line in .nuspec will add all files from some different location into the .nupkg package under "bin\additional" and will be deployed correctly by octopus.
 
Nuspec docs
Similar solution is discuses here.

MSBuild - how to force "AfterBuild" target when I do deployment?

I have the following setup: ASP.Net MVC .Net 4.0 solution with 5 projects in it, and several solution configurations (Site1-Stage, Site1-Live, Site2-Stage, etc). The reason for this is simple - we deploy same codebase to multiple servers with different config settings.
To manage these configurations, I use the approach described by Troy Hunt in his You're deploying it wrong! TeamCity, Subversion & Web Deploy part 1: Config transforms article. In 2 words - I do NOT have web.config in my SVN repo, instead I have Web.Base.Config, Web.Site1-Stage.Config, etc and XmlTransformation task in project AfterBuild target. During the build, the required web.config is generated based on selected configuration:
<UsingTask TaskName="TransformXml" AssemblyFile="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v10.0\Web\Microsoft.Web.Publishing.Tasks.dll" />
<Target Name="AfterBuild">
<TransformXml Source="Web.Base.config" Transform="Web.$(Configuration).config" Destination="Web.config" StackTrace="true" />
</Target>
Here comes the problem: when I'm execute MSBuild like this:
msbuild MySolution.sln /P:configuration=Site1-Stage /t:rebuild
all goes well, web.config is properly generated for the Site1-Stage configuration. However, if I run this command:
msbuild MySolution.sln /P:configuration=Site1-Stage /t:rebuild /P:DeployOnBuild=True
I get the following error:
"MySolution.sln" (rebuild target) (1) -> "MySolution\MyWebProj.csproj"
(Rebuild target) (3) -> (PreTransformWebConfig target) -> C:\Program
Files
(x86)\MSBuild\Microsoft\VisualStudio\v10.5\Web\Microsoft.Web.Publishing.targets(1399,5):
error : Copying file Web.config to
obj\Site1-Stage\TransformWebConfig\original\Web.config failed. Could
not find file 'Web.config'. [MySolution\MyWebProj.csproj]
I tried to explicitly add "AfterBuild" target into MSBuild command line:
msbuild MySolution.sln /P:configuration=Site1-Stage /t:rebuild,AfterBuild /P:DeployOnBuild=True
but it resulted in the same error.
Why do I need this: it's a very isolated example, and in reality I'm trying to setup automated publishing from TeamCity CI server. I think if I add new build step with "Visual Studio (sln)" runner BEFORE my current publishing step, that would work, it will first rebuild the project (and generate web.config) - and then publish. However, i have lots of publishing steps (around 20 now) and I would like to avoid that. My understanding is that "Publish" process does the build as part of it, so I would like to "reuse" that.
Question is: how should I modify my MSBuild command line to force config transformation to happen?
Thank you.
Maybe use "BeforeBuild"?
BTW do you have web.config included in csproj? I believe most publish activities relies on items in project rather than in folder. You can include web.config in project, while still have excluded it from source control.

TeamCity Build Failure

I have tried many things today to get my build to work in Teamcity but to no avail.
Here is my setup.
I have 2 build configurations in TeamCity
Build Solution
Build Deployment Package Debug
Build Solution is triggered by an SVN checkin and builds the solution file. This configuration works fine.
Build Deployment Package Debug has Build Solution as its dependency and has two (MSBuild) build steps. The solution contains two websites: a front end one and an admin one. One build step builds the front end site and the other the admin site. The end result is that it puts the combined results into a zip file for deployment to the deployment server (I've not got to this bit yet).
The problem that I have is that the Build Deployment Package Debug configuration fails trying to build the first site. This is the error:
[18:40:25]Step 1/2: Web (MSBuild) (29s)
[18:40:28][Step 1/2] x.Web\x.Web.csproj.teamcity: Build target: Build (27s)
[18:40:50][x.Web\x.Web.csproj.teamcity] MvcBuildViews (4s)
[18:40:50][MvcBuildViews] AspNetCompiler (4s)
[18:40:55][AspNetCompiler] C:\BuildAgent\work\252ec59002ecc2d\x.Web\obj\debug\csautoparameterize\original\web.config(39, 0): error ASPCONFIG: It is an error to use a section registered as allowDefinition='MachineToApplication' beyond application level. This error can be caused by a virtual directory not being configured as an application in IIS.
[18:40:55][x.Web\x.Web.csproj.teamcity] Project x.Web\x.Web.csproj.teamcity failed.
[18:40:55][Step 1/2] Step Web (MSBuild) failed
Here are Build Paramters -> System Properties
Name Value
system._PackageTempDir c:\deploypackage
system.Configuration Debug
system.CreatePackageOnPublish True
system.DeployIisAppPath Debug
system.DeployOnBuild True
system.PackageLocation c:\buildshares\Debug\Debug.zip
Here's what I did to solve this
I already had this in my project file
<Target Name="MvcBuildViews" AfterTargets="AfterBuild" Condition="'$(MvcBuildViews)'=='true'">
<AspNetCompiler VirtualPath="temp" PhysicalPath="$(WebProjectOutputDir)" />
</Target>
But I needed to add this also
<Target Name="AfterBuild">
<RemoveDir Directories="$(BaseIntermediateOutputPath)" />
</Target>
Doing this fixed the issue.
I hope this helps someone else who is working on TeamCity in the future.

Team Foundation Server 2010 - build configuration not set for project

(I´ve updated the title, to reflect my new findings)
I've just ported a bunch of projects from TFS2008 to TFS2010 and have run into a (actually several :)) problem with a specific project. When compiling with build configuration 'Debug', everything works as expected. However when compiling with build configuration 'Release' I get a linker error, due to al.exe cannot find the specified file in 'obj\debug'.
Error:
Task "AL" (TaskId:781)
...
ALINK : error AL1047: Error importing file 'c:\Builds\23\...\obj\Debug\someproject.exe' -- The system cannot find the file specified. [C:\Builds\23\...\Release\Sources\...\someproject.csproj]
The command exited with code 1. (TaskId:781)
Done executing task "AL" -- FAILED. (TaskId:781)
I've enabled the team build info diagnostic logging and found the following variable:
IntermediateOutputPath = obj\Debug\
My question is why would the linker look in the Debug folder, when I'm building under the release configuration. I've inspected the solution and project configuration and there are no 'Debug' configurations under the release solution configuration. Any ideas why this is happening and how to resolve it?
Thanks in advance.
!! Bonus info
I have the following statement in the project file that is failing, assuring if the build configuration is unspecified, it will be set to Debug.
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
I've tried to change it to Release as default and now my debug team build fails, pointing at obj\release instead. So it seems that the build configuration is unspecified, when the project is compiled. How can this be?
Found the problem. I have to set the build configuration explicitly for my publish target defined in the someproject.csproj project file. I've inserted the line 'Configuration=Release'
<MSBuild ToolsVersion="3.5" Projects="$(SolutionRoot)\...someproject.csproj"
Properties="RunCodeAnalysis=false;
Configuration=Release;
ClrVersion=2.0.50727.0;
ApplicationVersion=$(VersionNumber);
UpdateUrl=$(DevtestUpdateUrl);
InstallUrl=$(DevtestInstallUrl);
IsWebBootstrapper=true;
PublishDir=$(DropLocation)\$(BuildNumber)\Publish\Update\;
SolutionDir=$(SolutionRoot)\Kl******\;
DeploymentConfiguration=devtest;
SignManifests=true;
ManifestCertificateThumbprint=23...23;"
Targets="PublishOnly" />

How do I specify the platform for MSBuild?

I am trying to use MSBuild to build a solution with a specified target platform (I need both binaries, x86 and x64). This is how I tried it:
C:\WINDOWS\Microsoft.NET\Framework\v3.5>MsBuild SolutionPath\Solution.sln /t:Rebuild /p:Configuration=Release /p:Platform="x86"
However the build always fails if the platform is different from "Any CPU". What am I doing wrong?
This is the while output MSBuild prints:
C:\WINDOWS\Microsoft.NET\Framework\v3.5>MsBuild
SolutionPath\Solution.sln /t:Rebuild
/p:Configuration=Release
/p:Platform="x86" Microsoft (R) Build
Engine Version 3.5.30729.1 [Microsoft
.NET Framework, Version
2.0.50727.3082] Copyright (C) Microsoft Corporation 2007. All rights
reserved.
Build started 1.7.2010 8:28:10.
Project "SolutionPath\Solution.sln" on
node 0 (Rebuild targe t(s)).
SolutionPath\Solution.sln : error
MSB4126: The specified sol ution
configuration "Release|x86" is
invalid. Please specify a valid
solution c onfiguration using the
Configuration and Platform properties
(e.g. MSBuild.exe Solution.sln
/p:Configuration=Debug
/p:Platform="Any CPU") or leave those
prope rties blank to use the default
solution configuration. Done Building
Project "SolutionPath\Solution.sln"
(Rebuild t arget(s)) -- FAILED.
Build FAILED.
"SolutionPath\Solution.sln" (Rebuild
target) (1) ->
(ValidateSolutionConfiguration target)
-> SolutionPath\Solution.sln : error MSB4126: The specified s olution
configuration "Release|x86" is
invalid. Please specify a valid
solution configuration using the
Configuration and Platform properties
(e.g. MSBuild.ex e Solution.sln
/p:Configuration=Debug
/p:Platform="Any CPU") or leave those
pro perties blank to use the default
solution configuration.
0 Warning(s)
1 Error(s)
Time Elapsed 00:00:00.03
If I try to build it for x86/x64 with devenv it works perfectly, however I am trying to set up a build server without installing all the necessary versions of Visual Studio. By the way, if there is a better free tool (that supports .NET framework 4) out there, I'd love to hear about it.
In MSBuild or Teamcity use command line
MSBuild yourproject.sln /property:Configuration=Release /property:Platform=x64
or use shorter form:
MSBuild yourproject.sln /p:Configuration=Release /p:Platform=x64
However you need to set up platform in your project anyway, see the answer by Julien Hoarau.
If you want to build your solution for x86 and x64, your solution must be configured for both platforms. Actually you just have an Any CPU configuration.
How to check the available configuration for a project
To check the available configuration for a given project, open the project file (*.csproj for example) and look for a PropertyGroup with the right Condition.
If you want to build in Release mode for x86, you must have something like this in your project file:
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
...
</PropertyGroup>
How to create and edit the configuration in Visual Studio
(source: microsoft.com)
(source: msdn.com)
(source: msdn.com)
How to create and edit the configuration (on MSDN)
If you're trying to do this from the command line, you may be encountering an issue where a machine-wide environment variable 'Platform' is being set for you and working against you. I can reproduce this if I use the VS2012 Command window instead of a regular windows Command window.
At the command prompt type:
set platform
In a VS2012 Command window, I have a value of 'X64' preset. That seems to interfere with whatever is in my solution file.
In a regular Command window, the 'set' command results in a "variable not defined" message...which is good.
If the result of your 'set' command above returns no environment variable value, you should be good to go.
Hopefully this helps someone out there.
For platform I was specifying "Any CPU", changed it to "AnyCPU" and that fixed the problem.
msbuild C:\Users\Project\Project.publishproj /p:Platform="AnyCPU" /p:DeployOnBuild=true /p:PublishProfile=local /p:Configuration=Debug
If you look at your .csproj file you'll see the correct platform name to use.
For VS2017 and 2019... with the modern core library SDK project files, the platform can be changed during the build process. Here's an example to change to the anycpu platform, just before the built-in CoreCompile task runs:
<Project Sdk="Microsoft.NET.Sdk" >
<Target Name="SwitchToAnyCpu" BeforeTargets="CoreCompile" >
<Message Text="Current Platform=$(Platform)" />
<Message Text="Current PlatformTarget=$(PlatformName)" />
<PropertyGroup>
<Platform>anycpu</Platform>
<PlatformTarget>anycpu</PlatformTarget>
</PropertyGroup>
<Message Text="New Platform=$(Platform)" />
<Message Text="New PlatformTarget=$(PlatformTarget)" />
</Target>
</Project>
In my case, I'm building an FPGA with BeforeTargets and AfterTargets tasks, but compiling a C# app in the main CoreCompile. (partly as I may want some sort of command-line app, and partly because I could not figure out how to omit or override CoreCompile)
To build for multiple, concurrent binaries such as x86 and x64: either a separate, manual build task would be needed or two separate project files with the respective <PlatformTarget>x86</PlatformTarget> and <PlatformTarget>x64</PlatformTarget> settings in the example, above.
When you define different build configurations in your visual studio solution for your projects using a tool like ConfigurationTransform, you may want your Teamcity build, to build you a specified build configuration. You may have build configurations e.g., Debug, Release, Dev, UAT, Prod etc defined. This means, you will have MSBuild Configuration transformation setup for the different configurations. These different configurations are usually used when you have different configurations, e.g. different database connection strings, for the different environment. This is very common because you would have a different database for your production environment from your playground development environment.
They say a picture is worth a thousand words, please see the image below how you would specify multiple build configurations in Teamcity.
In the commandline input text box, specify as below
/p:OutputPath=Publish;Configuration=Dev
Here, I have specified two commandline build configurations/arguments OutputPath and build Configuration with values Publish and Dev respectively, but it could have been, UAT or Prod configuration. If you want more, simply separate them by semi-colon,;
There is an odd case I got in VS2017, about the space between ‘Any’ and 'CPU'.
this is not about using command prompt.
If you have a build project file, which could call other solution files. You can try to add the space between Any and CPU, like this (the Platform property value):
<MSBuild Projects="#(SolutionToBuild2)" Properties ="Configuration=$(ProjectConfiguration);Platform=Any CPU;Rerun=$(MsBuildReRun);" />
Before I fix this build issue, it is like this (ProjectPlatform is a global variable, was set to 'AnyCPU'):
<MSBuild Projects="#(SolutionToBuild1)" Properties ="Configuration=$(ProjectConfiguration);Platform=$(ProjectPlatform);Rerun=$(MsBuildReRun);" />
Also, we have a lot projects being called using $ (ProjectPlatform), which is 'AnyCPU' and work fine. If we open proj file, we can see lines liket this and it make sense.
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|AnyCPU'">
So my conclusion is,
'AnyCPU' works for calling project files, but not for calling solution files,
for calling solution files, using 'Any CPU' (add the space.)
For now, I am not sure if it is a bug of VS project file or MSBuild.
I am using VS2017 with VS2017 build tools installed.
In Visual Studio 2019, version 16.8.4, you can just add
<Prefer32Bit>false</Prefer32Bit>