Publishing with ClickOnce via Visual Studio and TFS 2015 (vNext)

ClickOnce equips your published application to be able to check for updates and to, optionally, do the update automatically. See this post for more information.

To invoke this functionality from either the command-line or your build definition/process, you need to pass some additional project parameters to MSBuild.

ApplicationVersion (e.g. 1.0.1.6)
InstallUrl (e.g. http://clickonce.localhost/consoletestfrombuild/)
UpdateUrl (e.g. http://clickonce.localhost/consoletestfrombuild/)
PublishUrl (e.g. http://clickonce.localhost/consoletestfrombuild/)
UpdateEnabled (e.g. true)
UpdateMode (e.g. Foreground)
ProductName (e.g. TestConsoleApplication)

There is some disagreement as to whether the “ProductName” parameter is necessary.

The corresponding set of MSBuild arguments using the example values:

/target:publish /p:ApplicationVersion=1.0.1.6 /p:InstallUrl=http://clickonce.localhost/consoletestfrombuild/ /p:UpdateUrl=http://clickonce.localhost/consoletestfrombuild/ /p:PublishUrl=http://clickonce.localhost/consoletestfrombuild/ /p:UpdateEnabled=true /p:UpdateMode=Foreground /p:ProductName=TestConsoleApplication

If your polling locations are going to be UNCs (“\\path\\file”) rather than URLs then you’ll have to pass an additional argument:

/p:IsWebBootstrapper=false

To configure this under a TFS 2015 build-definition, simply add the parameters to the “MSBuild Arguments” field:

ClickOnce Settings in TFS 2015

References

Building ClickOnce Applications from the Command Line (Microsoft)

Deploying a click-once application with build vNext in Azure Blob Storage

Advertisements

Adding a Task to Your On-Premise TFS 2015 Server

TFS 2015 embeds previous vNext functionality to provide you workflow-driven, scriptable builds. This is based on establishing discrete tasks that can be reused between your build definitions and release definitions as relevant.

You can extend the basic set of tasks, which, though sufficient for very simple builds and releases, might quickly become insufficient. New tasks are called “extension tasks”. Discussing how to create one is out of scope for this post so we’re assuming that you already have a path that describes a task. At the very least, there will be a task.json file in it.

What comes next?

  1. Install Microsoft’s “tfx” tool.
  2. Added support for “Basic Authentication” to your on-premise TFS’ IIS server.
  3. Enable Basic Authentication on that IIS server.
  4. Login to your TFS using the tfx tool.
  5. Upload task.

Instructions

1. Install Microsoft’s “tfx” tool

This is a cross-platform project that requires NodeJS to be installed locally. The TFS-CLI project is hosted here: https://github.com/Microsoft/tfs-cli.

To install:

npm install -g tfx-cli

2. Add support for “Basic Authentication” to your on-premise TFS’ IIS server

On a workstation flavor of Windows (in my case, Windows 8.1):

  1. Go to “Programs and Features” -> “Turn Windows features on or off”.
  2. Navigate down through the tree of features: “Internet Information Services” -> “World Wide Web Services” -> “Security”.
  3. Enable “Basic Authentication” and click “OK”.

If you’re running a server flavor of Windows you’ll have to update the “Web Server” role instead:

(https://github.com/Microsoft/tfs-cli/blob/master/docs/configureBasicAuth.md)

windowsserverconfigurebasicauthfeature.png

Make sure to close and re-open IIS Manager afterward.

3. Enable Basic Authentication in IIS

Under the application, click “Authentication”, right-click on “Basic Authentication”, and click “Enable”. Make sure you enable “Basic Authentication” under the application, not the site. Setting it on the site will be ineffectual.

4. Login to your TFS using the tfx tool

C:\>tfx login --auth-type basic
TFS Cross Platform Command Line Interface v0.3.20
Copyright Microsoft Corporation
> Service URL: http://localhost:8181/tfs/DefaultCollection
> Username: yourdomain\dustin.oprea
> Password:
Logged in successfully

5. Upload task

I tested using the “XLD” task, here:

XL Deploy

Unzip and install by passing the directory path:

tfx build tasks upload --task-path xld

Now, if you go to your list of release tasks (where the XLD task ends-up), you’ll see it:

windowsserverconfigurebasicauthfeature.png