How do I copy the Release folder contents to a secondary location? - msbuild

I am brand new to using TeamCity.
I have my .NET C# application building via a MSBuild "build step" in TeamCity. Once it is built, I would like TeamCity to copy the entire contents of the "Release" folder to a secondary location where we keep current and recent builds.
I cannot build to this location directly because there are other files which my application requires (databases, XML config files, etc..) that reside permanently in the Debug and Release folders. I know this is horrible and I would need a soapbox to complain about the decisions my predecessor made, but for not I am forced to keep that portion as-is.

You can add a command line build step with a simple xcopy command.
It will be executed only when every previous build step succeeds.

Related

Why is building two targets with msbuild different from building each target separately?

I have a project that imports a certain targets file from a Nuget package. Even though I use PackageReferences I am forced to import this file manually.
(See my other question for details - How are we supposed to execute package build targets in the new world where nuget packages are consumed through msbuild PackageReference?)
This targets file injects chromedriver.exe into the Content item group with CopyToOutputDirectory = PreserveNewest.
I observe a situation where chromedriver.exe is not copied to the bin folder when running msbuild /t:"Restore;Build", but it is copied when running the two targets separately - msbuild /t:Restore; msbuild /t:Build.
Can anyone explain how this happens?
(I killed a good portion of the day learning the difference on my skin, want to know how come?)
Restore changes the imported project files in the obj\ directory.
For this to take effect, the project file needs to be re-evaluated entirely, which does not happen when you run the Restore and Build targets in the same invocation.
Use the -restore command line switch for MSBuild to run a Restore before the other specified targets in the same command line call. MSBuild will run the Restore, empty its XML caches and re-evaluate the project again when running the requested build.

Erratic file naming of *.dacpac files when building a *.sqlproj SSDT project on a TeamCity 7 build server

We have an MSBuild task that builds our *.sqlproj file, the output of which is loaded back into TeamCity as an artifact for subsequent deployment.
Similar to this user, we are having some unpredictable output file naming happen:
Invalid file names when trying to deploy SSDT project with TeamCity 8
It appears that sometimes, it produces this output file under /bin/Release:
MyProj.sqlproj.dacpac
Then subsequent builds produce this file in the same folder:
MyProj.dacpac
We haven't done indepth testing yet - I was wondering if anyone else has seen similar or has a suggested troubleshooting path?
To be clear, it's the same task, running the same command against the same project - just run repeatedly overtime as new checkins happen.
Sounds like you have conflicting .sqlproj files being checked in.
I'd start by checking the history.
Well, after looking more closely at the build log I could see that the TeamCity MSBuild runner appears to be creating some temporary virtual project files (or something, I don't know for sure because they get deleted) with names like:
MyProj.sqlproj.teamcity
I theorized that this may be confusing MSBuild or one of the targets related to building dacpacs, so I replaced the TeamCity MSBuild build step with a Command Line build step that calls MSBuild on the original project file itself, and this appeared to solve the problem. It now produces the dacpac with the file I'm expecting.
I don't have time to dig further now, but I could believe that there's some logic in the chain somewhere that is deriving the name for the final *.dacpac from the name of the project file being used. My guess is that it just strips off everything after the last "." and attaches the ".dacpac" suffix.
I don't fully know why it would occasionally create a *.dacpac file with the correct name, but I was at times doing a manual build in the TeamCity agent work folder from the commandline on the build server itself, so this may have just been a file leftover from previous executions.

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.

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

TFS 2010 Build Publish via file system

I've got a fairly large MVC2 project in TFS which gets built automatically on checkin (Continuous Integration)
At present, the fully built version is dumped on a network share on our dev IIS server. \\Server\wwwrootLatest
TFS of course creates lots of sub-folders since it's just doing a build, it isn't even aware that it's drop directory is a wwwroot.
This means that to actually USE the build, we need to go and manually create an IIS App which points at the appropriate directory - which defeats the whole object of the exercise.
When we do a manual publish to that server, we use "File System" as the method and just overwrite the files in the UNC share \\Server\wwwroot
(When publishing to other environments, we use full-on MSDeploy.)
What I'd like to do is convince TFS to do a "File system" publish after the build completes and duplicate what we do on a manual publish eg:
Drop directory is \\Server\Build which would result in something like \\Server\Build\Project\Date.Rev\
After that is complete, we want it to publish to \\Server\wwwrootLatest - we can then set up the App once which will always contain the latest version but will still have a full history if required.
The only examples I've been able to find use MSBuild commands in the build definition (fine) but all use MSDeploy to do a full-on publish. I'm not sure how to automate what I want to do
Any help appreciated.
In your drop folder a folder named _PublishedWebsites is generated automatically. It contains files you need to put in wwwroot. You can use CopyDirectory build activity to copy them automatically.