Web Deploy: how do I include specific files in a webdeploy package? - webdeploy

I am transitioning my web application solution from xcopy deployment to Web Deploy deployment.
I have a PostBuild action that generates files the web app needs at runtime.
I want to use the 'Only files needed to run this application' option.
The generated files are, of course, not in the solution - which means that they don't get picked up by the setting above (which I want to use in order to avoid a long, long, ugly list of files-to-exclude). I know that there's a way to exclude files and folders explicitly, but is there a way to include files explicitly?

Sayed Ibrahim Hashimi would seem to disagree with the current answer.
http://sedodream.com/2010/05/01/WebDeploymentToolMSDeployBuildPackageIncludingExtraFilesOrExcludingSpecificFiles.aspx
According to this article you can modify the project file / create your own targets file that will include a specific file or folder by tying into the current build pipeline.

No such mechanism exists. The best practice is to set up the aforementioned long list of exclusions, and use the "all files" option.

Related

MSBuild shared .targets file

I have several .csproj files that I will be importing a common .targets file into, to extend the build process. The projects are in different directories. The .targets file is in the solution directory. How do I refer to the location of the .targets file to import it? There's a solution directory property, but this doesn't work if the developer just builds a project. What do I do? I am using .NET 4.5 and Visual Studio 2015.
As you figured a project doesn't know about a solution it's contained in, and arguably it shouldn't. So there's not much you can do to programmatically figure out where, from the project's point of view, a totally unrelated file is situated. Apart from scanning the entire filesystem for it. There are some alternatives:
rely on a proper directory structure. You do this already anyway, since you use a solution which also needs to find projects in a fixed location. So suppose you have a main project dir with projectA/a.vcxproj, projectB/b.vcxproj and solutionDir/ab.sln and solutionDir/my.targets then in a and b just <Import Project="$(MSBuildProjectDirectory)..\solutionDir\my.targets"/>
require a property (or environment variable) which is set to the location of the targets file and then use <Import Project="$(SomeDir)\my.targets"/>
put your targets file in a 'known' msbuild location like the Importbefore/ImportAfter directories, mentioned here for instance.
I've used all of these at one point and in the end the first is in my opinion the better one: you just have to stick with a directory convention - you need that anyway for projects spanning mulriple directories or with common shared stuff - and that's it. For example we have a ton of common msbuild files and they're in a single repository. Starting a new project always comes down to creating a directory, cloning the common files dir and adding a new project dir. That can it turn easily be automated, also works well on typical CI servers. The second option is also doable, but it relies on a properly setup environment which is less 'self-contained' and gets really messy if developpers start entering the variable in the machines' global environment variable settings, and in the local ones, and so on. Similar problems with the third one but worse since now there's only one correct location.

Exclude folder when building from VSO to Azure website

I am trying to exclude certain files/folders from deployment of a web project in Visual Studio Online to an Azure website.
The web project has a Content folder with CSS, JS, build scripts and so on, which are only necessary for development, once deployed to Azure the CSS and JS is loaded from a CDN. Currently the build from VSO is copying all those files to the webroot in Azure, which is unnecessary and a potential security issue in case of the build scripts.
Now I know this can be prevented by setting the build action of a file to None, but this a very tedious solution because there is a lot of development going on, new files get added all the time and it is easy to forget this setting.
First I tried setting the Content folder to Cloaked in the build definitions source settings, but this only causes VSO to not download this folder on build, msbuild will still complain that those files are missing.
Is there a way to tell msbuild to ignore the whole Content folder? I already tried adding /p:ExcludeFoldersFromDeployment="Content" as a msbuild argument in the build definition, and also tried the solutions in here How to get Visual Studio 'Publish' functionality to include files from post build event?, but nothing is working.
I was studying msbuild log files and came up with a solution that is good enough for us to work with.
The first thing I learned was that I cannot prevent msbuild from copying files with build action Content to the output directory, at least not without changing the Microsoft.WebApplication.targets file, which I didn't want to do and am not even sure is possible with VSO build.
Anyway because of this we cannot set the source settings of our Content folder to Cloaked in the build definition, since this will cause the build to fail.
What we ended up doing was described in this answer: https://stackoverflow.com/a/3140349/1230302
So by adding the ExcludeFoldersFromDeployment statement to the .csproj file, the Content folder is excluded from the webroot.
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|AnyCPU'">
<OutputPath>bin\</OutputPath>
<ExcludeFoldersFromDeployment>Content</ExcludeFoldersFromDeployment>
</PropertyGroup>
It is not an ideal solution, but at least this way nothing gets deployed if a developer forgets to set the build action to None.
The built in continuous delivery options are designed for convenience. Of you need something custom, like skipping deployment of files that have not changed, then you will need to write something yourself.
You can easily call PowerShell to complete any task from the build process.
If you'd like to customize your build as part of the VSO build system, you can just override your BuildTemplate.xaml file.
Visual Studio Build uses Windows Workflow (xaml) to make a workflow on what the build is supposed to do. You can edit this file and do any modifications to the directory structure before or after the build.
Here is an example.

