Azure DevOps を社内 npm registry として使う時の Tips

社内開発フレームワークの npm package を管理するために、Azure DevOps の Artifacts がメンバー限定 npm registry として使える事が判った。
その設定を行った際に判ったことをメモ。

## Azure DevOps の設定

* [Use packages from npmjs.com - Azure Artifacts | Microsoft Docs](https://docs.microsoft.com/ja-jp/azure/devops/artifacts/npm/upstream-sources?view=azure-devops)

に書いてある通りなのだが、サラッと言うと。

1. Azure DevOps にプロジェクトを作成し、Artifacts を選択
2. Create Feed で Feed を作成。名前は適当に、Visibility は "Member of <Organization>" で。"Upstream Source" もチェックを入れる。
3. 右上のギアアイコンをクリック → Upstream sources タブを選択し、npmjs **以外** の Source を削除する(npm registry としてのみ使うので)
4. Artifacts の Top に戻り、"Connect to Feed" を押す。次の画面で npm グループ内の npm を選択。
5. Linux(WSL) なので、Project setup 内の Other タブを選択。
6. ``registry=https://xxx`` で始まる2行をコピーしておく。 **※A**
7. 次に、 ``; begin auth token`` から ``; end auth token`` までをコピーしておく。 **※B**
7. Step 2 にある personal access token をクリックする。
8. パッケージデプロイする用の Token を作成する。Token Name は ``npm-uploader`` とし、期限は任意(最長で1年のようだ)、Scopes は **Packaging** の **Read & Write** を選択して保存する。表示される token をコピーしておく。 **※C**
9. パッケージを利用する人用の Token を作成する。Token Name は ``npm-reader`` とし、期限は任意(最長で1年のようだ)、Scopes は **Packaging** の **Read のみ** を選択して保存する。表示される token をコピーしておく。 **※D**

### ※A ～ D の例

**※A**

```terminal
registry=https://pkgs.dev.azure.com/myorg/myproj/_packaging/myfeed/npm/registry/

always-auth=true
```

**※B**

```terminal
; begin auth token
//pkgs.dev.azure.com/myorg/myproj/_packaging/myfeed/npm/registry/:username=myorg
//pkgs.dev.azure.com/myorg/myproj/_packaging/myfeed/npm/registry/:_password=[BASE64_ENCODED_PERSONAL_ACCESS_TOKEN]
//pkgs.dev.azure.com/myorg/myproj/_packaging/myfeed/npm/registry/:email=youraddress@mycompany.com
//pkgs.dev.azure.com/myorg/myproj/_packaging/myfeed/npm/:username=myorg
//pkgs.dev.azure.com/myorg/myproj/_packaging/myfeed/npm/:_password=[BASE64_ENCODED_PERSONAL_ACCESS_TOKEN]
//pkgs.dev.azure.com/myorg/myproj/_packaging/myfeed/npm/:email=youraddress@mycompany.com
; end auth token
```

↑なんだか後半の3行は特に必要ないみたい。※A の registry URL に対応してるのだからそうだよね。

**※C、※D** 値は適当です

```bash
# エンコード前の token
wbeogamr5bhqnyxpiodntpdb57tffqbqholocat3e6iwvyx2rd3q

# Base64 エンコード
echo -n "wbeogamr5bhqnyxpiodntpdb57tffqbqholocat3e6iwvyx2rd3q" | base64

# Base64 エンコードされた token
d2Jlb2dhbXI1Ymhxbnl4cGlvZG50cGRiNTd0ZmZxYnFob2xvY2F0M2U2aXd2eXgycmQzcQ==
```



## クライアント(パッケージデプロイ者)の設定

1. 端末のホームディレクトリ(``$home``) に ``.npmrc`` を作成し、**※A** の2行を貼り付けて保存する。
2. デプロイする npm プロジェクトの ``package.json`` と同じディレクトリに ``.npmrc`` を作成し、**※B** の ``; begin auth token`` から ``; end auth token`` を貼り付ける。2つある ``_password=`` に、**※C** の token を **BASE64 エンコードした文字列** を貼り付けて保存する。
3. 2箇所ある ``email=`` には、パッケージ開発者のメールアドレスを設定しておく(任意)。

これで ``npm publish`` を実行すると、Artifacts に npm パッケージがデプロイされる。
DevOps の Artifacts の Top ページを更新すると、デプロイされた npm パッケージが表示される。

## クライアント(パッケージ利用者)の設定

1. 端末のホームディレクトリ(``$home``) に ``.npmrc`` を作成し、**※A** の2行を貼り付けて保存する。
2. 1. の ``.npmrc`` に、**※B** の ``; begin auth token`` から ``; end auth token`` を貼り付ける。2つある ``_password=`` に、**※D** の token を **BASE64 エンコードした文字列** を貼り付けて保存する。

これで、``npm install <デプロイしたnpmパッケージ名>`` とすると、そのパッケージがダウンロード、インストールされる。

## ポイント

### デプロイ用と読み取り専用

パッケージをデプロイできる token と、利用しかできない token を用意して、利用しかできない token をユーザーホームの(既定の) 認証情報として設定する。

パッケージのデプロイが必要な場合は、プロジェクトごとに ``.npmrc`` を作り設定することで、間違えてデプロイしてしまう危険性を排除している。

### Upstrem source

セカンダリの npm registry として、既定の ``https://registry.npmjs.org/`` が使用されるため、``https://www.npmjs.com/`` で公開されているすべての npm パッケージも利用できる。

ただし、

* token が expire した場合は、``https://www.npmjs.com/`` からのインストールも失敗する
* DevOps を経由しているせいか、通常より遅い？(気のせい)

という留意点がある。

### 認証方式

Personal Access Token の代わりに SSH public keys が使えないだろうか？要検証。