【ライブラリ開発】リリースタグが切られた時に自動でnpmにpublishするGitHub Actions

## はじめに

お疲れ様です。
[クロスマートアドベントカレンダー](https://qiita.com/advent-calendar/2024/xmart) 2日目の記事となります。
最近コミットできてないですが、趣味でvue3のdatepickerライブラリを開発しています。
「折角なのでCIもちゃんとしたリポジトリの真似してみてえな！」ということで、リリースタグを切ると自動でbuildし、npmにpublishするCIを組んでみました。
その内容となります。

## relase.yamlの内容

こんな感じです。

https://github.com/FAL-coffee/vue3-datepick/blob/main/.github/workflows/release.yml

```yaml
name: Release

on:
  push:
    tags:
      - '*'

jobs:
  publish:
    name: Node.js ${{ matrix.python-version }} on ${{ matrix.os }}
    runs-on: ${{ matrix.os }}
    timeout-minutes: 10
    strategy:
      matrix:
        node-version: [20.x]
        os: [ubuntu-latest]

    permissions:
      contents: read
      id-token: write

    steps:
      - name: Checkout 🔔
        uses: actions/checkout@v4

      - name: Setup Node.js ${{ matrix.node-version }} 🔧
        uses: actions/setup-node@v4
        with:
          node-version: ${{ matrix.node-version }}
          registry-url: 'https://registry.npmjs.org'

      - name: Install dependencies 🧹
        run: npm install

      - name: Build 🔨
        run: npm run build

      - name: Publish 🎁
        run: npm publish --provenance --access public
        env:
          NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
```

## npm tokenの発行

ログイン後、画面右上のプロフィールアイコンから「Access Tokens」を選択します。

![スクリーンショット 2024-11-28 11.48.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1869061/8e960aea-9cd6-9339-9fd6-7a8cd8f5687a.png)

作成するトークン種別は「Granular Access Token」を選択します。

「Granular Access Token」と「Classic Token」の違いですが、大まかに以下です。

- 「Granular Access Token」
  - 権限のスコープを細かく設定可能で、特定のパッケージや操作（例: publish、read-onlyなど）に限定できる。
- 「Classic Token」
  - npm全体へのフルアクセスを許可する。従来のワークフローとの親和性が高い。

![スクリーンショット 2024-12-01 22.53.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1869061/808256ef-2764-a2e1-81c8-20e8aa5329a9.png)

### Granular Access Token設定内容例

お行儀良く設定するとこんな感じになります。
サクッと設定したい方はこちらを真似していただけると良さそうです。

| **設定項目**          | **設定内容**                                            | **理由**                                                                 |
|-----------------------|--------------------------------------------------------|--------------------------------------------------------------------------|
| **Token name**        | `ci-publish-token-vue3-datepick`                       | トークンの目的（CIから`vue3-datepick`のパッケージを公開する）を明確にするため。 |
| **Description**       | `Token for CI to publish packages to npm registry`     | チームメンバーや管理者がトークンの用途を簡単に把握できるようにするため。        |
| **Expiration**        | `90日間`                                               | セキュリティと運用負担のバランスを考慮し、漏洩リスクを最小限にするため。90日毎に更新を行い、管理体制を維持します。 |
| **Allowed IP ranges** | 設定なし                                               | CI環境のIPアドレスが固定されていないため。また、必要最小限の権限だけで運用するため、IP制限は不要と判断。 |
| **Packages**          | `Only select packages and scopes`                     | 必要なパッケージだけに権限を絞ることで、他のパッケージへの誤操作や漏洩リスクを防ぐため。  |
| **Selected packages** | `vue3-datepick`                                        | このトークンは`vue3-datepick`パッケージの公開専用であるため、対象を明確化しました。 |
| **Organizations**     | 設定なし（Provide no access to organizations）         | 組織全体へのアクセス権限は不要であり、誤用や漏洩時の影響を最小化するため。        |
| **Permissions**       | `Read-only access to 1 package (vue3-datepick)`        | `publish`権限だけが必要であるため、読み取り専用の権限で最小限に抑えました。      |

## GitHub Actions variables

![スクリーンショット 2024-12-01 23.12.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1869061/2f9fc70a-97e9-93f5-2444-05312fab705a.png)

「Settings > Security > Secrets and variables > Actions」を選択してください。

ページのURLは`https://github.com/{ユーザー名}/{repo名}/settings/secrets/actions`となります。

![スクリーンショット 2024-12-01 23.10.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1869061/6d086fe4-6bbe-f6bb-8dd8-e1530b7b2647.png)

> ```yaml
>        env:
>          NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
>```

としているため、Variablesではなく、Secretsに設定します。
これで設定としては完了です。

## Relaseしてみる

>```json
> {
>  "name": "vue3-datepick",
>  "version": "1.0.1",
> ```

`package.json > version`を変更し、適当な感じでRelaseを作成します。

![スクリーンショット 2024-12-01 23.17.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1869061/5dfe643c-e4f8-9f5f-7c77-ccc7a2d3f3a4.png)

yamlの内容に沿ってCIが実行され....

![スクリーンショット 2024-12-01 23.18.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1869061/ae887c7e-a3c4-432e-7ca0-47f9a3367e75.png)

build / npm publishが実行・無事完了しました。わーい！:tada:

![スクリーンショット 2024-12-01 23.19.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1869061/595b1c0e-caa9-805f-09e8-b0564c2845a9.png)

## まとめ

今回はリリースタグを切った時に自動でnpm publishするCIを構築してみました！
アドカレ次回もよろしくお願いします〜！