APC 技術ブログ

株式会社エーピーコミュニケーションズの技術ブログです。

株式会社 エーピーコミュニケーションズの技術ブログです。

ブログ管理をエンジニアリングしてみた — Markdownの限界をGitHub Issues + Actionsで超えた話

こんにちは。ACS事業部の越川です。

今年の目標として「1年200記事」を掲げ、APC技術ブログとQiitaにブログを書き続けています。3月から始めて、これまでに25件の記事を公開しました。

しかし25件を超えたあたりで、ブログの「中身」ではなく「管理」の方が追いつかなくなりました。公開したはずの記事がネタ帳に「執筆中」のまま残っている。Qiitaに出した記事がネタ帳に載っていない。そもそも何件公開したのか数えないとわからない。

この記事では、エンジニアとしてブログ管理の問題を解決した過程を書きます。

ネタ帳をMarkdownで始めた理由

ブログを毎日書くにはネタの安定供給が必要です。思いついたアイデアを忘れないように、リポジトリに ideas.md というファイルを作りました。

## ネタ1: インストラクションの行数でAIのルール遵守率は変わるのか?
- ステータス: **下準備中**
- 着想: Claude Code公式でCLAUDE.mdは200行以下推奨…
- 記事パターン: パターンA × パターンF

1ネタ1セクション。ステータス・着想・出典・一次情報をまとめて書いておく形です。

この方法を選んだ理由はシンプルで、手軽だったからです。GitリポジトリにあるMarkdownなので、Claude Codeとの壁打ち中にそのまま追記できます。ツールの選定や環境構築は不要。思いついた瞬間に書ける。

最初のうちはうまく回っていました。

25件で何が起きたか

3月に入って記事を書くペースが上がると、ideas.mdは1,048行・35,000トークンを超えました。Claude Codeで読み込むにも分割が必要なサイズです。

ただ、肥大化自体は織り込み済みでした。ネタ帳は書き溜めるものなので、大きくなるのは想定通りです。

問題は別のところにありました。

投稿実績との乖離

ある日、Qiitaの自分のプロフィールを見て「9件公開済み」と表示されていることに気づきました。ideas.mdを確認すると、公開済みとして記録されていたのは一部だけ。11件の記事がネタ帳に未登録でした。

原因はいくつかあります。

  • ideas.mdにネタ番号を振る前に書いた記事が登録されていなかった
  • 公開後にステータスを「公開済み」に更新し忘れていた
  • APC技術ブログとQiitaの2つのプラットフォームに書き分けているが、投稿先との突合手段がなかった

ルーティングの不在

APC技術ブログとQiitaでは記事の性質が異なります。

  • APC技術ブログ: 事業に紐づく技術、やってみた系
  • Qiita: 方法論・思考法・個人の実践

ネタの企画段階で「これはどちらに出すか」を判断しています。ideas.mdには投稿先を書いていましたが、実際に公開された記事との突合は手作業でした。手作業である以上、漏れるのは時間の問題です。

ブログシステムはネタ管理ツールではない

はてなブログにもQiitaにも下書き機能はあります。しかし「タネ→下準備中→執筆中→レビュー中→公開済み」というステータス管理や、2つのプラットフォームを横断した進捗の一覧表示はできません。

WordPress、はてなブログ、Qiitaなど既存のブログシステムは投稿・公開のためのシステムであって、ネタの企画・進捗管理のためのシステムではない。この2つは別の関心事です。

GitHub Issues + Projects + Actionsで解決する

以下の図は、移行前後のワークフローを比較したものです。

Beforeでは、投稿後のステータス更新が手作業のため「更新忘れ」「未登録」が発生していました。Afterでは、突合スクリプトがQiita APIとAPC技術ブログの公開状況を自動でチェックし、Issueの状態を正しく保ちます。

エンジニアであれば、この手の問題はなじみがあります。要件をチケットに起こし、ボードで進捗を管理し、CIで品質を担保する。ブログ管理にも同じアプローチを適用しました。

Issue = ネタ帳 + 意思決定の履歴

ideas.mdの全ネタをGitHub Issueに移行しました。1ネタ1Issue。着想・一次情報・構成案はIssueのbodyに入ります。

Issueにした理由はもう一つあります。コメント欄に「なぜこの方向にしたか」「なぜ路線変更したか」の履歴が残ることです。ideas.mdではネタの説明を上書き更新していたので、途中の判断経緯が消えていました。Issueのコメントは時系列で積み上がるため、ネタが育っていく過程がそのまま記録になります。

ラベル = ルーティング

ラベルで2つの情報を管理します。

ステータスラベル: タネ / 下準備中 / 執筆中 / レビュー中 / 公開済み / 内部議論 / 保留

プラットフォームラベル: APC技術ブログ / Qiita / 内部資料

ネタの性質に応じた投稿先のルーティングが、ラベルとして構造化されました。

Project = カンバン

