🚀

GitHub Package RegistryでプライベートなnpmパッケージをGitHub Actionsを使って管理する

2023/06/10に公開

こんにちは @glassmonekeyです。
現在、個人開発でGitHub Package Registryを利用したプライベートな npm パッケージ を管理をしています。
npm パッケージ の作成と GitHub Package Registry へのリリース運用フロー構築で少しハマったので、主に自分用の備忘録です。
もし間違っている点がありましたらコメントしていただけると幸いです。

リリースの運用フローについての方針

今回のバージョン管理は以下のフローで行うことにします。
ラベルを用いることで、手軽で間違えにくいバージョンの bump を行います。

  • Pull Request のマージの度に自動リリースが行えること。(基本的には patch バージョン)

  • 特別なリリース用 Label を付与した PullRequest がマージされたときはその内容に従ってバージョンを bump する。

    • 例えば release/major の付与された PR は major バージョンアップといった形。
    • 今回は relase/major, release/minor, release/patch の 3 パターンの想定です。
  • release itは利用しない。

    • npm の標準機能で事足りており、3rdParty なツールを入れなくても良いと判断した。
    • change log などもう少しリッチな機能が欲しくなったら要検討。

準備

1. package.jsonの設定

  "name": "@<OWNER>/<REPOSITORY>",
  "repository": {
    "type": "git",
    "url": "https://github.com/<OWNER>/<REPOSITORY>.git"
  },
   "files": [
        公開したいファイル郡
   ]
  ...

publish 先指定のために namerepository を記載します。

特に nameスコープを含める場合は @<SCOPE>/<REPOSITORY> の形式で名前を設定しておかないといけない点は注意が必要です。SCOPE は基本的にはリポジトリのオーナー名で良いでしょう。

また、files に公開したいファイル群を記載します。
この記載がないとすべてのファイルがパッケージに含まれてしまうので注意が必要です。
ライブラリの場合は主に build 結果のみでいいはずなので、build 出力先のディレクトリ(例えば dist)あたりを書いておくと良いでしょう。

記載した内容のファイル群が利用側のプロジェクトで npm install した際に node_modules 内部にインストールされます。

以下のファイルは指定されていなくても追加されます。

  • package.json
  • README
  • LICENSE / LICENCE
  • The file in the "main" field

https://docs.npmjs.com/cli/v8/configuring-npm/package-json#files

2. 認証情報の設定

2.1 パッケージPublish用のパッケージ読み(書き)ができるトークンを生成する

検証用ローカル上のパッケージ Publish と CI 上の設定ためのトークンを作成します。

GitHubの設定画面から GitHub Package Registry へ読み書き権限のあるトークンを作成します。

トークン設定画面

2.2 ローカルで認証を通す

ローカルから以下のコマンド入力します。
ユーザー名は GitHub のアカウント名、パスワードには上記で作成したトークンを入力します。

$ npm login --scope=@<OWNER> --auth-type=legacy --registry=https://npm.pkg.github.com

Username: <ユーザー名>
Password: <TOKEN>

すると ~/.npmrc にパッケージの向き先が記載されます。
.npmrc 自体はリポジトリごとに置いても機能するので、利用リポジトリ側に置くといった工夫も考えられます。

その際は Publish用 の同じトークンを使い回すのではなく、パッケージの読み込み権限さえあれば良いので read:pacakges が認可されているトークンを別途発行しておくと良いでしょう。

.npmrc そのものは、GitHub トークンを含んでいるので扱いには注意が必要です。

  //npm.pkg.github.com/:_authToken=<トークン名>
  @<OWNER>:registry=https://npm.pkg.github.com/

3. ローカルからGitHub Package Registryへpublishする

CI から publish する前に、ローカルからパッケージが publish できるか検証を行います。

3.1 バージョンのbump

基本的には package.jsonversion 内容に従って publish できます。同じバージョンに対しては publish できないので、内容に応じてバージョンを bump すると良いでしょう。

現在のバージョンが 0.1.0 とすると npm version を使って bump できます。他にも指定方法がありますが、基本的には major, minor, patch3 つでいいでしょう。
他の指定方法はnpm-versionをご覧ください。

$ npm version major
v1.0.0

$ npm version minor
v0.2.0

$ npm version patch
v0.1.1

3.2 npm publish

認証とバージョンの bump が完了していたら基本的に以下で publish ができるはずです。

$ npm publish

CIからPublishする

基本的にローカル上での publish 操作はしないはずなので、CI から publish できるようにします。今回は GitHub Actions を使います。
事前に NPM_TOKEN という名前で 2.1 で払い出したトークンを Actions secrets and variables で設定しておきます。

node のバージョンなどは適宜読み替えてください。

on:
  pull_request:
    # PR上のLabelを読み取るためにcloseしたタイミングでワークフローを発火させる。
    types:
      - closed
    branches:
      - main
jobs:
  release:
    # マージされたPR以外は動作させない
    if: github.event.pull_request.merged == true
    runs-on: ubuntu-latest
    env:
      GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
    permissions:
      packages: write
      contents: write
    steps:
      - uses: actions/checkout@v3
      - uses: actions-ecosystem/action-release-label@v1
        id: release-label
      - name: Setup node
        uses: actions/setup-node@v3
        with:
          node-version: 18
          check-latest: true
          cache: npm
          registry-url: https://npm.pkg.github.com/
      # PR作成者でcommitを行う
      - name: git config
        run: |
          git config user.name "${GITHUB_ACTOR}"
          git config user.email "${GITHUB_ACTOR}@users.noreply.github.com"
      - run: npm install
      # ラベルがない場合はpatchバージョンでバージョンを上げる
      - name: bump version
        run: npm version  ${{ steps.release-label.outputs.level || 'patch' }} --no-git-tag-version
      # バージョンをbumpした内容をmainブランチにcommitする
      - name: commit version
        uses: stefanzweifel/git-auto-commit-action@v4
        with:
          commit_message: bump version
          branch: main
      - name: publish
        run: npm publish
        env:
          NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

actions-ecosystem/action-release-labelを使うとラベルから release 用のレベル(major, minor, patch)を楽に識別できるので利用しました。

なお、package.json への commit のタイミングは PullRequest が close するタイミングだと、参照が取れないのでマージ先の main ブランチに直接 commit しています。

その際、main ブランチへの commit が禁止の場合は、別途 bump 用の PR を自動で作るなど、リリースとバージョンの bump 判定を分離すると良いでしょう。

まとめと感想

npm パッケージとして公開するための設定方法から、リリース用ラベルを含めたワークフロー運用例について紹介しました。

意外とバージョンの自動 bump 運用を含めた記事は意外となかったので、参考になったら幸いです。

参考

GitHub Actionsとrelease-it npmでリリース作業を自動化する

GitHub Packagesでプライベートnpmパッケージを公開する

Discussion