Stop SSDT being published when MSBuild publish run - msbuild

I have a ClickOnce project that I'm publishing on DevOps. I've set the MSBuild Arguments property for the WinForm solution's build stage in DevOps to /target:Publish in order to trigger the creation of all the ClickOnce files:
However, that solution also contains an SSDT project, and adding the /target:Publish setting appears to then cause the build process to try publish the SSDT too. That then fails with the error:
C:\Program Files (x86)\Microsoft Visual
Studio\2017\Enterprise\MSBuild\Microsoft\VisualStudio\v15.0\SSDT\Microsoft.Data.Tools.Schema.SqlTasks.targets(1808,5):
error MSB4044: The "SqlPublishTask" task was not given a value for the
required parameter "SqlPublishProfilePath"
Presumably it's failing because there's no publish profile specified in a build parameter for the SSDT to use.
I don't want MSBuild to publish the DacPac to a server, I just want it to create the DacPac. How can I stop the /target:Publish triggering the SSDT publish, is there another build argument I can add to stop that happening?
Notes on what I tried so far to solve this, none of which has worked:
Read about the -target switch in the MS Build official docs in the MSBuild command-line reference and in the MSBuild targets section.
Looked at the code in the .csproj file to try and identify the 'Publish' sections - think Publish must also call Build.
Unticking Deploy for the SSDTs in the solution configuration in VS
Adding entries for False in the Release and Deployment configurations in the SSDT's .csproj file, and also setting that to false for the Debug configuration (as per this question)
Setting MSBuild to only publish one project using the MS Build arguments on DevOps (as per this answer)
Considered pulling the ClickOnce publish out into an entirely separate stage using Mage.exe as per this Walkthrough: Manually deploy a ClickOnce application
Tried to create a publish profile that doesn't actually publish, so that the publish stage can complete (was looking at this question for ideas on that and also the official documentation for SqlPackage.exe)

Eventually I solved the issue above a completely different way. Instead of getting MSBuild to do what I wanted it to, I instead split the solution configuration in two, with one stage for the databases and one for the WinForms project without the databases.
I then used two separate VS Build stages on DevOps with only the WinForms stage still having /target:Publish set.
I've written that up here, but would still like to know the answer to whether it's possible to tell MSBuild not to build the SSDTs when the target is set to Publish?

Related

MSBuild deploy only - no build

Is there anyway to do the publish/deploy part of a /p:DeployOnBuild=true call to MSBuild? For instance, doing the build in one call, then the publish (file copy) in another call.
There is an issue with MSBuild 15 and publish profiles when called from command line.
A post on Github addressing the same concern raised by you has provided a solution.
You can find documentation on how to use PublishProfiles from
commandline here - https://github.com/aspnet/websdk#folder-publish
Here is a sample project with a PublishProfile:
https://github.com/vijayrkn/dotnetpublishprofilesample/blob/7dac43543173b4ce908921106cc84d810c6dc623/WebPublishCommandlineSample/Properties/PublishProfiles/SampleFolderProfile.pubxml
MSBuild command to publish to a folder using the above publish
profile:
https://github.com/vijayrkn/dotnetpublishprofilesample/blob/7dac43543173b4ce908921106cc84d810c6dc623/PublishCommandline.txt
I would be happy to take a look at the issue if some one can provide
me a sample project & msbuild command that is not working.
Source: https://github.com/Microsoft/msbuild/issues/1901#issuecomment-377140715
Hope it provides the needed information
Note: issue was fixed by Microsoft - https://github.com/dotnet/cli/pull/8996 as part of 2.1.3xx milestone

TeamCity config

