5

I am working on writing some new build scripts for a few of our applications, the current scripts build all projects in place with MSBuild and then manually copy all of the content (views, scripts, etc...) and the bin folder manually to an artifacts folder to be zipped; this requires that all files and folders that aren't part of the bin directory for an ASP.NET project to be explicitly listed in a configuration file which is of course immensely error prone.

Is there a way using MSBuild when specifying the output directory to also include the content files? Ideally this would be done without creating a publish profile as the current deployment method is not open to change so I need to make sure my build artifact matches the current one.

If it helps I am planning to use Cake for the build mechanism.

Rob
  • 26,989
  • 16
  • 82
  • 98
  • You can use a post-build event to archive this. Something like [this](http://stackoverflow.com/questions/834270/visual-studio-post-build-event-copy-to-relative-directory-location)? And just out of curiosity, are you doing that as part of a CI process? – dnlgmzddr Aug 06 '15 at 22:59
  • It will be utilized by teamcity but should also be runnable on the dev machine. –  Aug 06 '15 at 23:00
  • I don't believe that will work as the output directory (bin folder) does not contain the ASP.NET content, the content all remains in the solution directory and a copy of that folder would of course also get the source code. –  Aug 06 '15 at 23:03
  • Ok, great because you can use the publish profiles for the ASP.NET application and make it production ready (remove debug flags), and specified the final destination path. – dnlgmzddr Aug 06 '15 at 23:04
  • As stated in the question I cannot use publish profiles as we have a custom deployment engine that cannot currently be deviated from. TO get more specific the zip file that i need to output has a very specific structure that I cannot reproduce with a publish profile. –  Aug 06 '15 at 23:11
  • I'm pretty sure that msbuild will copy all files which are included in the project file and have the setting `Copy to Output Directory` properly configured. Can you not just use this? – Rob Aug 06 '15 at 23:15
  • @Rob, unless I'm missing somethign that would require almost exactly the manual configuration I have now just in a different place I would need to explicitly define what files are to be copied to the output directory. –  Aug 06 '15 at 23:22
  • http://stackoverflow.com/questions/7643615/how-can-i-get-msbuild-to-copy-all-files-marked-as-content-to-a-folder-preservin looks promising –  Aug 06 '15 at 23:24
  • @Phaeze That's right, but anything being referenced *should typically* be included in the project anyway. VS will give you warnings if you reference a script/file that's not present in the solution. – Rob Aug 06 '15 at 23:56

1 Answers1

3

Utilizing cake I was able to come up with a somewhat messy solution :

var excludedFiles = new List<string>{"Settings.settings", "packages.config"};
var artifactDir = "./Artifact";
var solutionFile = "./MySolution.sln";

Task("Package")
    .IsDependentOn("Build")
    .Does(() =>
    {
        var solution = ParseSolution(solutionFile);
        foreach (var project in solution.Projects)
        {
            var parsedProject = ParseProject(project.Path);
            var binDir = project.Path.GetDirectory() + Directory("/bin");

            if(project.Name.Contains("Host"))
            {             
                var soaDir = Directory(artifactDir + "/SOA");
                CreateDirectory(soaDir);
                CopyDirectory(binDir, soaDir + Directory("bin"));
                foreach(var file in parsedProject.Files)
                {
                    if(!file.Compile && excludedFiles.All(x=> !file.FilePath.ToString().Contains(x)))
                    {                        
                        var newFilePath = soaDir + File(file.RelativePath);
                        CreateDirectory(((FilePath)newFilePath).GetDirectory());
                        CopyFile(file.FilePath, newFilePath);
                    }
                }
            }
        }        
    });

The package task here will parse in the solution a loop through the projects to find any that contain the word Host is their names; this is how all of our web apps are named so for us it is safe but could definitely be improved.

Once we've identified the ASP.NET project we copy its bin contents and then loop through its files to find any that are not marked for compilation and excluded some specific files like the settings file and the nuget packages config file.

Finally we are able to use that files relative path to copy the file into the artifact directory.

  • I have cake script that copies some files from other directory into project/bin. Then cake calls task that does MSBuild. I am not seeing that file into the generated package/bin directory. Does MSBuild clean that directory? How can i achive this? any ideas? – Vivek Patel Mar 25 '21 at 19:41