GitHubのリリースをRSSで追う|releases.atomとPythonでの絞り込み
/ 7 min read
Updated:Table of Contents
はじめに
使っているライブラリやツールの更新を、どうやって知っていますか。
- Astroのメジャーアップデートが出ていたことに、数か月経ってから気づく
- pandasの破壊的変更を、自分のスクリプトが落ちてから知る
- 依存ライブラリのセキュリティ修正リリースを見逃す
GitHubの Watch → Custom → Releases を有効にすればメールは飛んできますが、他の通知に紛れて結局読まなくなりがちです。
GitHubは公開リポジトリのリリース情報をAtomフィードとして配信しています。RSSリーダーに登録しておけば、追いたいリポジトリの更新を1か所にまとめて流し込めます。認証もトークンも要りません。
この記事では、フィードのURL形式、リリースノートが本文に入るのはどれか、そしてモノレポでノイズに埋もれるときの絞り込み方までをまとめました。
検証は 2026-09-21 時点、Pythonは3.12(標準ライブラリのみ)です。
GitHubが配信しているフィードのURL
| 内容 | URL |
|---|---|
| リリース | https://github.com/<owner>/<repo>/releases.atom |
| タグ | https://github.com/<owner>/<repo>/tags.atom |
| コミット | https://github.com/<owner>/<repo>/commits/<ブランチ>.atom |
| ユーザーの公開アクティビティ | https://github.com/<ユーザー名>.atom |
公開リポジトリならブラウザでそのまま開けます。返ってくるのは最新10件です。それより前に遡ることはできないので、履歴を全部なめたいときはGitHub APIの方を使います。
たとえばAstroなら次のURLになります。
https://github.com/withastro/astro/releases.atomRSSリーダーに登録する
URLをそのままRSSリーダーの購読欄に貼るだけです。ブラウザで開くとXMLが表示されます(ブラウザによってはダウンロードになります)が、購読に使うのはそのURLです。
自分が実際に追っているのは、このあたりです。
- 使っているフレームワーク本体(Astro、pandasなど)
- バイナリを直接落として入れているツール。UbuntuでNeovimの最新安定版をGitHubリリース(tar.gz)から導入する方法 のように手動更新しているものは、フィードで気づかないと古いまま放置になります
- 自分が使っているセルフホストのアプリ
モノレポではノイズに埋もれる
ここが実際に使ってみて一番困るところです。
Astroのようなモノレポは、@astrojs/vue や @astrojs/node といったパッケージ単位でリリースが打たれます。releases.atom は最新10件しか返さないので、本体のリリースがアダプタのパッチリリースで押し流されます。
後述のスクリプトで実際に取得した10件がこちらです。
2026-09-18 astral-sh/uv 0.12.172026-09-18 astral-sh/uv 0.12.152026-09-18 astral-sh/uv 0.12.142026-09-18 astral-sh/uv 0.12.162026-09-17 pandas-dev/pandas pandas 3.0.62026-09-16 withastro/astro @astrojs/vue@7.0.32026-09-16 withastro/astro @astrojs/node@11.1.62026-09-16 withastro/astro @astrojs/netlify@8.2.62026-09-16 withastro/astro @astrojs/cloudflare@14.3.22026-09-16 withastro/astro @astrojs/upgrade@0.7.5Astroの本体(astro@7.3.3)は、この10件の中に入っていません。リーダー側にフィルタ機能があればそれで足りますが、無いなら自前で絞り込むのが早いです。
Pythonで複数リポジトリのリリースをまとめて見る
標準ライブラリだけで書けます。外部パッケージは要りません。
import urllib.requestimport xml.etree.ElementTree as ET
NS = {"atom": "http://www.w3.org/2005/Atom"}
def fetch_releases(repo: str) -> list[dict[str, str]]: """リポジトリの releases.atom を取得し、エントリを辞書のリストで返す。""" url = f"https://github.com/{repo}/releases.atom" with urllib.request.urlopen(url, timeout=30) as res: root = ET.parse(res).getroot()
releases = [] for entry in root.findall("atom:entry", NS): releases.append( { "repo": repo, "title": entry.findtext("atom:title", "", NS), "updated": entry.findtext("atom:updated", "", NS), "link": entry.find("atom:link", NS).get("href", ""), } ) return releases
repos = ["withastro/astro", "pandas-dev/pandas", "astral-sh/uv"]releases = [r for repo in repos for r in fetch_releases(repo)]
for r in sorted(releases, key=lambda x: x["updated"], reverse=True)[:10]: print(f"{r['updated'][:10]} {r['repo']:<18} {r['title']}")<entry> から取っているのは4つだけです。
| タグ | 中身 |
|---|---|
title |
リリース名またはタグ名(astro@7.3.3 など) |
updated |
公開日時(ISO 8601、UTC) |
link |
リリースページのURL |
content |
リリースノートのHTML(今回は使っていません) |
本体のリリースだけに絞る
タグ名の形が決まっているので、前方一致で落とせます。
core = [r for r in fetch_releases("withastro/astro") if r["title"].startswith("astro@")]
for r in core: print(r["updated"][:10], r["title"], r["link"])2026-09-16 astro@7.3.3 https://github.com/withastro/astro/releases/tag/astro%407.3.310件のうち本体はこの1件だけでした。フィードをそのままリーダーに入れていたら、まず気づけません。
おわりに
releases.atom を付けるだけ、というのがこの仕組みの良いところです。APIキーもレート制限の管理も要りません。
一方で、最新10件しか返らない点と、モノレポでは本体が埋もれる点は最初に知っておいた方が良いところでした。絞り込みを挟むなら、スクリプトを定期実行して結果をチャットに流すところまでやると取りこぼしが減ります。通知先の作り方は GASからSlackに通知する関数を作ってみる にまとめています。