We're pretty new to TeamCity at work. We have a build & deployment pckage setup which is using MSBuild/MSDeploy to ship changes to our web servers. However, we have a few issues (apologies for putting a few questions on the same post). For clarification our solutions looks like so:
Project Folder
WebApp (includes .csproj file. Includes a folder called "media" - this folder is not in SVN)
Libraries (includes referenced assemblies)
Our issues:
There is a specific folder within the Libraries folder that must be copied into the bin directory after build (because of an assembly redirect). We have always used a PostBuild event, however this doesnt work in TeamCity.
The folder "media" within the WebApp folder is not included in SVN. When the TeamCity package is executed it deletes this folder. I would like to prevent TeamCity from deleting just this folder.
When we run the TeamCity task, we get an ERROR_FILE_IN_USE error for one of the files teamcity is trying to delete during the sync task. I have read about using the app_offline.htm file to combat this - but quite how Im not sure.
I'm going to guess that some of these settings can be command line parameters in the msbuild job - I think it would be better to store these in the csproj file rather than just in teamcity if it is possible?
thanks in advance
Al
A few questions on the information provided
Can you clarify what you mean by post-build command doesnt work? Does it fail or does it just not do what you expect?
How have you setup your post-build command? does it reference specific filepaths? TeamCity executes MSBuild in the same was as you could from the command line or from visual studio.
Regarding the MSDeploy folder issue, you can configure MSDeploy with a Skip Action, here's a link to another post describing how to do this
Prevent MSDeploy (selectively) from deleting folders on target IIS server
Because MSDeploy is trying to deploy into a folder being used by IIS you are also seeing the file locking issue. There are two solutions
1. Add a teamcity step to stop IIS (using PowerShell) before deploying. This will cause downtime.
2. Deploy to a different folder and then switch IIS to point to your new folder. This is a much better solution as you also have roll back.
A much easier solution to all of this is to use a Deployment Tool such as Octopus Deploy to deploy your application. You can learn more about Octopus Deploy at http://octopusdeploy.com/

How can I pass MSDeploy-style parameters to MSBuild via the commandline?

I am setting up TeamCity to deploy our Website Project application (using a *.wdproj) and Web Deploy application to IIS.
I have a build configuration that uses MSBuild.exe with the MSDeployPublish to build and then deploy the application.
We now want to get the application to deploy to multiple target environments, therefore need a way to supply different settings based on the target environment.
I have added a parameters.xml file to the Web Deployment Project, and have verified that the parameters set in here are making all the way through the target IIS server and being correctly applied - great!
Now what I want to do is have different parameter settings per environment. I was hoping I could use something like the MSDeploy.exe -setParam argument to specify different values for each environment, however I can find no way to get my parameter values into MSBuild via the commandline.
I suspect I might need to do one of the following:
Split MSBuild and MSDeploy into separate build steps.
Configure a task somewhere in the pipeline to take 1 of n versions of parameters.something.xml and move it into parameters.xml so it gets picked up by the rest of the pipeline.
I'm looking for the simplest way to move ahead at this point, any suggestions welcome.
For reference, here is the command I'm experimenting with now:
msbuild /target:MSDeployPublish MySite_deploy.wdproj /P:Configuration=Debug
/P:DeployOnBuild=True /P:DeployTarget=MSDeployPublish
/P:MsDeployServiceUrl=www.myserver.com:8172/MsDeploy.axd
/P:AllowUntrustedCertificate=True /P:MSDeployPublishMethod=WMSvc
/P:CreatePackageOnPublish=True /P:UserName=MyUser /p:Password=MyPassword
/P:DeployIisAppPath=www.myserver.com/MySite
/P:ServerURL=http://www.tryingtoforcethis.com
It's working beautifully except the value for ServerURL, which is a parameter I've defined in my parameters.xml, is not making its way into the target site. The default I specified in parameters.xml, however, is. So I know that the parameters are working, I just can't figure out how to add them to the msbuild commandline.
Well, I think the short answer is that with MSBuild 4.0 and VS2010, you can't just pass arbitrary parameters into MSDeployPublish from the call to MSBuild.
I found these posts helpful:
http://forums.iis.net/t/1167657.aspx/1 - Ming Chen's comments
http://www.hanselman.com/blog/TinyHappyFeatures3PublishingImprovementsChainedConfigTransformsAndDeployingASPNETAppsFromTheCommandLine.aspx - the comments from Richard Szalay at the bottom
After reading these, and sifting through the Microsoft.Web.Publishing.targets file for some time trying to find a "way in", I finally settled on having multiple copies of Parameters.xml in my project folder in source control, labelled according to their environment eg:
Parameters.Test.xml
Parameters.Staging.xml
Parameters.Live.xml
Then, prior to the package and deploy, I just copy one of these files into Parameters.xml and it gets picked up by the rest of the pipeline - done!
BTW I had a temporary problem getting the parameters.xml copy and subsequent cleanup to work within a single MSBuild.exe call due to what seems to be some sort of file access issue, I've detailed it here:
MSBuild.exe Copy task not working properly unless a version of the file already appears in target
To answer your question, the parameterization of your command line is not a concern of MSBuild. Instead, you should utilize external tools. For example, if you run your msbuild command from a batch file you could pass the parameters to the batch file and run it for each environment with different parameters. Another approach is to use a build system like TeamCity or VSTS and utilize their parameterization mechanism. Adapted for the VSTS or TFS, your command could look like this:
msbuild MySite_deploy.wdproj /target:MSDeployPublish /p:Configuration=Debug
/p:DeployOnBuild=True /p:MsDeployServiceUrl=$(IIsHostNameIp)
/p:AllowUntrustedCertificate=True /p:MSDeployPublishMethod=WMSvc
/p:CreatePackageOnPublish=True /p:UserName=$(IIsUserName) /p:Password=$(IIsPassword)
/p:DeployIisAppPath=$(IIsSite)
In addition, I would suggest some clean up for your origianl command line:
Using both /p:target and /p:DeployTarget is redundant. Any one of them is enough. Also it could be replaced with /p:WebPublishMethod.
For /p:MSDeployServiceUrl it is enough to only provide a DNS name or IP. the port and the Url is automatically derived from the /p:MSDeployPublishingMethod=WMSVC.
The custom parameter /p:ServerURL is unknown and won't be mapped anywhere.
msbuild.exe {build-script.proj} /property:{someParameter=someValue}
In your build script you can use $(someParameter) as a variable

