銀の光と碧い空

クラウドなインフラとC#なアプリ開発の狭間にいるエンジニアの日々

VSTS 拡張を作ってみる (1)

Visual Studio Team Services にはExtensionという拡張を作ることができ、独自の機能を持った拡張を提供することができます。既存のVSTSのWeb画面(タブやコンテキストメニュー)に追加することができ、SDKを使うことで拡張側で新たな認証処理を入れることなくVSTSのAPIを呼び出せます。検索するといろいろ情報が出てくるのですが、いくつか試したところ現時点で一番正確な情報はここのようです。今回はこのサイトを見ながら作ったときの概要と注意点をまとめてみました。

Overview of extensions for Visual Studio Team Services

一方、こちらの情報はちょっと古いので注意が必要です.

パッケージのコンテンツの作成

VSTS 拡張の開発はJavaScriptとHTMLで書きます。JavaScriptはTypeScriptでも書けますが、とりあえずJavaScriptでやってみましょう。また、コードをパッケージングしたり、アップロードするのにnode.js製のコマンドを作るので、node.js をインストールしておきましょう。手元には、4.2.3 LTS を入れています。

Node.js

パッケージを作るのにSDKが必要です。GitHubから取ってきます。npmなどでも取得できますが、取得したあと、sdk/scriptsにVSS.SDK.jsを移動しておきます*1

github.com

次にhtmlファイルを作成します。これもサンプルのファイル名から変えてもいいですが、その場合はそのあとの該当箇所を書き換えます。

 <!DOCTYPE html>
 <html xmlns="http://www.w3.org/1999/xhtml">
 <head>
     <title>Hello World</title>
     <script src="sdk/scripts/VSS.SDK.js"></script>
 </head>
 <body>
     <script type="text/javascript">VSS.init();</script>
     <h1>Hello World</h1>
     <script type="text/javascript">VSS.notifyLoadSucceeded();</script>
 </body>
 </html>

次にロゴを作成するとありますがなくても問題ないので今回は省略します。

そして、manifestファイルと呼ばれる拡張の設定ファイルを記述します。サイトにはpackage.jsonという名前になっていますが、vss-extension.jsonの方がデフォルトの名前のようなのでそちらを使います。

{
    "manifestVersion": 1,
    "id": "<この拡張のID>",
    "version": "<拡張のバージョン。0.1.0みたいな形式>",
    "name": "<拡張の名前>",
    "description": "<拡張の設定>",
    "publisher": "<次のところで説明するPublisher ID>",
    "targets": [
        {
            "id": "Microsoft.VisualStudio.Services"
        }
    ],
    "categories": [
        "Integrate"
    ],
    "contributions": [
        {
            "id": "<Contributionごとに一意なID>",
            "type": "<ContributionのType>",
            "description": "<Contributionの説明>",
            "targets": [
                "<Contributionが拡張するポイント>"
            ],
            "properties": {
                "name": "Group",
                "order": 99,
                "uri": "build.html"
            }
        }
    ],
    "files": [
        {
            "path": "build.html",
            "addressable": true
        },
        {
            "path": "scripts",
            "addressable": true
        },
        {
            "path": "sdk/scripts",
            "addressable": true
        }
    ]
}

manifestのスキーマはここに説明があります。

https://www.visualstudio.com/integrate/extensions/develop/manifest

Contributionというのが拡張する機能の単位になっています。今回作っているのは特定の場所にタブを追加してそこに表示するHTMLコンテンツを追加するものになります。 そして、サイトによっては記述が省略されているのですが、filesというところにパッケージに含めるファイルを指定します。ここに指定されたファイルのみがパッケージ化されてVSTSにアップロードし、参照されます。パッケージに含めず、自分が管理するWebサイトにホスティングし、VSTSの拡張はそちらのWebサイトを参照する、という方法もできますが、今回はパッケージに含めることにするので必須です。

また、publisher のところには以下のサイトからpublisher登録をして、そのIDを指定します。publisher登録は次で説明するtfxコマンドを使ってもできます。

https://marketplace.visualstudio.com/manage/publishers/

パッケージを作成してアップロードする

それではパッケージを作成してアップロードしてみましょう。まずアップロードするときに使うアクセストークンをVSTSのページから作成します。

https://<yourdomain>.visualstudio.com/_details/security/tokens

f:id:tanaka733:20151218145836j:plain

次にサイトにある通り、tfx-cli というnpmパッケージをインストールします。このコマンドでパッケージの作成やアップロードを行います。 パッケージの作成は以下のコマンドで行います。manifestファイルの名前が vss-extension.json であれば明示的に指定しなくても大丈夫です。

> tfx extension create

実行すると、<publisherid>.<packageid>-<version>.vsixというVSIXパッケージができます。そして作成したパッケージをアップロードします。

> tfx extension publish --token <yourtoken> --share-with <youraccount>

--tokenは先ほど作成したトークンと指定します。--share-withはアップロードしたパッケージを共有(インストールできるようにする)VSTSのアカウント(xxx.visutalstudio.comのxxxの部分)を指定します。 アップロードしたパッケージは以下のURLの、publisherとして公開している拡張一覧ページで確認できます。

https://marketplace.visualstudio.com/manage/publishers/<publisherID>

f:id:tanaka733:20151218150017j:plain

コマンド経由ではなくこのWebページから直接VSIXパッケージをアップロードすることもできますが、その場合は共有する処理を別途行う必要があります。アップロードと共有が同時にできるので、tfxコマンドの方がおすすめです。 アップロードしたパッケージは、そのパッケージのリンクを踏んで、次の画面からインストールすることで利用可能になります。

f:id:tanaka733:20151218210831j:plain

また、VSTSのアカウントからは共有されているもしくはインストールした拡張一覧がこのページで確認できます。拡張の無効化、アンインストールが可能です。

https://<yourdomain>.visualstudio.com/DefaultCollection/_admin/_apps/hub/ms.vss-extmgmt-web.manageExtensions-collection

f:id:tanaka733:20151218145853j:plain

という感じでVSTS拡張の作成・アップロード・インストールまでのフローができます。また、同じバージョンでパッケージを更新することが可能*2なので、開発中はバージョンは上げずにパッケージ作成=>更新するだけで更新できます。

このままだと単なる静的コンテンツしか表示できないので、明日はVSTSのAPIをたたいて情報を表示してみましょう。

*1:おそらく別の場所でもいいが、そのときはサンプルのコードを適宜書き換える必要があるはず

*2:おそらくプライベートな拡張のみ?