Small Changes

Weneedfeed + GitHub ActionsでウェブページからRSSフィードを生成してGitHub Pagesでホスティングする方法


Metadata


前置き

Roam Researchでブログを構築してからRSSフィードを生成する方法として次のサービスを利用していました。

特に不便はなかったのですが自前でRSSフィード用のXMLを生成して、XMLをホスティングする形で対応できないかと思ったので実際に調べて構築しました。

実現したいこと

GitHub ActionsでRSSフィード用のXMLを自動生成して、無料ホスティングサービスでXMLをホスティングする。

リポジトリ

実際に構築したリポジトリです。

今回の構成

今回の構成は以下の通りです。

この構成の理由

今回自動生成したいなーと思ったときにGitHub Actionsが浮かんだので、GitGhub ActionsのMarketplaceを覗いてみると、r7kamuraさんが作成されているweneedfeed-actionというのが目に止まりました。

使い方を見た感じ簡単にできそうだったのでweneedfeed-actionを使う方針に決めました。

無料のホスティングサービス先としては、GitGhub Actionsと相性の良いGitHub Pagesを選びました。

また、この構成でr7kamuraさんが実際に構築済みの参考にできるリポジトリがあったのも大きいです。

Weneedfeedをローカルで試す

WeneedfeedはウェブページからXMLを生成するツールのようです。実際にローカルで試してみました。

WeneedfeedはgemなのでインストールするためにGemfileを作成します。

source 'https://rubygems.org'

gem 'weneedfeed

次にbundle installを実行します。

パスを通すために、source ~/.bashrcを実行して、weneedfeed helpでコマンドが実行できることを確認します。

下記のようにweneedfeed buildを実行すると、weneedfeed.ymlをもとに指定のウェブページからXMLファイルを./outputディレクトリに出力します。

weneedfeed build --base-url=https://example.com

