Developers Blogの移行に合わせて執筆環境を構築しました

サムネイル

はじめに

この記事は技術広報 Advent Calendar 2024のシリーズ2 16日目の記事です。

こんにちは。DMM.comのVPoE室で技術広報を担当している星です。

テックブログが11月1日にDMM insideからDMM Developers Blogへ移行されました!
それに合わせてHatena-Blog-Workflows-Boilerplateを活用し、記事をGitHubで管理できるように整えたので、今回はDMM Developers Blogでの執筆フローをご紹介します。

Hatena-Blog-Workflows-Boilerplate

Hatena-Blog-Workflows-Boilerplateとは、ブログのレビューや公開作業など、ブログの運営用ワークフローを支援するボイラープレートです。GitHub上で記事の作成、編集、公開などを行うことができます。
READMEに丁寧に手順が書かれているので、詰まることなく簡単に導入できました。
github.com

DMM Developers Blogの執筆環境について

DMMではチームごとに開発環境が様々で、GitHub Enterprise Server(以下GHES)を利用している場合もあれば、GitHub Enterprise Cloud(以下GHEC)を使用している場合もあります。
そのためブログの記事執筆環境についても、GHESを使用するフロー、GHECを利用するフローとそれぞれ運用しています。また、GitHubを業務で使用していない方がブログを執筆することもあるため、GitHubを利用しないフローも用意しています。

今回ご紹介するフローは、GHECを利用したフローです。なお同じGitHubの環境であるGHESは、GitHub Actionsを動作させるためにSelf-hosted runnerが必要となり、運用コストが高くなると懸念されるため、GitHub Actionsを活用したボイラープレートでの運用は見送っています。

GHECでの執筆の流れ

現在の執筆フローは下記のような流れです。

  1. Pull Request(以下PR)と下書きファイルの作成(GitHub Actions)
  2. 記事の執筆
  3. textlintでの校正(GitHub Actions)
  4. ブログカテゴリの選択(GitHub Actions)
  5. PRテンプレートの追記(GitHub Actions)
  6. 執筆チェックリスト確認
  7. 運営レビュー
  8. 予約投稿を設定
  9. 公開後にPRマージ

執筆者側が1〜6まで対応し、7〜9を運営チームメンバーが作業しています。ボイラープレートではPRをマージすることにより記事が公開できますが、他にも執筆環境があることもあり予約投稿での公開に統一し、マージによる投稿は見送りました。

「3.textlintでの校正」、「4.ブログカテゴリの選択」、「5.PRテンプレートの追記」のフローをGitHub Actionsで新たに構築しました。これらついて、以下で詳しく説明します。

textlintでの校正

PR作成後、ファイルを編集すると実行されます。また、reviewdogを使ってPR上で結果を確認できるようにしています。
tsuyoshicho/action-textlintを参考に、簡単に構築できたので、詳細は割愛します。

textlintのルールはtextlint-rule-preset-ja-technical-writingなど複数のルールを採用していますが、少し厳しすぎるルールは緩和しながら使っています。まだ運用開始直後の段階ではあるので、今後も執筆者からのフィードバックを反映しながら、ルールを柔軟に調整していく予定です。

ブログカテゴリの選択

執筆者に最適なブログカテゴリを選択してもらえるよう、PRのLabelsを使ってカテゴリを選択できるようにしています。

ボイラープレートが内部的に利用しているblogsyncを確認するとFrontMatterにカテゴリ情報も追記できるとのことだったので、Labelsの選択/削除をトリガーとしてActionsを実行させ、記事ファイルのFront Matterを書き換えています。

name: Pull Request Labels to Category
on:
  pull_request:
    types: [labeled, unlabeled]
