😎

semantic releaseを使ってパッケージを手軽に公開する方法

2022/06/01に公開

先日仕事でパッケージを作っていて、semantic-release を知って感動したので記事にすることにしました。

まず、semantic-release の良いところは

  • master ブランチに push したら自動でパッケージのバージョンが上がって、パッケージが更新されること
  • コミットメッセージから自動で Release   Note を作成してくれること
    だと思います。
    また、バージョン毎のタグ付けだったり、コミットのリンクもつけて Release Note を作ってくれてすごく良く自動化されていると思います。
    ただ、semantic-release を使うにあたって、ドキュメントがイマイチ読みづらく実際に使ってみないと良さが分からないなと思ったので、この記事を呼んだら semantic-release の良さを分かってくれるような記事にしたいです。

セットアップ

では、早速プロジェクトを作って見ましょう
今回は究極にシンプルな cli を作ります
今回はsayHelloとコマンドを叩いたらHello!と返ってくる cli を作ります
https://qiita.com/toshi-toma/items/ea76b8894e7771d47e10
こちらの記事を参考に作りました

  1. ファイルを作成する
mkdir semantic-release-tutorial
npm init -y
mkdir lib
touch lib/cli.js
  1. 実行ファイルの作成
./lib/index.js
module.exports = () => {
  console.log("Hello!")
}
  1. コマンドとファイルのマッピング
package
{
  // ...
  "bin": {
    "sayHello": "bin/cli.js"
  },
  // ...
}

コマンドとファイルのマッピングは bin フィールドでします

mkdir bin
touch bin/cli.js
bin
#!/usr/bin/env node

require("../lib/index")();

#! /usr/bin/env nodeは node の環境を作るためにあります。
ためしに command line で/usr/bin/env nodeと実行してみてください
node が起動するはずです
詳細はこちらを見てみてください

  1. npm linkを使って手元で試せるようにします
    npm linkを使うとグローバルなパッケージがインストールされる場所にシンボリックリンクが作られます

これでコマンドラインでsayHelloとうつとHello!と返ってくるはずです

semantic-release を使用する

最低限の package を作ったつもりなのですが、思ったよりも長くなってしまったかもしれません
ここからがこの記事の本題です!

  1. semantic-release を install する
npm i -D semantic-release

ci の設定をする

https://github.com/semantic-release/semantic-release/blob/master/docs/recipes/ci-configurations/github-actions.md
上記のコードを参考に setup をしていきます

  1. 環境変数を設定する
    NPM_TOKENGITHUB_TOKENが必要です。
    GITHUB_TOKENは ci の過程で自動で生成されるので問題ないのですが、NPM_TOKENこちらを参考に自分で用意する必要があります

    NPM_TOKENを作成したら下記の画像のように token を保存しましょう

  2. github actions を作成する

./.github/workflows/release.yml
name: Release
on:
  push:
    branches:
      - master
permissions:
  contents: write
jobs:
  release:
    name: Release
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v3
        with:
          fetch-depth: 0
      - name: Setup Node.js
        uses: actions/setup-node@v3
        with:
          node-version: "lts/*"
      - uses: pnpm/action-setup@v2
        with:
          version: 7
      - name: Install dependencies
        run: pnpm install
      - name: Release
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
        run: npx semantic-release

上記のコードをそのまま使えます
ci を作ったら github に push して、ci を動かしてみましょう
この時 commit メッセージは以下と同じにしてください

git add .
git commit -m 'chore: setup semantic release
git push

ci の結果を見ると全てパスをしています。
ただ、肝心な package が公開されていないです。

[3:16:39 PM] [semantic-release] › ✔ Completed step "verifyConditions" of plugin "@semantic-release/npm"
[3:16:39 PM] [semantic-release] › ℹ Start step "verifyConditions" of plugin "@semantic-release/github"
[3:16:39 PM] [semantic-release] [@semantic-release/github] › ℹ Verify GitHub authentication (https://api.github.com)
[3:16:39 PM] [semantic-release] › ✔ Completed step "verifyConditions" of plugin "@semantic-release/github"
[3:16:39 PM] [semantic-release] › ℹ Found git tag v1.0.0 associated with version 1.0.0 on branch master
[3:16:39 PM] [semantic-release] › ℹ Found 1 commits since last release
[3:16:39 PM] [semantic-release] › ℹ Start step "analyzeCommits" of plugin "@semantic-release/commit-analyzer"
[3:16:39 PM] [semantic-release] [@semantic-release/commit-analyzer] › ℹ Analyzing commit: chore: package version to 1
[3:16:39 PM] [semantic-release] [@semantic-release/commit-analyzer] › ℹ The commit should not trigger a release
[3:16:39 PM] [semantic-release] [@semantic-release/commit-analyzer] › ℹ Analysis of 1 commits complete: no release
[3:16:39 PM] [semantic-release] › ✔ Completed step "analyzeCommits" of plugin "@semantic-release/commit-analyzer"
[3:16:39 PM] [semantic-release] › ℹ There are no relevant changes, so no new version is released.

github actions のログをみてみるとThere are no relevant changes, so no new version is released.と書いてあり、パッケージが公開されてそうにありません

https://github.com/semantic-release/semantic-release/issues/192
調べてみるとcommit analyzerはコミットメッセージにfeat又はfixがないとバージョンをあげてくれないそうです。
試しにfeatをつけてからコミットをしてみます

git commit --allow-empty -m 'feat: release'
git push

無事リリースノートとパッケージが公開されました!
https://github.com/nozomi-iida/semantic-release-tutorial/releases/tag/v1.1.0
https://www.npmjs.com/package/semantic-release-tutorial

npm にパッケージを公開した場合自分のアイコンをクリックして、packagesをクリックすると確認することができます

CHANGELOG を作成する

パッケージを公開するという目的は達成したのですが、最後に Changelog を作ってみましょう
Changelog とはバージョンごとにどのような変更があったのかをまとめるテキストのことを指します。
これもsemantic-releaseを使うと自動化することができます

  1. @semantic-release/changelogというプラグインをインストールする
    @semantic-release/changelog@semantic-release/gitという公式プラグインをインストールします
    @semantic-release/git は changelog で作成したファイルをコミットするためにいれます
npm install @semantic-release/changelog @semantic-release/git -D
  1. 設定ファイルを作成し、設定を書く
touch .releaserc.yml

.releaserc.ymlというファイルを作成し、設定を書きます

.releaserc
{
  "plugins": [
    "@semantic-release/commit-analyzer",
    "@semantic-release/release-notes-generator",
    [
      "@semantic-release/changelog",
      {
        "changelogFile": "docs/CHANGELOG.md"
      }
    ],
    "@semantic-release/npm",
    [
      "@semantic-release/git",
      {
        "assets": ["docs/CHANGELOG.md"]
      }
    ]
  ]
}

https://github.com/semantic-release/changelog#usage

ほとんど公式通りにすれば問題ないです。
注意点としてはプラグインの順番で、@semantic-release/changelogを記述した後に@semantic-release/npm@semantic-release/gitを記述してください
これで再度 github に push されると CHANGELOG が自動で出来上がっています

https://github.com/nozomi-iida/semantic-release-tutorial/blob/master/docs/CHANGELOG.md

いかがだったでしょうか?
手動だと tag を作って、リリースノートを作って、changelog を作ってとかなり手間になり、適当になってしまうと思います。
しかし、semantic-releaseを使うことでそれらの作業を全て自動化することができました!
みなさんも package を作成するときは是非使ってみてください!

GitHubで編集を提案

Discussion