ぺのめも

Web開発を勉強中。学んだことや思ったことなど

個人開発のプロジェクトにtagprを導入した

はじめに

個人でRuby on Railsのサービス開発を始めており、CIの構築の中でtagprを導入しました。導入にあたって設定したことを記録しておきます。
tagprのおかげでCIが快適になりいい感じです。ありがとうございます!

tagprリポジトリgithub.com

tagprの作者の方のリリースブログ: songmu.jp

やりたいこと

今回のプロジェクトでは下記のようなブランチ運用にしたく、やり方を検討していたところ tagpr を見つけました。

  • mainブランチと、各featureブランチのみで運用
    • featureブランチはmainへのマージ後に削除
  • mainブランチにfeatureブランチがマージされたら、ステージング環境へデプロイ
  • mainブランチにタグを打ったら、本番環境へデプロイ
    • どのコミットまでをリリースに含めるかを決めたら、タグを打つまでは追加でマージしないようにする

自分がこのような運用にしたかった背景・CI設定の全体については、こちらの記事に記載しています。

peno022.hatenablog.com

導入結果

PRの確認を経てmainにfeatureがマージされると、

  • リリースブランチの作成
  • CHANGELOGの更新
  • PRの作成

を自動で実行してくれます。 PRをマージすると、mainに該当バージョンのタグが打たれ、デプロイできる状態になります。
OSSのリリース作業の属人性を下げることを主な動機として開発されたアクションとのことですが、個人開発であっても快適です。

ワークフローファイル(完成版)

リポジトリに記載のサンプルコードを参考に、tagpr 実行のワークフローファイルを作成しました。
最終的なコードは下記になります。

# .github/workflows/tagpr.yml

name: tagpr
on:
  push:
    branches:
      - main

jobs:
  tagpr:
    runs-on: ubuntu-latest
    outputs:
      tagpr-tag: ${{ steps.run-tagpr.outputs.tag }}
    env:
      GITHUB_TOKEN: ${{ secrets.GH_PAT }}
    steps:
      - name: Check out source code
        uses: actions/checkout@v3
        with:
          token: ${{ secrets.GH_PAT }}

      - id: run-tagpr
        name: Run tagpr
        uses: Songmu/tagpr@v1

  release:
    needs: tagpr
    if: needs.tagpr.outputs.tagpr-tag != ''
    runs-on: ubuntu-latest
    env:
      GITHUB_TOKEN: ${{ secrets.GH_PAT }}
    steps:
      - name: Check out source code
        uses: actions/checkout@v3
        with:
          token: ${{ secrets.GH_PAT }}
      - name: Trigger release action
        uses: ./.github/actions/release

調べた箇所

リポジトリの許可Actionに登録する

リポジトリSettings > Actions > Generalの Actions permissions の設定を修正しました。
自分で追加したactionsか、GitHub認証済みのactionsのみ利用できる設定にしていたため、許可するactionsにtagprを追加しています。

後続のワークフローをトリガーできない問題

tagprのサンプルコードだとsecrets.GITHUB_TOKENを使っているのですが、このトークンを利用した場合、後続のワークフローのトリガーができません。(pushしたらCIのワークフローを起動する、等)

自分の場合は、リリース用PRについても「CIが通ったことを確認してマージ」としたかったので、GITHUB_TOKENを使うのをやめて、personal access tokenを利用することにしました(secrets.GH_PAT)。
PATを使うと、後続アクションをトリガーできるようになります。(ただし、PATには有効期限を適切に設定・更新する必要があったり、流出に注意が必要であったりと、GITHUB_TOKENと違って自分で管理する手間がかかるという面もあります)

personal access token を発行する

personal access tokenは、
Settings > Developper settings > Personal access tokens > Fine-grained tokens
から作成することができます。

Fine-grained tokens について少し調べると、2022年10月に発表された比較的新しい機能でした。
従来のトークンは発行者がアクセスできる全リポジトリに対して使えていましたが、Fine-grained tokens は、対象とする組織・リポジトリを選択することができるという点で、より「きめ細かい」トークンであるということのようです。

github.blog

docs.github.com

トークンの権限設定をする

トークンを作成したら、Permissions の項目を設定します。
tagprの実行には、下記の権限設定が必要でした。

  • Actions
    • Read and write
  • Contents
    • Read and write
  • Metadata
    • Read-only
      • mandatoryと表示され、Actions に Read and write 権限を付与すると自動的にこちらも設定されます
  • Pull requests
    • Read and write

最初にActionsの Read and write 権限だけを設定して実行したら、下記ログのように権限エラーが出たので、必要な権限を追加していった形です。

POST https://api.github.com/repos/peno022/kpi-tree-generator/releases/generate-notes  403 Resource not accessible by personal access token [] 


どのAPIにどの権限が必要かは、こちらのドキュメントに一覧でまとまっているため、ここを見ながら権限設定をしました。

docs.github.com

トークンをリポジトリに登録してワークフローで利用する

リポジトリSettings > Security > Secrets and variables > Actionsから、作成したトークンを登録します。
項目名に任意の名前(今回はGH_PAT)をつけ、Valueには生成したトークンの文字列をペーストして、登録完了です。


リリースのジョブをactionsへの切り出す

「タグが打たれたら本番環境にデプロイする」という部分について、デプロイの実行を./.github/actions/releaseに切り出しています。

      - name: Trigger release action
        uses: ./.github/actions/release

製作者の方のリリースブログに記載があった、 tagprのワークフローが途中で意図せず失敗してしまった場合に、リリースフローをリカバリするために手動でタグを打つワークフローを別途用意しやすくなる という利点のため、このようにしました。

actionsの構文について補足

workflow間に共通するようなジョブを切り出す際には、workflowではなくactionsとして作る必要があり、構文のルールがworkflowとは少し違っています。 下記のような条件があるので、注意が必要でした。

  • .github/actions/[任意のアクション名]/action.ymlというパス・ファイル名にする
  • workflowの場合は必須である、トリガーイベント、ランナーの指定は不要
  • using: "composite"の記述が必須
  • shell の指定が必須

参考: zenn.dev zenn.dev

公式ドキュメント:

docs.github.com

docs.github.com

GitHub アプリのレート制限エラー

403 You have exceeded a secondary rate limit. Please wait a few minutes before you try again. 

頻繁にリクエストを送りすぎると、一時的な制限がかかって出るエラーのようです。動作確認のために繰り返し実行していたタイミングで、一度だけ出ました。
メッセージに記載があるように、数分待ってからジョブの Rerun を行ったら解消しました。

docs.github.com