Taming TFS - Automatic deployment of Click Once projects

By eidias on (tags: tfs, categories: infrastructure)

We’ve covered deploying web application, now it’s time for click once. So let’s get to it.

This is the end result:

image

After some checks I’m retrieving the project files with “FindMatchingFiles” activity, then for each project and each configuration publishing the project and transferring it to the test server.

Here’s the breakdown in detail.

The “FindMatchingFiles” activity arguments:

Argument Value
MatchPattern String.Join(";", ClickOnceProjects.Select(Function(p) String.Format("{0}\**\{1}.csproj", SourcesDirectory, p)))
Result ClickOnceProjectsToTransfer

Assign

Argument Value
To projectName
Value Path.GetFileNameWithoutExtension(project)

Publish Click Once Projects (type “MSBuild”)

Argument Value
CommandLineArguments

String.Format("/p:SkipInvalidConfigurations=true /property:PublishDir=""{0}/"";SignManifests=True;ManifestCertificateThumbprint={1};ApplicationVersion={2};PublisherName={3};InstallURL={4};UpdateUrl={5};SupportUrl={6};UpdateEnabled={7};UpdateMode={8};BootstrapperEnabled=True;IsWebBootstrapper=True;MapFileExtensions=True",
              Path.Combine(BinariesDirectory, PublishedDir, Directory.GetParent(project).Name),
              SigningThumbprint,
              AssemblyVersion,
              PublisherName,
              InstallUrl.Replace("$(ProjectName)", projectName),
              UpdateUrl.Replace("$(ProjectName)", projectName),
              SupportUrl.Replace("$(ProjectName)", projectName),
              UpdateEnabled,
              UpdateMode)

configuration platformConfiguration.Configuration
Project project
Targets New String() {"Publish"}
TargetsNotLogged New String() {"Publish"}
ToolPlatform MSBuildPlatform
Verbosity Verbosity

The following things are worth mentioning

  • CommandLineArguments – most of them are standard publishing parameters for click once, but not all, pay special attention to MapFileExtensions parameter as it’s apparently a part of secret knowledge
  • TargetsNotLogged – this is populated with the same list as Targets property. If you don’t specify this, your build will have an additional ‘summary’ like this one:
    image
    If you’re ok with that, leave the argument empty

FtpClean:

Argument Value
Address FtpAddress + "/" + projectName
Password FtpPassword
User FtpUser

and finally FtpTransfer:

Argument Value
Address FtpAddress + "/" + projectName
Password FtpPassword
User FtpUser
SourceDirectory Path.Combine(BinariesDirectory, PublishedDir, projectName)

I’ve blogged about the Ftp actions here. You can also find the source code there.

That’s it. Hope this will give you some additional hints on how to handle tfs builds.

Cheers