Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / All-Topics

A 'Hello World' for VSO Extensions

5.00/5 (1 vote)
18 Jun 2015CPOL5 min read 7K  
A 'Hello World' for VSO extensions

So if you haven't heard yet, VSO Extensions are now in a private preview where you can sign up to get into the preview on extensions integration site. These extensions in the shortest sentence supported way of doing customizations to VSO that will replace any of the "hacky" extensions that you may be playing around with at the moment like Tiago Pascal's Task Board Enhancer or maybe you have even created your own following similar steps to what I show in my TFS 2013 Customization book.

This post aims to give you a super quick guide on how to get started, you will need to go through the integrations site to really get into detail. It has most of what you will find in most posts but gives you a little something extra that most posts wouldn't have like tips on free stuff. :)

File, New Project

The easiest way to get a basic something in VSO is to just create a new project.

Create/Configure Project

We are going to create a new Type Script project:

 New_Project_2015-06-18_20-08-23

You should have something like below now:

2015-06-18_20-09-35

Configure SSL in IIS Express

When you have the VSO Time Ticker project selected, head over to the properties window:

2015-06-18_20-17-56

Change SSL Enabled to True:

2015-06-18_20-18-36

Take note of the SSL Url that is now available to you.

Add an extensions.json

Let's add a extensions.json manifest file that will be used to inform VSO what our projects actually about:

Add_New_Item_-_VSO_Time_Ticker_2015-06-18_20-11-47

and drop in the content below, replace the baseUri property to include the port you have been assigned for SSL for the project.

C#
{
  "namespace": "VSO-Time-Ticker",
  "version": "0.0.1",
  "name": "Time Ticker",
  "description": "A simple extension for Visual Studio Online of a Time Ticker",
  "provider": {
    "name": "Gordon Beeming"
  },
  "baseUri": "https://localhost:44300/",
  "icon": "https://localhost:44300/images/some-icon.png",
  "contributions": {
    "vss.web#hubs": [
      {
        "id": "time",
        "name": "Time",
        "groupId": "home",
        "order": 22,
        "uri": "index.html",
        "usesSdk": true,
        "fullPage": false
      }
    ]
  }
}

Get the SDK

Navigate to GitHub to the samples project and grab the VSS.SDK.js file. Save a copy of that to a scripts folder inside a sdk folder and add it to your project.

2015-06-18_20-27-15

Include Our App js Files

While we're here, let's build the project, show hidden folders and add the app.js and app.js.map files to the project:

2015-06-18_20-29-042015-06-18_20-29-58

If you are using source control, you should also at this point undo those files being added source control and then also add them to be excluded, otherwise you may get a weird error when it comes time to build your project on a build server (TypeScript : Emit Error: Write to file failed...).

2015-06-18_20-33-152015-06-18_20-33-49

The reason we want these as part of the solution is so that when we do web deploy later, they are deployed as well. :)

Add Our App Icon

Make an images folder and add an image called some-icon.png to it:

2015-06-18_20-44-48

Move App js File

Move your App.ts, App.js and App.js.map into a scripts folder. If you have source, you might need to re undo and ignore those extra files.

2015-06-18_20-51-48

Setup index.html

This is a rather simple step, replace the reference to app.js with one to sdk/Scripts/VSS.SDK.js so it will look something like:

2015-06-18_20-49-40

Add the following script just inside your body tag:

C#
<script type="text/javascript">
    // Initialize the VSS sdk
    VSS.init({
        setupModuleLoader: true,
        moduleLoaderConfig: {
            paths: {
                "Scripts": "scripts"
            }
        }
    });

    // Wait for the SDK to be initialized
    VSS.ready(function () {
        require(["Scripts/app"], function (app) { });
    });
</script>

So at this stage, your full index.html page will look like:

C#
<!DOCTYPE html>

<html lang="en">
<head>
    <meta charset="utf-8" />
    <title>TypeScript HTML App</title>
    <link rel="stylesheet" href="app.css" type="text/css" />
    <script src="sdk/Scripts/VSS.SDK.js"></script>
</head>
<body>
    <script type="text/javascript">
        // Initialize the VSS sdk
        VSS.init({
            setupModuleLoader: true,
            moduleLoaderConfig: {
                paths: {
                    "Scripts": "scripts"
                }
            }
        });

        // Wait for the SDK to be initialized
        VSS.ready(function () {
            require(["Scripts/app"], function (app) { });
        });
    </script>
    <h1>TypeScript HTML App</h1>

    <div id="content"></div>
</body>
</html>

