📦

NPMパッケージバージョンを常に最新に保つ!GitHub Actionsで自動チェック&Issue作成

2024/09/24に公開

とりあえずコード

毎月1日にnpmで管理しているパッケージのバージョンをチェックし、最新になっていないパッケージがある場合にはIssueを作成するようなGithub Actionsです

name: Check npm packages version on the first day of the month

on:
  schedule:
    - cron: "0 0 1 * *"

jobs:
  check-npm-version:
    name: Check npm packages version
    runs-on: ubuntu-latest
    steps:
      - name: Checkout repository
        uses: actions/checkout@v3

      - name: Setup Node.js
        run: |
          npm install

      - name: Check if there is outdated packages and set an environment variable
        id: outdated-check
        run: |
          if [ "$(npm outdated --json || echo '{}')" != "{}" ]; then
            echo "Outdated packages found."
            echo "outdated=true" >> $GITHUB_ENV
          else
            echo "No outdated packages." && exit 0
          fi

      - name: Create GitHub issue body as a markdown file
        if: env.outdated == 'true'
        run: |
          echo "| Package | Current Version | Latest Version |" > issue_body.md
          echo "|---------|-----------------|----------------|" >> issue_body.md
          npm outdated --json || echo "{}" | jq -r '. | to_entries | .[] | "| \(.key) | \(.value.current) | \(.value.latest) |"' >> issue_body.md

      - name: Create GitHub issue
        if: env.outdated == 'true'
        uses: peter-evans/create-issue-from-file@v4
        with:
          title: "新しいバージョンのパッケージに更新してください"
          content-filepath: ./issue_body.md

はじめに

最近はTypeScriptを使ったフロントエンド開発をメインに取り組んでいるエンジニアです。先日、長期プロジェクトの納品に向けて作業していた際、プロジェクト期間中にいくつかのパッケージが古いまま放置されていることに気づきました。知らず知らずのうちに技術的負債が重なっていたようで、だいぶ痛い目を見ました😭

そこで、「新しいバージョンのパッケージが出た際に、アラートや通知を自動であげてくれる仕組みがあれば便利なのでは?」と考えたのが今回の開発を行った動機です。既存のソリューションもあるかもしれませんが、GitHub ActionsやCI/CDに触れる機会がこれまでなかったため、勉強も兼ねて自分で1から構築してみました。

調査

まずは調査です。GithubActionsの設定方法は知っていましたが、スケジューリングを行ったり、Issueを作ったりする方法、packageのバージョンチェックに最適な方法がわからなかったので調べてみました。下記のような内容が参考になりそうです。

Issueを作る方法に関しては既存のものを使うのがよさそうです。

コードの解説

調査の結果、簡単にできそうだったのでそれぞれを組み合わせることで今回やりたかったことは達成できそうです。完成系のコードはすでに冒頭で紹介しているので、ここからはコードについて簡単に解説です。

スケジューリング

on:
  schedule:
    - cron: "0 0 1 * *"

Github Actionsのスケジュールを行う部分です。cronに適切な値を設定することで特定の日時にGithubActionsを発火させることができます。

分 時 日 月 曜日

上記はcronに渡す値の詳細です。今回の場合は毎月1日に発火させたいので、「日」の箇所に1を設定し、曜日や月については全てという意味の「*」を設定しています。
例えば、毎週月曜日朝の8時に発火させたい場合は0 8 * * 1になります

古いバージョンのパッケージがないかチェック

      - name: Setup Node.js
        run: |
          npm install

      - name: Check if there is outdated packages and set an environment variable
        id: outdated-check
        run: |
          if [ "$(npm outdated --json || echo '{}')" != "{}" ]; then
            echo "Outdated packages found."
            echo "outdated=true" >> $GITHUB_ENV
          else
            echo "No outdated packages." && exit 0
          fi

上記の部分で、古くなっているパッケージがないかどうかをチェックしています。まずはsetUpの箇所でレポジトリ内で使われているパッケージをインストールしています。npm outdatedを使用するためにはこの処理が必要になります。
次に実際に古いpackageがないかの確認です。確認にはnpm outdatedを使用し、もし、古いバージョンを使っているpackageがある場合にはaction内で有効な変数を設定しています。
IDを使う方法を試したのですが、現状は変数を使用する方がGithubのおすすめになっていました。

Issueのbody部分の作成

      - name: Create GitHub issue body as a markdown file
        if: env.outdated == 'true'
        run: |
          echo "| Package | Current Version | Latest Version |" > issue_body.md
          echo "|---------|-----------------|----------------|" >> issue_body.md
          npm outdated --json || echo "{}" | jq -r '. | to_entries | .[] | "| \(.key) | \(.value.current) | \(.value.latest) |"' >> issue_body.md

この部分ではIssueのbodyに当たるmdファイルを作成しています。古いバージョンのパッケージが見つかった場合のみ、実行できるようにif文で制御を行っており、現在使っているバージョンと最新バージョンを表形式で記録しています。この部分に関しては好みだと思うので、markdown形式で適当に変更していただくとよりリッチなIssueが出来上がると思います。

Issueの作成

      - name: Create GitHub issue
        if: env.outdated == 'true'
        uses: peter-evans/create-issue-from-file@v4
        with:
          title: "新しいバージョンのパッケージに更新してください"
          content-filepath: ./issue_body.md

実際に前工程のmdファイルを使用して、Issueを作っています。mdファイルを用いたIssueを作成できるパッケージがすでにあったのでそちらを活用させていただいています。
タイトルとbodyに値するmdファイルを渡すだけで簡単にできました。

実際にできたIssueは下記のようになります。Expoを使用したReact-Nativeを使用したレポジトリに対して下記のようなIssueが作られました。

まとめ

お疲れ様でした。意外と簡単にできましたが、これで「毎月npmで管理しているパッケージのバージョンを確認する」という部分を自動化できました。最新版のパッケージに常にしておくかどうかはプロジェクトの方針によると思いますが、アラートを上げるという意味では良いのかなと思いました。
弊社の場合は月に一度技術負債返済日を設けており、普段後回しになっているIssueを解決する日があります。技術負債返済日の前日に上記のActionsが走るようにしておくことで負債を溜めすぎないようにできるのかなと思います。

NCDCエンジニアブログ

Discussion