TFS Build dropping extra files including csproj in target folder

I have an automated build process set up to run from a build definition in TFS, which publishes a web application and generates/executes a database project script successfully via publish profiles that are passed as msbuild arguments in the build process definition. Everything is now running as expected except that several unnecessary files are being deployed to the target folder, including the .csproj file, all of the config transforms, and the properties folder which contains all of my publish profiles.
This is strange because 1. It's definitely not including ALL files/folders and mostly appears to be including ones used by the publish profile like transforms, while applying the transform correctly and excluding any explicitly excluded file (as defined in the pubxml), and 2. The process works perfectly if I do it by publishing from the project in Visual Studio 2013. I have the profile configured to only include files needed by the application, and I've confirmed in the csproj file that this property is there.
I tried excluding the properties folder from deployment in the pubxml file, but this causes the build to crash because it can't find the assembly file. What I've gathered is that the process is keeping all files it needs to complete the build, and dropping all of those files in my destination folder. FWIW, I'm using the "file system" method and I'm not sure yet if web deploy will make a difference. I haven't been able yet to connect to the target server with web deploy, but that's a separate problem to solve. Is there something in the build that I can configure so that my destination folder has only the files it needs to run the application, and not the files needed to BUILD the application?
FYI I also have not been using a drop folder, I'm not sure if that makes a difference or not but that might be the only thing I haven't tested as it doesn't seem necessary since I'm using a publishprofile and don't want to use the default tfs build configuration.
I found a solution that works well enough, after reading this: http://www.asp.net/web-forms/tutorials/deployment/advanced-enterprise-web-deployment/excluding-files-and-folders-from-deployment
This was a little uglier solution than I wanted, since it requires hard-coding the names of excluded files, but it does the trick and only requires identifying the files and folders in one location instead of altering a publish profile for each target environment. I created a wpp.targets file and used the ExcludeFromPackageFolders and ExcludeFromPackageFiles elements to identify the extra files. Ironically, if I don't also name the wpp.targets file in the exclude element, THAT file is included in my package. It's possible MSDeploy doesn't have the same issues with TFS as filesystem, but after spending half a day trying to work through a different set of issues and permissions workarounds, we decided that file system is a cleaner publishing method.

Put file into specific directory when check in into TFS - Continuous Integration

I try to set up a MSBuild-project that will copy the file(s) that are being checked in into TFS (2010) to a specific directory at the Build-server (or share).
I have the Build Definition as a Continuous Integration, but how can I get to the specifics files I am checking in, and copy only those to the directory?
(The best would be If only inchecked *.sql-files should be copied, but if all files I am checking in goes there It's ok. I can manage it from there.)
Does anybody know how to only copy the chosen files?
By default there is no way to do this. There is no standard out-of-the-box build activity that does this for you.
What you can do is to create a small Custom Build Activity that checks which ChangeSets are associated to your build. Then use teh VersionControlServer class int he TFS Client Object Model (specifically the DownloadFile method) to download the changed files in these changesets and save them to wherever you want. Remember to pass in the VersionSpec you can use the c##### changeset number format.
If you just want the files that are in the Builds workspace you need to do a few more things (checking the Workspace Mapping of the Build Definition).
See also:
Microsoft ALM Rangers Build Customization Guide
Community TFS Build Extensions
The GetChangeSet activity in the TFS Build Extensions should provide a great starting point.

I would like to have my AssemblyVersion in my deployment package name

I am using MSbuild to create a deployment package (simply copying various files from the projects in my solution to different folders) I would like the root folder to be of the format
DeploymentPackage2.3.4.5ForRelease
How can I get MSbuild to put the Assembly number in the folder name automatically?
EDIT:
The solution has a great deal of projects in it (too many really) they all get their version number from a SharedAssemblyInfo.cs file that is manually updated but in the fullness of time will pick up the svn build number (but that is a job for later)
I am building using an external .bat file that calls a custom written .targets/.proj setup that simply calls msbuild on the .sln of the solution.
The 'create package' step I am trying to create happens after a succesful build and will eventually be run by our CI framework, however I would like to be able to run it locally too.
I have created a "CreatePackage" target that does the copying that I want, however it is currently into a fixed folder. I need the folder name to reflect the AssemblyVersion of one of the final dll's.
If there is a better way then I want to know about it... but I am going to use this I think
MSBuild Task to read version of dll