Update App.ts

In your App.ts file, remove the window.onload function and replace it with its body so your App.ts file will look like below:

C#
class Greeter {
    element: HTMLElement;
    span: HTMLElement;
    timerToken: number;

    constructor(element: HTMLElement) {
        this.element = element;
        this.element.innerHTML += "The time is: ";
        this.span = document.createElement('span');
        this.element.appendChild(this.span);
        this.span.innerText = new Date().toUTCString();
    }

    start() {
        this.timerToken = setInterval(() => this.span.innerHTML = new Date().toUTCString(), 500);
    }

    stop() {
        clearTimeout(this.timerToken);
    }
}

var el = document.getElementById('content');
var greeter = new Greeter(el);
greeter.start();

Run App

Running your app with ctrl + F5, you will get a blank app that does nothing. :)

TypeScript_HTML_App_-_Internet_Explorer_2015-06-18_20-57-12

Changed the url to point to the SSL version of your site just to make sure everything is working:

2015-06-18_20-59-24

Our app is now complete. :D 

Install Your Extension

If you have signed up for the private preview, you should see a tab in the admin section of your account called Extensions like so:

2015-06-18_21-01-57

Click Install, and then Browse:

2015-06-18_21-06-49

Browse for your extension.json file:

Open_2015-06-18_21-07-59

 

Click Open and then OK:

2015-06-18_21-11-56

Your extension is now installed:

2015-06-18_21-17-24

View It on VSO

Go to a team project home page and you should now see a Time hub, click on it:

image

Once you land here, you will see the time. :)

image

That's 1 extension in the bag but having this run on your local machine is probably not what you would want because nobody else can see it.

Publishing Your App

You could buy an SSL certification but that costs a lot and most people don't have that kind of money laying around for fun apps and extensions so we'll turn to Azure. We will now right click on our project and click publish.

2015-06-18_21-45-47

If you setup an Azure site already, you can import the publish settings but I haven't so I'm going to click on Microsoft Azure Web Apps...

Publish_Web_2015-06-18_21-46-16

...and then click on New (again if you have a site already, you can select it in this list).

Select_Existing_Web_App_2015-06-18_21-47-26

Select a name and click Create.

Create_Web_App_on_Microsoft_Azure_2015-06-18_21-48-31

It will now take a small bit to setup your Azure resource:

Create_Web_App_on_Microsoft_Azure_2015-06-18_21-49-28

and then auto magically configure everything you need :), click Publish.

Publish_Web_2015-06-18_21-49-58

After the publish is finished, your site will launch:

TypeScript_HTML_App_-_Internet_Explorer_2015-06-18_21-51-30

Something that you will notice is that this is http but not https as we earlier said we require. So let's see what happens if we add an s in there. :)

TypeScript_HTML_App_-_Internet_Explorer_2015-06-18_21-53-07

Everything still works. :D

Last Bit of Manifest Changes

Now that we have a publicly accessible website running on https (for FREE), we can take that url and replace what we currently have in our manifest so it will now look like this:

C#
{
  "namespace": "VSO-Time-Ticker",
  "version": "0.0.2",
  "name": "Time Ticker",
  "description": "A simple extension for Visual Studio Online of a Time Ticker",
  "provider": {
    "name": "Gordon Beeming"
  },
  "baseUri": "https://vso-hello-world.azurewebsites.net/",
  "icon": "https://vso-hello-world.azurewebsites.net/images/some-icon.png",
  "contributions": {
    "vss.web#hubs": [
      {
        "id": "time",
        "name": "Time",
        "groupId": "home",
        "order": 22,
        "uri": "index.html",
        "usesSdk": true,
        "fullPage": false
      }
    ]
  }
}

Re-install your extension...

2015-06-18_21-56-38

...and refresh your extension in VSO:

image

You will notice now that it obviously still works :), if you close Visual Studio and it still works you know it working :) and I suppose you can check fiddler for where it's reading the files from.

Links

For more information on VSO Extensions, visit http://aka.ms/vsoextensions.

A pretty neat getting started post is also on that site at https://www.visualstudio.com/en-us/integrate/extensions/get-started/visual-studio.

Microsoft has a project out on GitHub as well that is quite advanced in the APIs that it uses and can be found at https://github.com/Microsoft/vso-team-calendar.

If you want a light overview over everything, then you can get their VSO Extension Samples out on GitHub as well using the link https://github.com/Microsoft/vso-extension-samples.

The complete sample code for this post is also out on Github at https://github.com/Gordon-Beeming/VSO-Time-Ticker.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)