GitHub ActionsからGithub PackagesにNPMパッケージをアップロードする

Github Packages を試すついでにGitHub Actions でNPMパッケージをアップロードする方法をまとめてみました。

2019/10/28更新 トークン周りをsetup-nodeで設定する方法に修正
2019/11/14更新 GitHub ActionsとGithub PackagesがGAになったのでGA後の内容に更新

事前準備

まずは普通にパッケージにするコードとpackage.jsonを用意します。
無くても大丈夫ですが無いとワークフローのファイルもパッケージに含まれてしまうので.npmignoreに除外設定を追加しておくとよいでしょう。

.github

レポジトリの設定

パッケージ名の設定

新しく作ったまっさらなレポジトリをクローンしてきてnpm inityarn initするとデフォルトだとレポジトリ名がパッケージ名になりますが、Github Package Registryはスコープ付きNPMパッケージのみをサポートするのでスコープ付きNPMパッケージ用の名前を指定する必要があります。

"name": "@OWNER/pkgname"

OWNERの部分にはレポジトリオーナーのユーザ名かOrganization名を指定します。
一点注意点があってスコープ付きNPMパッケージの仕様で大文字はダメらしくユーザ名やOrganization名に大文字が含まれる場合は小文字にする必要があるそうです。

repositoryフィールドの設定

package.jsonrepositoryに設定されているレポジトリのURLがGitHubのURLと一致している必要があるようです。
repositoryの書き方が複数あったりGitHubのURLもSSHとHTTPSとかで複数ありますがそれっぽければ良いみたいです。
とりあえずnpm inityarn initで自動で設定されるものはどちらもOKでした。

パッケージのスコープを設定

レポジトリのルートの.npmrcにスコープの設定を追加しアップロード先のレポジトリを指定します。

@OWNER:registry=https://npm.pkg.github.com/

設定自体はホームディレクトリ直下の.npmrcでも良いのですがレポジトリに含まれていないとワークフロー内部で別途設定する必要があるのでレポジトリに含めてしまったほうが良いでしょう。

ワークフローの設定

アクション使わないで素で書いてますが、探せば誰か公開してるかもしれないしそのうちGitHub公式から提供されるかも。

ワークフローのファイル追加

ワークフローのファイルを用意します。
setup-nodeがトークン周りの設定をしてくれるのでレジストリをwithに指定します。
トリガーのイベントやテストなどのステップはお好みで。

name: build
on: push

jobs:
  build:
    name: build
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@master
        with:
          fetch-depth: 1
      - name: Setup Node.js
        uses: actions/setup-node@v1
        with:
          node-version: 10
          registry-url: https://npm.pkg.github.com
      - name: test
        run: npm test

トークンの設定 & アップロード

パッケージをアップロードするのにトークンの設定が必要なため設定します。
GitHub Actionsだと特別な設定無しでいい感じのトークンが用意されているのでそれを使えばOKで環境変数のNODE_AUTH_TOKENに設定するとトークン周りをいい感じに設定してくれます。
あとは普通にpublishするだけでOK。

- name: publish
  if: contains(github.ref, 'master')
  run: npm publish
  env:
    NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}

アップロードしたパッケージをインストールする

インストールしたいレポジトリのルートの.npmrcにインストールしたいパッケージのスコープのレジストリの設定を追加します。

@OWNER:registry=https://npm.pkg.github.com/

レジストリの設定だけではなくトークンの設定も必要です。
レジストリの設定と同様に.npmrcに追加するのですが、こちらはレポジトリにpushしてしまうとまずいのでホームディレクトリ直下の.npmrcに追加しましょう。

//npm.pkg.github.com/:_authToken=PERSONAL-ACCESS-TOKEN

権限周りだけ仕様がいまいちよくわからなくて、どうやらパブリック・プライベート問わずread:packagesのスコープ付き個人アクセストークンの設定が必要みたいです。
てっきりパプリックレポジトリのパッケージならレジストリの設定だけでインストールできるものかと思っていたのですが、設定しないとエラーになってインストールできませんでした。
プライベートレポジトリのパッケージでトークンが必要なのは分かりますがパブリックなOSSなどのパッケージでも必要なのはやや不便なのでパプリックはトークンなしでもインストールできるようになると良いのですが・・・

アップロードしたパッケージを削除する

パブリックなパッケージは基本的には削除できないみたいです。
法律とかそういうレベルでやらかしちゃった場合は問い合わせフォームから削除依頼出せば削除してもらえるとのこと。

プライベートなパッケージはバージョン指定で削除できるみたいです。
Deleting a version of a private package

参考リンク