1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

GitHub ActionsAdvent Calendar 2023

Day 17

アプリケーションに記載のAPPのバージョンをGitHub Actionsで自動で更新する

Last updated at Posted at 2023-12-16

フロントエンドはReact.js, バックエンドはRailsでAPIとして利用しているような環境で働いています。

フロントエンドを新しくリリースしたが、ブラウザキャッシュやCDNがキャッシュを返していてリリースされたバージョンが反映されていないかも!?
みたいなことが最近ありました。

で、このときの調査が大変だったので、ユーザーが見ているバージョンは何であるかわかるようにしたいなとか考えました。

ってことで

  • フロントエンドはpackage.jsonに記載のバージョンを自動で更新させよう
  • APIでも、現在のバージョンを返すAPIを生やしておこう

としました。
このバージョンを、GitHub Actionsを使って自動で更新させたら便利だったので紹介です。

完成系はこんな感じです

スクリーンショット 2023-12-09 22.57.28.png

スクリーンショット 2023-12-09 22.58.01.png

やること

前提ですが、自分はGitHubのリリース機能を利用しています。
Releaseがpublished(公開)されたら、リリースフローが走る、という流れです。

なので、リリースががされたら、次のバージョンに更新するCIを動かすことにしました。

フロントエンド

いきなりCIを書いてしまいます。

.github/workflows/update-version.yml

name: Update Version

on:
  release:
    types: [published]

jobs:
  update-version:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v4
        with:
          ref: main

      - name: Set up Git user
        run: |
          git config user.name github-actions
          git config user.email github-actions@github.com
    
      - name: Update version file
        run: |
          npm version patch

      - name: push
        run: git push

それほど難しないですね。
バージョンの更新は、 npm version patch で行っています。
このコマンドを実行をすると、

  • package.jsonのバージョンが更新される
  • package-lock.jsonのバージョンが更新される
  • バージョン名のコミットが作成される

と上記の3つが行われます。

ここからは余談

ここで更新されたバージョンをReact.jsでも表示させてあげたかったので、それもやってしまいます。
自分はWebpackを利用しているので、その場合で書きます。

webpack.config.js

const webpack = require("webpack");

module.exports = {
  ...,
  pluguins: [
    ...,
    new webpack.DefinePlugin({
      "process.env.APP_VERSION": JSON.stringify(
        process.env.npm_package_version,
      ),
    }),
  ],
}

process.env.npm_package_versionでバージョンは取得できるので、それを環境変数に組み込むようなコードです。

これを書いておけば、アプリケーション側で、以下のようなコードでバージョンが表示されます。

<strong>App Version:</strong> {process.env.APP_VERSION}

自分の場合は、こんな感じでユーザーのブラウザの情報を表示させる画面とか作っています。そこに載せました。

スクリーンショット 2023-12-09 23.13.53.png

バックエンド

こっちは npm run patchのようなコマンドがないので、もう少し工夫が必要です。

まず、バージョンを管理しているファイルはここです。

lib/version.rb

module YourAppName
  VERSION = "1.1.41".freeze
end

Controller側でこのようにして表示していますね。

require "version"

class Api::VersionsController < Api::BaseController
  def show
    render json: { version: YourAppName::VERSION }
  end
end

スクリーンショット 2023-12-09 22.58.01.png

で、CI側では lib/version.rb

module YourAppName
  VERSION = "1.1.41".freeze
end

ここのVERSIONの値を更新させます。

実際のCI

詳しく見ていきます。

name: Update Version

on:
  release:
    types: [published]

