Jekyllブログの記事をQiita CLIで自動ミラーする

はじめに

個人ブログの記事をQiitaにも掲載したいと考えました。しかし、同じ本文を2か所で編集すると、修正の反映漏れやリンク切れが起きやすくなります。

そこで、Jekyllの_posts/を正本にして、Qiita CLI用Markdownを生成する仕組みを追加しました。mainブランチへマージした記事だけをGitHub ActionsからQiitaへ投稿します。

作った仕組み

記事の編集元は、これまでどおり_posts/だけです。

flowchart LR
  P[Jekyll _posts] --> E[export-qiita.rb]
  E --> Q[qiita/public]
  Q --> R[Pull Requestで確認]
  R --> M[mainへマージ]
  M --> A[GitHub Actions]
  A --> C[Qiita CLI]
  C --> I[Qiitaの記事]
  C --> D[記事IDと更新日時]
  D --> Q

変換スクリプトは、次の処理を行います。

生成先はqiita/public/です。生成物もGit管理し、Pull Requestで実際の投稿内容を確認できるようにしました。

Qiita APIではなくQiita CLIを選んだ理由

Qiita APIを直接使う方法もありますが、今回は公式CLIを選びました。

方法 今回の判断
Qiita API 記事ID、リクエスト、エラー処理、プレビューを自前実装する必要がある
Qiita CLI プレビュー、投稿、更新、記事ID管理を利用できる

独自実装はJekyllからQiita形式への変換だけに絞り、投稿処理は公式ツールへ任せます。

使用したQiita CLIは1.10.0です。Node.jsは22.22.1以上を指定し、開発環境とCIではNode.js 24を使います。

{
  "engines": {
    "node": ">=22.22.1"
  },
  "devDependencies": {
    "@qiita/qiita-cli": "1.10.0"
  }
}
npm install
npx qiita version

ミラーする記事を明示する

Qiitaへ出したい記事だけに、次の設定を追加します。

qiita:
  publish: true
  tags:
    - Qiita
    - QiitaCLI
    - GitHubActions
    - Jekyll

運用ルールは次のとおりです。

Jekyll固有のリンクを変換する

ブログ内のルート相対URLは、そのままQiitaへ投稿するとリンク切れになります。

[Qiita CLI](/terms/qiita-cli/)
![設定画面](/assets/images/example.png)

変換後は、ブログの絶対URLになります。

[Qiita CLI](https://reotech736.com/terms/qiita-cli/)
![設定画面](https://reotech736.com/assets/images/example.png)

変換対象はMarkdownのリンクと画像、HTMLのhrefsrcです。コード例を壊さないよう、fenced code block内は変換しません。

生成、確認、投稿の流れ

ruby scripts/export-qiita.rb
ruby scripts/export-qiita.rb --dry-run
ruby scripts/export-qiita.rb --check
mkdir -p qiita-preview/public
cp -R qiita/public/. qiita-preview/public/
npx qiita preview --root qiita-preview --config qiita-preview

各コマンドの用途は次のとおりです。

Pull Requestでは_posts/qiita/public/を確認してからmainへマージします。

プレビューを開くと、生成した記事が未投稿の記事として表示されます。

Qiita Previewのサイドバーに、生成した記事が未投稿として表示されている

記事を選択すると、タイトル、タグ、本文、図をQiitaに近い表示で確認できます。

Qiita Previewで「Jekyllブログの記事をQiita CLIで自動ミラーする」を表示している

GitHub Actionsから投稿する

mainブランチでは、生成物の検査後にQiita CLIを実行します。

- name: Check generated Qiita articles
  run: ruby scripts/export-qiita.rb --check

- name: Publish articles
  env:
    QIITA_TOKEN: GitHub Actions Secretから設定
  run: npx qiita publish --all --root qiita

投稿後の処理も自動化しています。

トークンにはread_qiitawrite_qiita権限が必要です。

ローカルで確認した結果

変換スクリプトでは、次をテストしています。

ruby test/export_qiita_test.rb

8テスト、41 assertionsが成功し、--checkとJekyllの本番ビルドも完了しました。Qiitaへの最初の公開対象はこの記事自身です。投稿後は記事IDの保存と、再実行時に重複せず更新されることを確認します。

まとめ

Jekyllの記事を正本にし、形式の変換だけを自作して、投稿と記事ID管理はQiita CLIへ任せました。公開対象をFront Matterで明示し、生成結果をPull Requestで確認してから投稿する構成です。

まずはこの記事1本で新規投稿と更新を確認し、安定してから既存記事のミラーを検討します。


この記事はReo’s Tech Blogの同名記事にも掲載しています。

Reo’s Tech Blogでは、個人開発や日々の技術的な取り組みを記録しています。興味がありましたら、ほかの記事もご覧ください