jobs:
  add-category:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4
        with:
          fetch-depth: 0
          ref: ${{ github.event.pull_request.head.ref }}
          token: ${{ secrets.PERSONAL_ACCESS_TOKEN }}

      - name: Setup node/npm
        uses: actions/setup-node@v4
        with:
          node-version: '18'

      - name: Replace categories
        env:
          LABELS: ${{ toJson(github.event.pull_request.labels.*.name) }}
        run: |
          FILE_PATHS=$(git diff --name-only origin/main...HEAD | grep '^draft_entries/.*\.md$')
          if [ ${#FILE_PATHS[@]} -ne 1 ]; then
            echo "Error: Found ${#FILE_PATHS[@]} files. Only one file should be processed."
            exit 1
          fi
          FILE_PATH=${FILE_PATHS[0]}
          echo "FILE_PATH=$FILE_PATH" >> $GITHUB_ENV

          NEW_CATEGORY_LINE=""
          for i in $(seq 0 $(($(echo "$LABELS" | jq length) - 1)))
          do
            label=$(echo "$LABELS" | jq -r .[$i])
            if [ $i -eq $(($(echo "$LABELS" | jq length) - 1)) ]; then
              NEW_CATEGORY_LINE="$NEW_CATEGORY_LINE  - $label"
            else
              NEW_CATEGORY_LINE="$NEW_CATEGORY_LINE  - $label\n"
            fi
          done
          sed -i '/^Category:/,/^EditURL:/ {/^[[:space:]]*-/d}' "$FILE_PATH"
          sed -i "/^Category:/a\\$NEW_CATEGORY_LINE" "$FILE_PATH"

      - name: Commit and push
        run: |
          git config --global user.name 'github-actions[bot]'
          git config --global user.email 'github-actions[bot]@users.noreply.github.com'
          git pull origin "${{ github.head_ref }}"
          git checkout "${{ github.head_ref }}"
          git add "${{ env.FILE_PATH }}"
          git commit -m "[bot-commit] Update categories in ${{ env.FILE_PATH }}"
          git push origin "${{ github.head_ref }}" 

記事ファイルのFront Matterを更新後、PRの変更を検知して記事更新のActionsを起動させ、下書き記事へカテゴリを追加する予定でした。
しかし、ファイルのpushを行った後、後続のActionsが起動されないいう制約に直面しました。 構築当初GITHUB_TOKENを利用してファイルのpushを行っていたのですが、調べたところ、下記のとおりGITHUB_TOKENの動作をトリガーとして別のActionsを動かすことができないとわかりました。

ワークフロー実行でリポジトリの GITHUB_TOKEN を使用してコードがプッシュされた場合、push イベントの発生時に実行するように構成されたワークフローがリポジトリに含まれている場合でも、新しいワークフローは実行されません。 参考:https://docs.github.com/ja/actions/security-for-github-actions/security-guides/automatic-token-authentication

そのため、GITHUB_TOKENを使わずPersonal Access Tokens(PAT)やGitHub Appsのトークンを使用する必要がありました。今回は社内のGitHub管理者との協議の結果、PATを利用することになりました。
PATを使用しファイルを更新することで、記事をブログに反映するActionsも問題なく起動し、ブログ記事にカテゴリが反映されました。

PRテンプレートの追記

PR作成時にPRテンプレートを活用したいと考えましたが、現時点のボイラープレートでは対応していませんでした。そのため、PRテンプレートを説明欄(description)に追記するGitHub Actionsを構築しました。
トリガーについてはさまざまな案を検討しましたが、ボイラープレートで作成されるPRはdraft状態であることを考慮し、運営への記事提出前に執筆者にPRをopenしてもらうフローを採用しました。PRがopenされたタイミングでPRテンプレートがdescriptionへ追記されるように設定しています。

name: add PR comment
on: 
  pull_request:
    types: [ ready_for_review ]
jobs:
  add-comment:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4
      - name: Comment
        env:
          PR_NUMBER: ${{ github.event.number }}
          GH_TOKEN: ${{ github.token }}
        run: |
          NEW_BODY=$(echo -e "$(gh pr view ${PR_NUMBER} --json body --jq .body)\n\n$(cat .github/pull_request_template.md)")
          gh pr edit "${PR_NUMBER}" --body "${NEW_BODY}"

さいごに

現在のブログ執筆環境についてフローと工夫した点をまとめました。

クリエイター組織メンバーが普段使い慣れているGitHubを活用し、執筆やレビューがスムーズに行えるようになりました。今まではslackでレビュー結果をフィードバックしていたため、今回の執筆環境変更で多少なりとも効率化されたのではないかと思います。
さらに、追加でいくつかGitHub Actionsを構築した結果、ブログ管理画面での操作は予約投稿の設定時のみで済むようになり、運営負荷も軽減されたように感じます。

今後も継続的に改善を重ね、より良い執筆環境にしていきたいです!

ブログを移行して1ヶ月半ほどなのでブログの記事数はまだ少ないですが、これからも多くの記事を発信していく予定ですので、更新をぜひ楽しみにしていてください!