jobs:
  update-version:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v4
        with:
          ref: main
          fetch-depth: 0

      - name: Get latest version
        id: get_version
        run: |
          LATEST_VERSION=$(git tag --sort=-creatordate | head -1 | sed 's/^v//')
          echo "Latest version: $LATEST_VERSION"
          echo "::set-output name=version::${LATEST_VERSION}"

      - name: Calculate next version
        id: calc_next_version
        run: |
          # バージョン番号を分割(例: 1.0.0 -> 1, 0, 0)
          echo "Version: ${{ steps.get_version.outputs.version }}"
          IFS='.' read -ra VERSION_PARTS <<< "${{ steps.get_version.outputs.version }}"
          MAJOR=${VERSION_PARTS[0]}
          MINOR=${VERSION_PARTS[1]}
          PATCH=${VERSION_PARTS[2]}
          echo "Major: $MAJOR, Minor: $MINOR, Patch: $PATCH"

          # パッチバージョンをインクリメント
          let PATCH+=1

          # 次のバージョンを計算
          NEXT_VERSION="$MAJOR.$MINOR.$PATCH"
          echo "Next version: $NEXT_VERSION"
          echo "::set-output name=next_version::${NEXT_VERSION}"
    
      - name: Update version file
        run: |
          sed -i "s/VERSION = \".*\"/VERSION = \"${{ steps.calc_next_version.outputs.next_version }}\"/" lib/version.rb

      - name: Commit and push
        run: |
          git config user.name github-actions
          git config user.email github-actions@github.com
          git add lib/version.rb
          git commit -m "Update version to ${{ steps.calc_next_version.outputs.next_version }}"
          git push

最初のStep(Checkout)

      - name: Checkout code
        uses: actions/checkout@v4
        with:
          ref: main
          fetch-depth: 0

これはいつもやるcheckoutです。
このとき、ref: mainにしておいて、mainブランチで動かすように明示しています。
また、git tagでタグ一覧も取得できるようにするため。fetch-depth: 0も書きます。

2番目のステップ(最新のバージョン取得)

      - name: Get latest version
        id: get_version
        run: |
          LATEST_VERSION=$(git tag --sort=-creatordate | head -1 | sed 's/^v//')
          echo "Latest version: $LATEST_VERSION"
          echo "::set-output name=version::${LATEST_VERSION}"

git tag --sort=-creatordate | head -1 このコマンドで、最新のバージョンを取得します。
またv1.0.0のように私はしているので、vを消すように置換しそれをLATEST_VERSIONという変数に入れます。

3番目のステップ(次のバージョン番号を作る)

      - name: Calculate next version
        id: calc_next_version
        run: |
          # バージョン番号を分割(例: 1.0.0 -> 1, 0, 0)
          echo "Version: ${{ steps.get_version.outputs.version }}"
          IFS='.' read -ra VERSION_PARTS <<< "${{ steps.get_version.outputs.version }}"
          MAJOR=${VERSION_PARTS[0]}
          MINOR=${VERSION_PARTS[1]}
          PATCH=${VERSION_PARTS[2]}
          echo "Major: $MAJOR, Minor: $MINOR, Patch: $PATCH"

          # パッチバージョンをインクリメント
          let PATCH+=1

          # 次のバージョンを計算
          NEXT_VERSION="$MAJOR.$MINOR.$PATCH"
          echo "Next version: $NEXT_VERSION"
          echo "::set-output name=next_version::${NEXT_VERSION}"

ここでやっていることは、

  1. 2番目のステップで取得した2.1.0のようなバージョンを、2と1と0に分割して、VERSION_PARTSという変数に入れます。
  2. パッチバージョンがあるVERSION_PARTS[2]の数字に1つ加えます(0 + 1をする)
  3. NEXT_VERSIONという変数にバッチバージョンを更新した状態で代入(2.1.1)が代入される

です。

4番目のステップ(lib/version.rbの更新)

      - name: Update version file
        run: |
          sed -i "s/VERSION = \".*\"/VERSION = \"${{ steps.calc_next_version.outputs.next_version }}\"/" lib/version.rb

sedを使って新しいバージョンへ置換するようにしています。

5番目のステップ(commitしてpush)

      - name: Commit and push
        run: |
          git config user.name github-actions
          git config user.email github-actions@github.com
          git add lib/version.rb
          git commit -m "Update version to ${{ steps.calc_next_version.outputs.next_version }}"
          git push

これで完成です。

おわりに

今回はリリースがされたら、というのをトリガーにして次のバージョンへの更新を行いました。
組織によってはリリースの流れが違うと思うので、その際はちょっとずつ変更しながら使ってください。

自分の組織では、ユーザーに届いているバージョンが確認できるようになったことは、とてもお問合せの際に役立つのでよかったなと思います。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?