はじめに
こんにちは m-hamashita です。
この記事は Gunosy Advent Calendar 2023 の 4 日目の記事です。 3 日目の記事は TksYamaguchi さんのいろんなやり方の読書会をやってみたら当日音読その場でまとめ方式が最高だった話でした。
今回はテックブログのレビューを GitHub 上でするようになって 1 年ほど経ったので、その経緯とリポジトリの紹介をしたいと思います。 個人的にかなり運用が楽になったので、ぜひ見てもらえると嬉しいです。
今までのブログレビュー
今まではブログ用の Slack チャンネルで有志にレビューをお願いし、スレッドでレビューをおこなっていました。
そこでは以下のような問題を感じていました。
- レビュー箇所をコピー&ペーストしてレビューするのが面倒
- レビュー内容が反映されないことがあった
- レビューされないまま公開される場合があった
- 毎回同じようなレビュー(例:スペースの使い方の統一)をおこなっていた
現在のブログレビュー
GitHub リポジトリでブログを管理することで、先述した問題の解決を試みました。 最近公式でテンプレートリポジトリが公開されたので、これからレビューリポジトリを作成する場合はこちらを使用し、この記事で使えそうな部分があればそれを取り入れるという形が良さそうです。
レビュー箇所を指定してレビューすることができるようになり、レビュー箇所をコピー&ペーストする必要がなくなりました。 また、commit suggestion を使うことで、レビューされた側の修正も楽になりました。
現在のレビューの流れは以下のようになっています。
main
ブランチからブランチを切る- はてなブログ上で下書きを作成し、カスタム URL を設定する
./pull
(後述)を実行して、下書き(markdown)を取得する- リモートにプッシュして、(完成していなければ draft で)Pull Request を出す
- markdown を編集して記事を書く
- プッシュすると CI によって下書きが同期される
- (画像アップロード等)はてなブログ上で編集した場合は、
./pull
(or./fetch
) を実行することで同期する
- 書ききったら Ready for Review にして、レビューを依頼する
- レビューが完了したら、記事を公開(予約投稿)する
ブログの同期
はてなブログとリポジトリの同期には blogsync を用いました。 blogsync は、はてなブログ用の CLI クライアントです。これを使うと、ブログのダウンロードや、更新などをおこなうことができます。
パッケージのインストールには aqua を使っています。今回インストールしたパッケージは以下のようになっています。
registries: - type: standard ref: v4.92.2 # renovate: depName=aquaproj/aqua-registry packages: - name: x-motemen/blogsync@v0.20.1 - name: stedolan/jq@jq-1.7 - name: a8m/envsubst@v1.4.2
blogsync では blogsync.yaml というファイルを用いて、はてなブログの設定をおこないます。 一方弊社ではテックブログとデータ分析ブログの 2 つのブログを運用しています。そのため、単一の blogsync.yaml では設定をおこなうことができず、少し工夫が必要でした。
ブログの取得
はてなブログ上にあるブログを取得する pull
は以下のようになっています。ここでは、はてなブログの API キーなどを Secrets Manager に保存しています。
先述したように 2 つのブログを運用しているため、今回は template ファイルと envsubst を用いて、ブログごとに設定を変えるようにしています。
#!/bin/bash set -e SECRET=$(aws secretsmanager get-secret-value --secret-id "techblog" | jq -r '.SecretString') export API_KEY=$(echo "$SECRET" | jq -r '.api_key') export USER_NAME=$(echo "$SECRET" | jq -r '.user_name') if [ "$#" -eq 1 ] && { [ "$1" == "data" ] || [ "$1" == "tech" ]; }; then envsubst < "${1}_blogsync.yaml.template" > blogsync.yaml blogsync pull "gunosy-${1}.hatenablog.com" rm blogsync.yaml elif [ "$#" -eq 0 ]; then envsubst < "data_blogsync.yaml.template" > blogsync.yaml blogsync pull "gunosy-data.hatenablog.com" rm blogsync.yaml envsubst < "tech_blogsync.yaml.template" > blogsync.yaml blogsync pull "gunosy-tech.hatenablog.com" rm blogsync.yaml else echo "Usage: $0 [data|tech]" exit 1 fi
上記で指定されている template ファイルは以下のようになっています。
gunosy-tech.hatenablog.com: username: ${USER_NAME} password: ${API_KEY} default: local_root: ./
リポジトリと下書きの同期
リポジトリを作成してすぐの頃は、手動で GitHub とはてなブログを同期していました。そうすると、GitHub 上では修正されているのに、はてなブログ上では修正されていなかったり、逆にはてなブログ上では修正されているのに、GitHub 上では修正されていなかったりすることがありました。
これを解消するために、Pull Request を作成すると CI によって、ブログの下書きが更新されるようにしました。これによって、レビューをおこなう際に GitHub と下書きの内容が同期されるようになりました。
以下は、(テック)ブログの下書きを更新する GitHub Actions の設定です*1*2。 これによって GitHub とはてなブログの下書きが同期され、手動で同期する必要がなくなり、上記の問題を解消することができました。
name: push to tech blog on: pull_request: paths: - gunosy-tech.hatenablog.com/entry/** jobs: push: name: push runs-on: ubuntu-latest env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} steps: - uses: actions/checkout@v3 - name: Get changed files id: changed-files-specific uses: tj-actions/changed-files@v35 with: files: gunosy-tech.hatenablog.com/entry/** - uses: aquaproj/aqua-installer@v2.0.2 with: aqua_version: v1.34.2 - name: Setup tech blogsync run: | echo "${{ secrets.TECH_BLOG_CONFIG_YAML }}" > blogsync.yaml - name: push blog to hatena blog run: | for file in ${{ steps.changed-files-specific.outputs.all_changed_files }}; do blogsync push $file done
余談ですが、pull
がすべてのブログを更新するのに対して、指定したブログのみを更新したいときに使う fetch
は以下のようになっています。
#!/bin/bash set -e SECRET=$(aws secretsmanager get-secret-value --secret-id "techblog" | jq -r '.SecretString') export API_KEY=$(echo "$SECRET" | jq -r '.api_key') export USER_NAME=$(echo "$SECRET" | jq -r '.user_name') tech_blog_pattern="*gunosy-tech.hatenablog.com/entry/*" data_blog_pattern="*gunosy-data.hatenablog.com/entry/*" if [ "$#" -eq 1 ] && [[ "$1" == $tech_blog_pattern ]]; then envsubst < "tech_blogsync.yaml.template" > blogsync.yaml blogsync fetch "$1" rm blogsync.yaml elif [ "$#" -eq 1 ] && [[ "$1" == $data_blog_pattern ]]; then envsubst < "data_blogsync.yaml.template" > blogsync.yaml blogsync fetch "$1" rm blogsync.yaml else echo "Usage: $0 <path/to/file>" exit 1 fi
textlint の導入
似たようなレビューを繰り返していたので、機械的に検知できる部分は CI に任せたいという思いがありました。 そこで、textlint を導入しました。 textlint は、テキストファイルの構文や文章の書き方をチェックするツールで、プラグインを利用することで、様々なチェックをおこなうことができます。
また、action-textlint を用いることで、 textlint の結果を Pull Request のコメントとして表示することができます。 自動修正可能なものについては変更を suggest してくれるため、修正も容易です。
以下に GitHub Actions の設定を示します。
name: reviewdog on: [pull_request] jobs: textlint: name: runner / textlint runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 with: submodules: true - name: textlint-github-pr-review uses: tsuyoshicho/action-textlint@v3 with: github_token: ${{ secrets.github_token }} reporter: github-pr-review level: warning textlint_flags: "**/*.md"
現在はルールをあまり設定していません。これはルールをたくさん設定すると、GitHub Actions のコメントで埋まってしまう & 人によって流儀が異なるといったことがあったため、いったん最低限の設定にしています*3。
導入した結果
導入した結果、過去のレビューの問題点がどのようになったか、また反省点について振り返ります。
- 問題点振り返り
- レビュー箇所をコピー&ペーストしてレビューするのが面倒
- → GitHub でレビューできるようになり、レビュー箇所を指定してレビューできるようになった
- commit suggestion を使うことで、修正も楽になった
- レビュー内容が反映されないことが多々あった
- →場所を指定してレビューできるので、修正されているか確認しやすくなった
- レビューされないまま公開される場合があった
- →(意識的な問題か)レビューされずに公開されることはなくなった
- 毎回同じようなレビューをおこなっていた
- → textlint で多少カバーできているが、まだ同じような指摘をおこなうことがある*4
- レビュー箇所をコピー&ペーストしてレビューするのが面倒
- 反省: 環境構築が難しい人がいた
- 全エンジニアが AWS CLI を入れていると思っていたがそうではなかった
- → README を手厚く書いたり、導入をサポートした。それでも難しい人のために、代替案を用意した
まとめ
今回は、ブログのレビューを GitHub リポジトリでおこなうことで、レビューの効率化をおこないました。 今後はブログレビューをより効率化するために以下のことをしていきたいと思っています*5。
- hatenablog-workflows などのエッセンスを取り入れる
- 下書き作成から pull までを一貫して実行
- textlint の設定を拡充する
- はてなブログに合わせたルールの自作
- ブランチルールによる draft Pull Request の自動作成
明日は hyamamoto さんが稼働中のデータ基盤を安全に dbt 移行する仕組みについて書くそうです!とても楽しみです!
*1:blogsync.yaml の取得に secrets コンテキストを用いていますが、 pull でおこなったように修正したいですね
*2:最近 blogsync に GitHub Actions が追加されていましたのでこちらを使うと良さそうです https://github.com/x-motemen/blogsync?tab=readme-ov-file#github-actions
*3:個人的に設定したいルールはたくさんあります
*4:ルールを実装しようと思っていましたが間に合いませんでした
*5:このブログを書いているときに GPT でのレビューが追加されていました。雰囲気良さそうな部分もあったので、ブログでも初手のレビューとして GPT を動かすというのも良さそうです