GitHub Actionsの中で生成したファイルをブランチに登録する
この記事について
というわけで、前回の記事で作成したツールをGitHub Actionsに組み込んで自動化したいと思います。
今回の目標
やりたいのは、インプットとなるMarkdownの記事ファイルを作業用ブランチにプッシュした際、
GitHub Actionsのワークフローが動いて、同ブランチに生成した画像がプッシュされる仕組みを作ることです。
最初に成果物
GitHub Actionsは、以下の手順を踏めば簡単に有効化できます。
- リポジトリに
.github/workflows
ディレクトリを作成する - ワークフローの処理を
yaml
形式のファイルに定義したものを、.github/workflows
ディレクトリに登録する
今回はこんな感じのyaml
ファイルを作りました。
name: Main CI
on:
push:
branches:
- 'article/**'
paths:
- 'articles/**'
- '.github/**'
jobs:
parse-markdown:
runs-on: ubuntu-latest
container:
image: mcr.microsoft.com/playwright/python:v1.30.0-focal
steps:
- name: setting playwright container
run: |
pip install markdown
git clone https://github.com/googlefonts/zen-marugothic.git
cp ./zen-marugothic/fonts/ttf/ZenMaruGothic-Regular.ttf /usr/local/share/fonts/
- name: Checkout
uses: actions/checkout@v3
with:
fetch-depth: 0
token: ${{ secrets.PERSONAL_ACCESS_TOKEN }}
- name: safe dirctory
run: git config --global --add safe.directory $(pwd)
- name: generate conversation image
run: |
ARTICLE_LIST=$(git diff --name-only origin/main...HEAD | grep articles/article_)
for ARTICLE in ${ARTICLE_LIST}; do
python3 playwright/markdown/markdown_parser.py ${ARTICLE}
done
- name: push generated image
run: |
git config user.name auto-push
git config user.email auto-push@example.com
git add .
git commit -m "auto push from ci" || echo no commits
git push
各設定について
ワークフローの起動設定
on:
push:
branches:
- 'article/**'
paths:
- 'articles/**'
- '.github/**'
記事を作成する際は、article/xxxx
といった命名ルールにしようと決めたので、そのブランチに対してpush
を実施した際、起動するようにしました。
push
以外にも色々なイベントを起因に起動設定が可能です!
また、最終的にはimages/
ディレクトリ配下に画像ファイルをpush
するので、再び起動条件に一致してしまうのを防ぐためpaths
を使用しています。
また、yaml
のメンテナンス時にも動作確認したいので、.github/
ディレクトリも追加しています。
ジョブ実行環境の設定
ワークフローで実行する処理の単位をジョブと呼びます。
そのジョブを実行する環境の定義を以下のように記述。
jobs:
parse-markdown:
runs-on: ubuntu-latest
container:
image: mcr.microsoft.com/playwright/python:v1.30.0-focal
ジョブを実行するサーバであるランナーのOSをこれらの中から選択して指定します。
とりあえずLinuxであれば良いので、Ubuntu
の最新版を選択。
またcontainer
を設定することで、ランナー上にコンテナが起動され、そのコンテナ上でジョブを実行するという設定も可能です。
今回はPlaywrightの公式イメージをそのまま利用することで、Playwright環境を構築手間を省きました。
各ジョブの詳細
steps
の配下にジョブをリストで記述していきます。
追加のインストール
- name: setting playwright container
run: |
pip install markdown
git clone https://github.com/googlefonts/zen-marugothic.git
cp ./zen-marugothic/fonts/ttf/ZenMaruGothic-Regular.ttf /usr/local/share/fonts/
run
に記述したコマンドがジョブで実行されます。
ここでは、Playwrightのコンテナに足りないライブラリとGoogleフォントを追加。
リポジトリのソースを取得
GitHub Actionsの利点として、別リポジトリのワークフローを利用することで、自分で処理を記述しなくても良いという、ライブラリ的な使い方ができます。
- name: Checkout
uses: actions/checkout@v3
with:
fetch-depth: 0
token: ${{ secrets.PERSONAL_ACCESS_TOKEN }}
ここでは、公式で準備されているcheckout
を利用して、リポジトリのソースコードをランナーにダウンロードします。
また最終的に、画像生成したものをpush
するので、リポジトリに対してpush
する権限が必要となります。そのため、予めPersonal Access Tokenを作成します。それをシークレットに登録しておきtoken
に設定。
safe directoryの設定
checkout
したランナー上のローカルリポジトリの中でgit操作をしようとすると、以下エラーがでます。
warning: Not a git repository
Gitのセキュリティ脆弱性対策っぽいです。そのため、次のコマンドを実行しておく必要があります。
- name: safe dirctory
run: git config --global --add safe.directory $(pwd)
参考:https://git-scm.com/docs/git-config/2.40.0
これらの設定項目は、Git で追跡されたディレクトリが現在のユーザー以外によって所有されていても安全であるとみなされるように指定します。
メイン処理
- name: generate conversation image
run: |
ARTICLE_LIST=$(git diff --name-only origin/main...HEAD | grep articles/article_)
for ARTICLE in ${ARTICLE_LIST}; do
python3 playwright/markdown/markdown_parser.py ${ARTICLE}
done
- name: push generated image
run: |
git config user.name auto-push
git config user.email auto-push@example.com
git add .
git commit -m "auto push from ci" || echo no commits
git push
工夫ポイントとしては
-
git diff
コマンドを使って、更新がかかったMarkdownファイルを抽出してツール実行している - ツールで画像生成しなかった場合、
git commit
が失敗するので||
でecho
を繋げてジョブがエラーにならないようにする
となります。
まとめ
GitHub Actionsでツール実行を自動化しました。
yamlファイル作成するだけなので簡単ですよね!
ただ、完成するまではトライ&エラーでワークフローを動かしまくる必要があるので、ワークフロー自体のデバッグはもっと効率化したいところです。
そこで、ローカル端末上でワークフローを実行できるactというツールがあったり、そもそもGitHub Actionsに依存しない自動化処理を作成できるdaggerというツールが流行ってるので、今後使い勝手を見ていけたらなと思ってます!
Discussion