GitHub Projectsのボードビューで、ステータス別にIssueを一覧表示します。「公開URL」というカスタムフィールドも追加しました。

  • カンバンで執筆中のIssueが想定より溜まっていることが一目でわかります
  • 公開URLが空のまま公開済みになっているIssueが書き漏れ候補です

テーブルビューに切り替えれば、プラットフォーム別のフィルタリングもできます。

Actions = 突合

決定論的に整合性をチェックするスクリプト(sync-blog-project.py)を作り、GitHub Actionsで毎週月曜に自動実行しています。

チェック項目は7つです。

チェック 内容
ステータス整合 IssueラベルとProjectステータスの一致
URL完全性 公開済みIssueに公開URLが設定されているか
コメント完全性 公開済みIssueにURLコメントがあるか
未登録記事検出 Qiita API・APC技術ブログにあるがIssueがない記事
重複検出 同一URLや類似タイトルのIssue
停滞検出 「執筆中」のまま4週間以上更新なし
URL正確性 コメントのURLが実際の記事と一致するか

Qiita APIは認証不要で公開記事の一覧を取得できます。APC技術ブログは検索結果をスクレイピングしています。これにより、投稿先のプラットフォームとIssueの突合が自動化されました。

python3 scripts/sync-blog-project.py          # レポートのみ
python3 scripts/sync-blog-project.py --apply   # 修正も適用

移行してわかったこと

可視化の威力

GitHub Projectsのボードビューでは、各ステータスのカラムにIssueがカードとして並びます。全ネタをカンバンに移行した直後、執筆中カラムにカードが想定より溜まっていることに気づきました。ideas.mdでは上から順にスクロールして読むしかなかったので、どのステータスにネタが偏っているかを把握できていませんでした。

テーブルビューでは公開URLカラムを追加しました。公開済みステータスのIssueなのに公開URLカラムが空であれば、URLの登録漏れです。移行直後にチェックしたところ、11件のIssueでURLが未登録だったことが発覚しています。

突合スクリプトで蓄積された管理の負債が見えた

前述の突合スクリプト sync-blog-project.py を初めて実行したところ、14件の問題が検出されました。内訳は、ステータスラベルの不整合が2件、公開済みIssueへのURLコメント不足が11件、非標準ラベルの混在が1件です。いずれもideas.md時代に蓄積された管理の負債でした。

これらは --apply オプションで一括修正できます。ラベルの正規化、URLコメントの追加、ProjectフィールドへのURL設定をスクリプトが自動で行います。初回実行で負債を一掃した後は、毎週の自動チェックで新たな不整合を早期に検出する運用に切り替えています。

管理だけでなく品質保証も仕組み化されている

今回の記事ではネタ管理の移行にフォーカスしていますが、実際にはブログ執筆の品質保証も8つのClaude Code hooksで自動化しています。記事を書くたびに文体チェック・はてなブログ固有のルール検証・Grokによる読者視点レビューが自動で走ります。

また、published.md は引き続き維持しています。GitHub Issueは進捗管理の正ですが、published.mdは公開済み記事のテーマ別の繋がりや「なぜ書いたか」を記録する役割を持っています。管理と記録は別の関心事です。

hooksによる品質保証については「AIのルール遵守は確率的、hooksは決定論的 — ハーネスの2つのレイヤー」で詳しく書いています。

手軽に始めたこと自体は正解だった

ideas.mdで始めたことを後悔はしていません。ブログを毎日書くペースを確立することが最優先だった時期に、管理基盤の構築に時間をかけていたら本末転倒です。

25件という実績ができて、書き分けのパターンが見えて、管理の限界を体感したからこそ、「何を仕組み化すべきか」が明確になりました。

おわりに

以前「AI時代の"ゴールデンパス"、まだ誰も定義していないなら自分たちで定義してみた」という記事を書きました。整備された道を用意することで、チームの開発者体験を向上させるという話です。

今回やったことは、その考え方を自分のブログ管理に適用したことになります。ideas.mdという属人的な道を、GitHub Issues + Projects + Actionsという整備された道に置き換えた。大げさな基盤は不要で、GitHubの標準機能と100行程度のPythonスクリプトで実現できています。

自分のワークフローにエンジニアリングを適用する。ブログ管理に限らず、日々のドキュメント管理や情報整理でも同じアプローチが使えるはずです。

参考

ACS 事業部のご紹介

私の所属する ACS 事業部では、開発者ポータル Backstage、Azure AI Service などを活用し、Platform Engineering + AI の推進・内製化を支援しています。

www.ap-com.co.jp www.ap-com.co.jp www.ap-com.co.jp

また、GitHub パートナーとしてお客様に GitHub ソリューションの導入支援を行っています。 GitHub Copilot などのトレーニングなども行っておりますので、ご興味を持っていただけましたらぜひお声がけいただけますと幸いです。

一緒に働いていただける仲間も募集中です! ご興味持っていただけましたらぜひお声がけください。

※求人名の冒頭に【ACSD】と入っている求人が当事業部の求人です

www.ap-com.co.jp www.ap-com.co.jp

本記事の投稿者: 越川将人