Analytics

Thursday, April 21, 2011

TFS 2010 Copy Files Custom Activity

I had the need recently to copy specific files from my TFS build output directory to a deployment directory. TFS has a built in activity to copy an entire directory, but no way to limit which files get copied. So, I created a quick implementation of CodeActivity that does just that.

  1. using System;
  2. using System.Activities;
  3. using System.Collections.Generic;
  4. using System.IO;
  5. using System.Linq;
  6.  
  7. namespace BuildTasks.Activities
  8. {
  9.     public class CopyFiles : CodeActivity
  10.     {
  11.         [RequiredArgument]
  12.         public InArgument<IEnumerable<string>> SourceFileMasks { get; set; }
  13.  
  14.         [RequiredArgument]
  15.         public InArgument<string> SourceDirectory { get; set; }
  16.  
  17.         [RequiredArgument]
  18.         public InArgument<string> DestinationDirectory { get; set; }
  19.         
  20.         public InArgument<bool> OverwriteFiles { get; set; }
  21.  
  22.         protected override void Execute(CodeActivityContext context)
  23.         {
  24.             var sourceFileMasks = context.GetValue(SourceFileMasks);
  25.             if (sourceFileMasks == null || sourceFileMasks.Count() == 0) return;
  26.  
  27.             var sourceDirectory = new DirectoryInfo(context.GetValue(SourceDirectory));
  28.             if (!sourceDirectory.Exists) return;
  29.  
  30.             var destinationDirectory = context.GetValue(DestinationDirectory);
  31.             if (!Directory.Exists(destinationDirectory)) return;
  32.  
  33.             var overwrite = context.GetValue(OverwriteFiles);
  34.  
  35.             foreach (var sourceFileMask in sourceFileMasks)
  36.             {
  37.                 var sourceFiles = sourceDirectory.GetFiles(sourceFileMask);
  38.                 foreach (var sourceFile in sourceFiles)
  39.                 {
  40.                     sourceFile.CopyTo(Path.Combine(destinationDirectory, sourceFile.Name), overwrite);
  41.                 }
  42.             }
  43.         }
  44.     }
  45. }

The SourceFileMasks property allows you to pass in a list of file name masks that match the files you would like to copy. For example, if you needed to copy YourApp.exe, YourApp.exe.config, YourApp.pdb, Dependency.dll, Dependency.pdb, you could specify that with the following list:

{"YourApp.*", "Dependency.*"}

The screen shot below shows a simplified workflow using the CopyFiles activity to copy files from the build drop folder to a network share at “\\MyServer\Destination”. Also of note is the OverwriteFiles property where you can specify if any existing files should be overwritten.

image

I put together this code rather quickly, so let me know if you see anything overtly incorrect about it. The code is available as a gist at https://gist.github.com/935122.