--base-urlに指定したURLはホスティング先のURL(例:https://snyt45.github.io/weneedfeed-snyt45com/ )を指定する必要があるようです。

次にweneedfeed.ymlを作成します。中身はWeneedfeedのREADMEを参考に下記のようにしました。

title: Small Changes RSS feeds

pages:
  - id: snyt45com
    title: Small Changes
    description: Small ChangesのRSSフィードです。
    url: https://snyt45.com/
    item_selector: article
    item_link_selector: a
    item_time_selector: time
    item_title_selector: a

ここまでディレクトリ構成です。

~/dev/weneedfeed via 💎 v2.7.6 took 6s
❯ tree
.
├── Gemfile
├── Gemfile.lock
└── weneedfeed.yml

0 directories, 3 files

この状態でweneedfeed build --base-url=https://example.comを実行します。

  • ローカルで試すだけなので--base-urlは仮です。

下記のように./outputディレクトリが出力されます。

今回の目的のXMLファイルが./output/feeds/snyt45com.xml に生成されることも確認できました。

~/dev/weneedfeed via 💎 v2.7.6
❯ tree
.
├── Gemfile
├── Gemfile.lock
├── output
│   ├── feeds
│   │   └── snyt45com.xml
│   ├── index.html
│   └── opml.xml
└── weneedfeed.yml

2 directories, 6 files

./output/feeds/snyt45com.xmlは下記のように出力されていました。

❯ cat output/feeds/snyt45com.xml
<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
  xmlns:atom="http://www.w3.org/2005/Atom"
  xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title><![CDATA[Small Changes]]></title>
    <link>https://snyt45.com/</link>
    <atom:link href="https://example.com/feeds/snyt45com.xml" rel="self"/>
    <description><![CDATA[Small ChangesのRSSフィードです。]]></description>
    <lastBuildDate>Sun, 28 Aug 2022 22:27:39 +0900</lastBuildDate>

    <item>
      <title><![CDATA[Ubuntu22.04でruby3.1.0以外をインストールするのに苦労した話]]></title>
      <link>https://snyt45.com/TdTglt5eQ</link>

        <pubDate>Sun, 28 Aug 2022 00:00:00 +0900</pubDate>

      <description><![CDATA[]]></description>
      <content:encoded><![CDATA[]]></content:encoded>
      <guid isPermaLink="true">https://snyt45.com/TdTglt5eQ</guid>

    </item>

    <item>
      <title><![CDATA[Roam ResearchでZettelkastenを実践する]]></title>
      <link>https://snyt45.com/18j8JdYuy</link>

        <pubDate>Mon, 01 Aug 2022 00:00:00 +0900</pubDate>

      <description><![CDATA[]]></description>
      <content:encoded><![CDATA[]]></content:encoded>
      <guid isPermaLink="true">https://snyt45.com/18j8JdYuy</guid>

    </item>

    <item>
      <title><![CDATA[20227月の振り返り]]></title>
      <link>https://snyt45.com/oKLBemvZw</link>

        <pubDate>Sat, 30 Jul 2022 00:00:00 +0900</pubDate>

      <description><![CDATA[]]></description>
      <content:encoded><![CDATA[]]></content:encoded>
      <guid isPermaLink="true">https://snyt45.com/oKLBemvZw</guid>

    </item>

    <item>
      <title><![CDATA[仙台出張前にChromeリモートデスクトップを試してみた]]></title>
      <link>https://snyt45.com/Ph5Yok7Zq</link>

        <pubDate>Sat, 16 Jul 2022 00:00:00 +0900</pubDate>

      <description><![CDATA[]]></description>
      <content:encoded><![CDATA[]]></content:encoded>
      <guid isPermaLink="true">https://snyt45.com/Ph5Yok7Zq</guid>

    </item>

    <item>
      <title><![CDATA[Roam ResearchでGTDを実践する]]></title>
      <link>https://snyt45.com/7nzMX-D02</link>

        <pubDate>Sun, 10 Jul 2022 00:00:00 +0900</pubDate>

      <description><![CDATA[]]></description>
      <content:encoded><![CDATA[]]></content:encoded>
      <guid isPermaLink="true">https://snyt45.com/7nzMX-D02</guid>

    </item>

    <item>
      <title><![CDATA[20226月の振り返り]]></title>
      <link>https://snyt45.com/pDgRjvIOd</link>

        <pubDate>Sat, 02 Jul 2022 00:00:00 +0900</pubDate>

      <description><![CDATA[]]></description>
      <content:encoded><![CDATA[]]></content:encoded>
      <guid isPermaLink="true">https://snyt45.com/pDgRjvIOd</guid>

    </item>

    <item>
      <title><![CDATA[20225月の振り返り]]></title>
      <link>https://snyt45.com/9W0vLoMdL</link>

        <pubDate>Sat, 28 May 2022 00:00:00 +0900</pubDate>

      <description><![CDATA[]]></description>
      <content:encoded><![CDATA[]]></content:encoded>
      <guid isPermaLink="true">https://snyt45.com/9W0vLoMdL</guid>

    </item>

    <item>
      <title><![CDATA[ようやくダックタイピングの意味が分かった]]></title>
      <link>https://snyt45.com/LR_aCZ8Mh</link>

        <pubDate>Fri, 06 May 2022 00:00:00 +0900</pubDate>

      <description><![CDATA[]]></description>
      <content:encoded><![CDATA[]]></content:encoded>
      <guid isPermaLink="true">https://snyt45.com/LR_aCZ8Mh</guid>

    </item>

    <item>
      <title><![CDATA[[読書メモ]オブジェクト指向設計実践ガイド/4章 柔軟なインターフェイスをつくる]]></title>
      <link>https://snyt45.com/YZMgwLMtL</link>

        <pubDate>Thu, 05 May 2022 00:00:00 +0900</pubDate>

      <description><![CDATA[]]></description>
      <content:encoded><![CDATA[]]></content:encoded>
      <guid isPermaLink="true">https://snyt45.com/YZMgwLMtL</guid>

    </item>

    <item>
      <title><![CDATA[20224月の振り返り]]></title>
      <link>https://snyt45.com/RcFrYkKmB</link>

        <pubDate>Wed, 04 May 2022 00:00:00 +0900</pubDate>

      <description><![CDATA[]]></description>
      <content:encoded><![CDATA[]]></content:encoded>
      <guid isPermaLink="true">https://snyt45.com/RcFrYkKmB</guid>

    </item>

  </channel>
</rss>

ローカルでいい感じのXMLファイルが生成されることを確認できたので次は https://github.com/r7kamura/weneedfeed-sundaywebry を参考にリポジトリを作成していきます。

GitHub Pagesを有効にします

リポジトリを作成したら、Settings > Pages から有効にして、Sourceの箇所で「GitHub Actions」を選択します。

この時点で、GitHub Pagesができていました。 https://snyt45.github.io/weneedfeed-snyt45com/

GitHub Actions ワークフローで./outputディレクトリをアーティファクトとしてアップロードして、アーティファクトをGitHub Pagesにデプロイする

GitHub Actions ワークフローで./outputディレクトリをアーティファクトとしてアップロードして、アーティファクトをGitHub Pagesにデプロイする部分は https://zenn.dev/ssssota/articles/f2509a21b768ed の記事を参考に構築しました。

カスタムGitHub Actions ワークフローを作成してGitHub Pagesにデプロイする方法については、公式のドキュメントも参考になります。

基本は、r7kamuraさんの参考リポジトリ通りなのですが、GitHub Pagesにデプロイする部分が変わっていました。

最終的なpublish.ymlの内容です。

name: publish

on:
  push:
    branches:
      - main
  schedule:
    - cron: "0 15 * * *"

jobs:
  publish:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      # weneedfeed.ymlの内容でRSSフィードのXMLファイルを./outputディレクトリに出力
      # ref: https://r7kamura.com/articles/2020-11-15-weneedfeed
      - uses: r7kamura/weneedfeed-action@v3
        with:
          base_url: https://snyt45.github.io/weneedfeed-snyt45com
      # artifactsにoutputのコンテンツをアップロード
      # ref: https://zenn.dev/ssssota/articles/f2509a21b768ed
      - uses: actions/upload-pages-artifact@v1
        with:
          path: output
  deploy:
    needs: publish # publishのjobに依存するのでneedsに指定
    permissions:
      pages: write
      id-token: write
    environment:
      name: github-pages
      url: ${{ steps.deployment.outputs.page_url }}
    runs-on: ubuntu-latest
    steps:
      - name: Deploy to GitHub Pages
        id: deployment
        uses: actions/deploy-pages@v1

参考記事

さいごに

便利なライブラリや便利なGitHub Actionsのおかげで当初の目的である「GitHub ActionsでRSSフィード用のXMLを自動生成して、無料ホスティングサービスでXMLをホスティングする」を達成することができました!

cronで毎日0時にスケジュールされているので、その時点のブログの内容をもとにRSSフィードのXMLファイルを生成してGitHub Pagesに自動デプロイしてくれるのでメンテナンスも不要で最高です。r7kamuraさんに感謝です。

References