From b4b7e16cc8ccf06b57f813a48699457515252e30 Mon Sep 17 00:00:00 2001 From: azu Date: Sat, 25 Apr 2026 16:43:50 +0900 Subject: [PATCH 1/2] docs: add design spec for rss-to-bluesky workflow Co-Authored-By: Claude Opus 4.7 (1M context) --- .../specs/2026-04-25-rss-to-bluesky-design.md | 83 +++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 docs/superpowers/specs/2026-04-25-rss-to-bluesky-design.md diff --git a/docs/superpowers/specs/2026-04-25-rss-to-bluesky-design.md b/docs/superpowers/specs/2026-04-25-rss-to-bluesky-design.md new file mode 100644 index 00000000000..3ab9ab994de --- /dev/null +++ b/docs/superpowers/specs/2026-04-25-rss-to-bluesky-design.md @@ -0,0 +1,83 @@ +# RSS to Bluesky workflow design + +## 概要 + +JSer.info の RSS フィードを Bluesky (`@jser.info`) に自動投稿する GitHub Actions workflow を追加する。既存の Mastodon workflow (`rss-to-mastodon.yml`) と同じ構造で、`joschi/blueskyfeedbot` を使用する。 + +## 動機 + +- 既存の Mastodon (`@jser@mstdn.jp`) と Twitter への投稿に加え、Bluesky (`@jser.info`) でも更新を配信する +- Bluesky アカウントは既に存在: (DID: `did:plc:fqprbc6qtifjv7cpx5vjhwgq`) + +## 設計 + +### ファイル + +`.github/workflows/rss-to-bluesky.yml` を新規追加する。 + +### Action + +`joschi/blueskyfeedbot` を使用する。 + +- バージョン: v1 (`ded1962e3afb0d7283f49a037bf4d4fd9d7b86ad`) +- 既存の workflow と同じく commit SHA で pinning する +- 参照: + +### トリガー + +- `schedule: '*/5 * * * *'` (5分毎) +- `workflow_dispatch` (手動実行用) + +5分毎にする理由: Bluesky 投稿は public な情報のみで、Mastodon (15分毎) より低レイテンシで配信したい。`joschi/blueskyfeedbot` の README デフォルトも 5 分。 + +### 投稿対象 + +| Job | RSS フィード | テンプレート | +|---|---|---| +| `realtime` | `https://realtime.jser.info/feed.xml` | `{{item.title}}\n{{item.link}}\n\n{{item.description}}` | +| `jser` | `https://jser.info/rss/` | `今週のJSer.infoを更新しました!\n{{item.title}}\n{{item.link}}` | + +テンプレートは Mastodon と揃える。ただし `joschi/blueskyfeedbot` は Handlebars + `{{item.*}}` プレフィックスで、`jser/mastofeedbot` は `{{title}}` 形式なので、フィールド参照は読み替える。 + +### 共通設定 + +```yaml +service-url: https://bsky.social +username: ${{ secrets.JSER_BLUESKY_USERNAME }} +password: ${{ secrets.JSER_BLUESKY_PASSWORD }} +cache-file: ${{ github.workspace }}/blueskyfeedbot/cache.json +initial-post-limit: 1 +``` + +`initial-post-limit: 1` を設定する理由: 初回実行時にキャッシュが無いと過去の RSS 全件が一気に投稿される可能性があるため、最初の 1 件だけに絞る。 + +### キャッシュ + +各ジョブで個別の cache key を使用する (Mastodon workflow と同じパターン)。 + +- `realtime` ジョブ: `feed-cache-realtime-jser-info-bluesky-${cache-key}` +- `jser` ジョブ: `feed-cache-jser-info-bluesky-${cache-key}` + +`actions/cache` と `actions/github-script` のバージョンも既存 workflow に合わせて pinning する。 + +### 並列実行制御 + +`concurrency: group: feedbot-bluesky` を設定し、ジョブが重複実行されないようにする。 + +## ユーザー側で必要な作業 + +1. で App Password を作成 +2. リポジトリの Secrets に以下を追加: + - `JSER_BLUESKY_USERNAME`: `jser.info` + - `JSER_BLUESKY_PASSWORD`: 上で作成した App Password + +## 影響範囲 + +- 新規ファイル `.github/workflows/rss-to-bluesky.yml` の追加のみ +- 既存の Mastodon/Twitter workflow には影響しない + +## 検証方法 + +1. Secrets 設定後、`workflow_dispatch` で手動実行して動作確認 +2. 初回は `initial-post-limit: 1` により最新記事 1 件のみ投稿されることを確認 +3. 以降は新しい記事が出たタイミングで自動投稿されることを確認 From ed2b992d43315142a204acacc52958ce158d9c18 Mon Sep 17 00:00:00 2001 From: azu Date: Sat, 25 Apr 2026 16:45:43 +0900 Subject: [PATCH 2/2] ci: add rss-to-bluesky workflow Post jser.info and realtime.jser.info feeds to Bluesky (@jser.info) using joschi/blueskyfeedbot, mirroring the existing Mastodon workflow. Co-Authored-By: Claude Opus 4.7 (1M context) --- .github/workflows/rss-to-bluesky.yml | 75 ++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 .github/workflows/rss-to-bluesky.yml diff --git a/.github/workflows/rss-to-bluesky.yml b/.github/workflows/rss-to-bluesky.yml new file mode 100644 index 00000000000..f74dcd46bb0 --- /dev/null +++ b/.github/workflows/rss-to-bluesky.yml @@ -0,0 +1,75 @@ +# Source: https://github.com/joschi/blueskyfeedbot +name: rss-to-bluesky +on: + schedule: + - cron: '*/5 * * * *' + workflow_dispatch: +concurrency: + group: feedbot-bluesky +jobs: + realtime: + runs-on: ubuntu-latest + permissions: + actions: write + steps: + - name: Generate cache key + uses: actions/github-script@d7906e4ad0b1822421a7e6a35d5ca353c962f410 # v6.4.1 + id: generate-key + with: + script: | + core.setOutput('cache-key', new Date().valueOf()) + + - name: Retrieve cache + uses: actions/cache@6f8efc29b200d32929f49075959781ed54ec270c # v3.5.0 + with: + path: ${{ github.workspace }}/blueskyfeedbot + key: feed-cache-realtime-jser-info-bluesky-${{ steps.generate-key.outputs.cache-key }} + restore-keys: feed-cache-realtime-jser-info-bluesky- + + - name: JSer.info realtime + uses: 'joschi/blueskyfeedbot@ded1962e3afb0d7283f49a037bf4d4fd9d7b86ad' # v1 + with: + rss-feed: https://realtime.jser.info/feed.xml + template: | + {{item.title}} + {{item.link}} + + {{item.description}} + service-url: https://bsky.social + username: ${{ secrets.JSER_BLUESKY_USERNAME }} + password: ${{ secrets.JSER_BLUESKY_PASSWORD }} + cache-file: ${{ github.workspace }}/blueskyfeedbot/cache.json + initial-post-limit: 1 + + jser: + runs-on: ubuntu-latest + permissions: + actions: write + steps: + - name: Generate cache key + uses: actions/github-script@d7906e4ad0b1822421a7e6a35d5ca353c962f410 # v6.4.1 + id: generate-key + with: + script: | + core.setOutput('cache-key', new Date().valueOf()) + + - name: Retrieve cache + uses: actions/cache@6f8efc29b200d32929f49075959781ed54ec270c # v3.5.0 + with: + path: ${{ github.workspace }}/blueskyfeedbot + key: feed-cache-jser-info-bluesky-${{ steps.generate-key.outputs.cache-key }} + restore-keys: feed-cache-jser-info-bluesky- + + - name: JSer.info + uses: 'joschi/blueskyfeedbot@ded1962e3afb0d7283f49a037bf4d4fd9d7b86ad' # v1 + with: + rss-feed: https://jser.info/rss/ + template: | + 今週のJSer.infoを更新しました! + {{item.title}} + {{item.link}} + service-url: https://bsky.social + username: ${{ secrets.JSER_BLUESKY_USERNAME }} + password: ${{ secrets.JSER_BLUESKY_PASSWORD }} + cache-file: ${{ github.workspace }}/blueskyfeedbot/cache.json + initial-post-limit: 1