概要
- CircleCIを使用して週1で自動実行していたbundle updateを、GitHub Actionsに移行した際に行ったことのメモ
- CircleCIを使用していたときはcircleci-bundle-update-prというGemを使用させていただき、bundle update自動実行→プルリクエスト自動作成を実現していた
- circleci-bundle-update-prは、名前の通りCircleCIでの使用を目的に作成されているように見受けられたGemだが、READMEを見ていたらGitHub Actionsで動かすためのexampleも記載されていた
- Dependabot等の別ツールへの移行コストや運用コストを考えたときに、こちらを使用し続けるほうが良いという判断に至ったため、GitHub ActionsでもこちらのGemを引き続き使用させていただくことにした
作成した結果、以下のようなbundle updateを行ったプルリクエストを毎週決まった日時に自動作成できるようになっている
以下詳細を記載
作成したワークフロー
- exampleでも十分動くので大した変更はしていないが、幾つか変更した箇所はあるので以下に記載
bundle-update-pr.yaml
name: bundle-update-pr
on:
schedule:
- cron: "00 22 * * 3" # JST 07:00 (Thu)
jobs:
create_bundle_update_pr:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: libgsl-dev Install
run: |
if ! dpkg -l | grep -q "libgsl-dev"; then
echo "Package not found. Installing..."
sudo dpkg -i vendor/packages/gsl_2.3-1_amd64.deb
else
echo "Package already installed. Skipping installation."
fi
- name: Get Ruby Version
id: ruby
run: echo "ruby-version=$(cat .ruby-version)" >> $GITHUB_OUTPUT
- name: Set up Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: ${{ steps.ruby.outputs.ruby-version }}
- name: Install dependencies
run: |
set -x
gem install -N bundler circleci-bundle-update-pr
- name: Set timezone to Asia/Tokyo
run: |
set -x
cp /usr/share/zoneinfo/Asia/Tokyo /etc/localtime
- name: Create GitHub Apps Token
id: github_apps
uses: actions/create-github-app-token@v1
with:
app-id: ${{ secrets.APP_ID }}
private-key: ${{ secrets.PRIVATE_KEY }}
- name: run circleci-bundle-update-pr
run: |
set -x
export CIRCLE_BRANCH=$(echo $GITHUB_REF | sed -e 's!refs/heads/!!g')
export CIRCLE_PROJECT_USERNAME=$(echo $GITHUB_REPOSITORY | cut -d "/" -f 1)
export CIRCLE_PROJECT_REPONAME=$(echo $GITHUB_REPOSITORY | cut -d "/" -f 2)
circleci-bundle-update-pr "${GIT_USER_NAME}" "${GIT_USER_EMAIL}"
env:
GITHUB_ACCESS_TOKEN: ${{ steps.github_apps.outputs.token }}
GIT_USER_NAME: "YOUR USER NAME"
GIT_USER_EMAIL: "YOUR USER EMAIL"
Get Ruby Version
- name: Get Ruby Version
id: ruby
run: echo "ruby-version=$(cat .ruby-version)" >> $GITHUB_OUTPUT
-
ruby/setup-ruby@v1
で使用するruby-versionは固定ではなく、アプリケーションの.ruby-version
のバージョンに準拠するようにしたかったため、バージョンを取得するステップを追加
※追記→コメント欄で@takaram様にご指摘いただきましたが、ruby/setup-ruby
はバージョン指定しなければ自動で.ruby- version
ファイルを読んでくれるとのこと
https://github.com/ruby/setup-ruby#supported-version-syntax
ご指摘いただありがとうございます!
Create GitHub Apps Token
- name: Create GitHub Apps Token
id: github_apps
uses: actions/create-github-app-token@v1
with:
app-id: ${{ secrets.APP_ID }}
private-key: ${{ secrets.PRIVATE_KEY }}
- このワークフローが適用されるアプリケーションは、ブランチにpushが発生した場合にRspecや静的解析が回るという別のワークフローが実装されており、このワークフローを通過しないとブランチをマージできない仕様になっている
- ただ、デフォルトのままこのGemを使用して作成されるプルリクエストは、作成者が
github-actions
というbotになり、botの場合、別のCIをキックしないという仕様があったため、このテストワークフローを回すことができず、bundle updateのプルリクエストをマージすることもできなかった - そのためGitHub Appsトークンを作成して、そのトークンをアクセストークンとして渡すことで、作成者をbotではなく開発者自身としてプルリクエスト作成を実行できるようにした
- actions/create-github-app-token: GitHub Action for creating a GitHub App Installation Access Tokenというアクションを使用することで簡単に作成できる
- 詳しいGitHub Appsトークンの作成方法は割愛
- Personal Access Tokenはセキュリティ的に非推奨っぽいので使用しなかった
- GitHub Appsトークンを渡した結果、作成者が
github-actions
という名前から渡したトークン名(ここではnitta-test-2)に変化していた
libgsl-dev
- name: libgsl-dev Install
run: |
if ! dpkg -l | grep -q "libgsl-dev"; then
echo "Package not found. Installing..."
sudo dpkg -i vendor/packages/gsl_2.3-1_amd64.deb
else
echo "Package already installed. Skipping installation."
fi
- 動かしている環境では特定のDebianパッケージファイルがないとbundle installが動かないため追加