TL;DR
個人ブログの記事をGitHubプロフィールのREADMEに自動反映する仕組みを実装しました。
@astrojs/rssでRSSフィードを生成- GitHub Actionsで別リポジトリのREADMEを更新
はじめに
これまでZennなどに書いたブログのリンクをGitHubのREADMEに載せていますが、この個人ブログも載せたいと思っていました。 記事数もそこまで多くないので手動で更新すれば良いのですが、せっかくの個人サイトなのでRSSとGitHub Actionsを使って自動化してみました。
自動反映の流れ
以下の流れで、個人ブログの記事をGitHubプロフィールのREADMEに自動反映しています。
rss.xml] C --> D[GitHub Actions
手動実行] D --> E[RSSフィード取得] E --> F[README更新] F --> G[別リポジトリにPush]
現在は手動実行(workflow_dispatch)にしています。mainブランチへのマージ時に自動実行することも可能ですが、実行タイミングを制御したかったため手動実行としました。
別リポジトリのREADMEを更新するためにPATを発行
GitHub Actionsで別リポジトリにアクセスするには、Personal Access Token(PAT)が必要です。
PATの発行手順
- GitHubの設定画面から「Developer settings」→「Personal access tokens」→「Tokens (classic)」を選択
- 「Generate new token (classic)」をクリック
- 必要な権限を選択(
repoのみでOK) - トークンをコピー
Secretsへの登録
- ブログリポジトリの「Settings」→「Secrets and variables」→「Actions」を選択
- 「New repository secret」をクリック
- Name:
PROFILE_README_TOKEN、Value: 先ほどコピーしたトークンを入力
これで、GitHub ActionsからプロフィールリポジトリにPushできるようになります。
@astrojs/rssを使って、RSS用のxmlを作成
@astrojs/rssは、Astroの公式パッケージで、簡単にRSSフィードを生成できます。
インストール
pnpm add @astrojs/rss
実装
src/pages/rss.xml.tsを作成し、以下のように実装しました。
import rss from '@astrojs/rss';
import { getCollection } from 'astro:content';
import type { APIContext } from 'astro';
export async function GET(context: APIContext) {
const posts = await getCollection('posts');
// 公開済みの記事のみを取得し、日付降順でソート
const publishedPosts = posts
.filter((post) => !post.data.draft)
.sort((a, b) => b.data.date.getTime() - a.data.date.getTime());
return rss({
title: 'write-down',
description: '個人ブログ - 日々の学びとアウトプット',
site: context.site || 'https://write-down.com',
items: publishedPosts.map((post) => ({
title: post.data.title,
pubDate: post.data.date,
link: `/posts/${post.data.uuid}`,
})),
customData: '<language>ja</language>',
});
}
ポイント
- 下書きの除外:
filter((post) => !post.data.draft)で下書き記事を除外 - ソート: 日付降順でソートし、最新記事が先頭に来るように
- 言語指定:
customDataで日本語フィードであることを明示
これでhttps://write-down.com/rss.xmlにアクセスすると、RSSフィードが取得できます。
GitHub Actionsを使ってREADMEを更新
GitHub Actionsで、RSSフィードを取得してREADMEを更新する処理を実装しました。
ワークフローの概要
.github/workflows/update-blog-list-manual.ymlを作成し、以下の処理を実装しています。
name: Update Blog Post List (Manual)
on:
workflow_dispatch:
手動実行のみのシンプルな構成にしました。
処理の流れ
-
RSSフィードのビルド
pnpm installとpnpm run buildでRSSフィードを生成
-
RSSフィードの取得とパース
- 公開されたRSSフィード(
https://write-down.com/rss.xml)を取得 xmllintでXMLをパースし、タイトルとリンクを抽出
- 公開されたRSSフィード(
-
README更新
<!-- BLOG-POST-LIST:START -->と<!-- BLOG-POST-LIST:END -->のマーカー間に記事リストを挿入- Markdown形式のリンクリストを生成
- マーカーは任意の文字列でOK
-
コミット & Push
- プロフィールリポジトリにコミット & Push
README側の準備
プロフィールリポジトリのREADME.mdに、以下のマーカーを追加しておく必要があります。
<!-- BLOG-POST-LIST:START -->
<!-- BLOG-POST-LIST:END -->
このマーカーの間に、GitHub Actionsが記事リストを自動で挿入します。
おわりに
これで記事を公開したら、GitHub Actionsを手動実行するだけでREADMEが自動更新されるようになりました。 RSSフィードを活用することで、別リポジトリへの自動反映が簡単に実現できました。
今後は、記事をたくさん書いてこの機能を活用していきたいと思います。