What parameters does TeamCity pass to MSBuild under the covers?

I just downloaded TeamCity 7 today and decided to get it up and running for my Azure solution. I am not trying to do anything fancy (yet) and started with a very basic command line build:
msbuild /t:Publish /p:Configuration=Release;TargetProfile=Production;PublishDir=S:\HoursTracker\Deployments
This builds successfully and produces a package that looks like this*:
I then attempted to configure TeamCity in an identical fashion:
This builds successfully and produces a package that looks like this*:
What I don't understand is why there is such a huge discrepancy in the size of the MVC project. Publishing directly from Visual Studio produces the exact same result as my MSBuild command so I'm convinced that TeamCity is the odd man out. Since I assume TeamCity is not broken, can someone please educate me on how to properly configure it so that I get the expected output?
*I have renamed the package files with .zip so that the details were viewable for this post.
Ming's answer helped me solve the mystery. After inspecting the contents of the zip files, I discovered the difference was that my MSBuild package contained bin and obj folders and the TeamCity package did not.
After making this discovery, I realized that I could specify multiple targets to MSBuild and prepended "Clean" to my targets switch like so:
msbuild /t:Clean;Publish /p:Configuration=Release;TargetProfile=Production;PublishDir=S:\HoursTracker\Deployments
As expected, this removed those folders. So apparently, TeamCity specifies "Clean" implicitly for you. Mystery solved.
Windows Azure packages may be larger than we expect. You can rename the cssx file to zip and you will find out what’s inside the package. In addition to the web application’s usual files, there’re a bunch of Windows Azure files. For example, if you enable diagnostics, you will see a diagnostics folder, where you’ll find files used by Windows Azure diagnostics runtime.
Best Regards,
Ming Xu.
Why you specified x64 for msbuild runner? Try selecting tools version as well. You have not specified /p:Platform parameter. Does publish task involve rebuild?
TeamCity starts msbuild with number of /p: parameters taken from " properties and environment variables " section, plus some well-known parameters like configuration name or project name.

How to create a TFS2010 Team Build Template for getting source and call msbuild.exe

I have a build.proj, that is a MSBuild file and can be run locally.
All I need from TFS is
Get the sources from TFS Source Control.
Call "MSBuild.exe /t:Deploy".
Update the build status based on the result of MSBuild.
I have tried to make a template combining the DefaultTemplate.xaml and UpgradeTemplate.xaml.
But so far, no luck :-(
Can someone help me make this template?
If you select the upgrade template that comes out of the box when you create a new TFS project with 2010, you can supply your old TFS2008 proj (MSBuild) file without problems. Please read http://msdn.microsoft.com/en-us/library/dd647553.aspx for more details.
You should use DefaultTemplate. I had the same problem and I solved it this way.
You can do it using UpgradeTempate also, but using DefaultTemplate was easier for me.
On Process section follow these steps:
Select Default template
Add your project into Items To Build collection
Set MSBuild Arguments (Advanced section) to "/t:Deploy"
I have MSBuild project file for running builds locally. This script is used also for sever builds. I have three MSBuild projects in Items To Build collection. One for PreBuild step (some checks before build is executed), main build script used also for local build and the last script for additional post build tasks (deploy process). I'm setting additional MSBuild propertires like IncrementalBuild and ServerBuild properties in MSBuild Arguments.