GitHub publish release 時にファイルのバージョンを更新する

GitHub Actions を使って、publish release 時に独自管理ファイルと package.json のバージョンを更新するようにしてみました。
2021.02.26

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

最近、GitHub の publish release を契機にファイルのバージョンを更新するワークフローを構築する機会があったので、その手順をまとめました。

なぜ必要なのか

担当プロジェクトで GitHub Flow に近い形のリリースフローを構築しました。

一方で master へのマージを即デプロイとはせず、ある程度の塊をリリースバージョンとして管理したいという事情があったため、 GitHub で Publish release を実施したタイミングでバージョンを設定し、そのバージョンで管理ファイルを更新するような ワークフローとしました。

リポジトリのリリースを管理する - GitHub Docs

実際のプロジェクトでは、後段として自動デプロイも実施しますが、今回の記事では割愛します。

ワークフローの構築

publish release に対応するイベント

Publish release を契機としてワークフローを実行するには、release イベントの published アクティビティタイプを利用します。

Events that trigger workflows - GitHub Docs

独自管理ファイルの更新

運用の都合上、以下のようなファイルでバージョンを管理しています。

export const GLOBAL = {
    VERSION: 'v0.2.0',
};

VERSION の値 v0.2.0 を publish release 時に設定したバージョンで上書きしたいです。

何か既製コマンドで対応出来ないか調べてみましたが、結局以下のように処理することにしました。

LATEST_VERSION=$(git tag --sort=-creatordate | head -1)
sed -e "s/VERSION: '\(.*\)',/VERSION: '$LATEST_VERSION',/" src/global.js > tmpfile && mv tmpfile src/global.js

実際は LATEST_VERSION を複数のステップで使用したいので ::set-output コマンドを使って設定しています。

GitHub Actionsのワークフローコマンド - GitHub Docs

package.json, pakcage-lock.json の更新

npm version で対応します。

npm-version | npm Docs

LATEST_VERSION=$(git tag --sort=-creatordate | head -1)
npm --no-git-tag-version version $LATEST_VERSION

ポイントは --no-git-tag-version を付けることで、ファイルの更新のみ行い、タグ付けを行わないようにします。 (タグ付けは publish release 時に自動的に行われるため)

コミット

上記で更新したファイルをコミットします。

ワークフロー内でコミットするために、以下を利用しました。

ワークフロー全体

veevalidate-test/publish_release.yml at master · teknocat/veevalidate-test

.github/workflows/publish_release.yml

name: "Publish release"
on:
  release:
    types: [published]

jobs:
  build:
    runs-on: ubuntu-18.04
    steps:
      - uses: actions/checkout@v2
      - uses: actions/setup-node@v1
        with:
          node-version: '12.x'

      - name: Install dependencies
        run: npm install

      - name: Get latest version
        id: get_version
        run: |
          LATEST_VERSION=$(git tag --sort=-creatordate | head -1)
          echo ::set-output name=LATEST_VERSION::$LATEST_VERSION

      - name: Update global.js
        run: |
          sed -e "s/VERSION: '\(.*\)',/VERSION: '${{ steps.get_version.outputs.LATEST_VERSION }}',/" src/global.js > tmpfile && mv tmpfile src/global.js

      - name: Update package.json
        run: |
          npm --no-git-tag-version version ${{ steps.get_version.outputs.LATEST_VERSION }}

      - name: Commit updates
        uses: EndBug/add-and-commit@v7
        with:
          branch: master
          message: "Bump version: ${{ steps.get_version.outputs.LATEST_VERSION }}"
          add: "['src/global.js', 'package.json', 'package-lock.json']"

publish release の実施

GitHub 上で publish release を実施します。

Create a new release を選択します。

必要な情報を入力して Publish release を選択すると、リリースが作成されます。

ワークフローが実行されます。

管理ファイルが更新されます。

課題

バージョンタグを付けてからファイルの更新が発生しているため、厳密にはタグの位置が最新になっていません。 コミットのタイミングでタグを付け直す処理を入れた方が良いかもしれません。

最後に

master -> main への移行は今後実施予定です…。

例によって、上記確認出来るソースを以下リポジトリに置いています。