diff --git a/.github/renovate.json5 b/.github/renovate.json5 index fbc91e290..7a2015945 100644 --- a/.github/renovate.json5 +++ b/.github/renovate.json5 @@ -17,16 +17,17 @@ // - lockFileMaintenance: 四半期に pnpm-lock 全リフレッシュ // github-actions / docker-compose は pnpm 非依存のため .github/dependabot.yml が担当。 enabledManagers: ["npm", "mise", "nvm"], - // Mend Cloud / self-host いずれでも pnpm install の lifecycle scripts (sharp / + // self-host runner での pnpm install の lifecycle scripts (sharp / // @prisma/engines / @sentry/cli / esbuild) によるメモリ消費を抑える保険。 // CI (--frozen-lockfile) と本番 deploy 側の install では通常通りバイナリを取得する。 ignoreScripts: true, - // Mend-hosted の kernel-out-of-memory 対策 (公式 FAQ 推奨)。pnpm の Node プロセスに - // --max-old-space-size=2048(MB) を渡し、V8 ヒープを Mend のコンテナ上限より下で - // 頭打ちにして積極 GC させ、OOM Killer による kill を回避する。 - // まだ落ちるなら値を下げる (1536) / JS heap OOM に変われば 1 回の作業量を削る。 + // self-host runner (GitHub Actions / ubuntu-24.04, 7GB RAM) での pnpm メモリ上限。 + // pnpm の Node プロセスに --max-old-space-size=4096(MB) を渡し、V8 ヒープを runner の + // 物理メモリより十分下で頭打ちにして OOM を回避する (.github/workflows/renovate.yaml)。 + // Mend Cloud 無料枠の 3GB コンテナでは OOM Killer に殺されていたため self-host へ移行済み。 + // モノレポ規模が増えて落ちるようなら branchConcurrentLimit を下げるか値を調整する。 toolSettings: { - nodeMaxMemory: 2048, + nodeMaxMemory: 4096, }, dependencyDashboard: true, branchConcurrentLimit: 3, diff --git a/.github/workflows/renovate.yaml b/.github/workflows/renovate.yaml new file mode 100644 index 000000000..67e9c5260 --- /dev/null +++ b/.github/workflows/renovate.yaml @@ -0,0 +1,78 @@ +name: renovate + +permissions: {} + +on: + schedule: + # 毎日 16:00 UTC = 翌 01:00 JST に起動。実際の PR 生成は .github/renovate.json5 の + # schedule / timezone(Asia/Tokyo) が gate する。この時刻なら + # - "before 11am on monday" → 月曜 01:00 JST でヒット + # - 四半期 "before 5am on the 1st" → 1日 01:00 JST でヒット + # の両方の窓を取りこぼさない(窓外の日は Renovate 側で no-op になるだけ)。 + - cron: "0 16 * * *" + workflow_dispatch: + inputs: + logLevel: + description: ログレベル + type: choice + default: info + options: [info, debug] + dryRun: + description: dry-run(書き込みなしでログ出力のみ) + type: boolean + default: false + # NOTE: `issues: edited` / `pull_request` トリガーは意図的に外している。Renovate 自身が + # Dependency Dashboard issue の body を毎回更新するため、これらを残すと + # 「run が dashboard を更新 → issues:edited が発火 → 別の run が起動」の自走ループになり + # 大量の `repository-changed` abort を生む。Dashboard checkbox を toggle しても次の + # scheduled / workflow_dispatch run で読み取られるので機能は失われない(即時反応しなくなるだけ)。 + +concurrency: + group: renovate + cancel-in-progress: false + +jobs: + renovate: + runs-on: ubuntu-24.04 + timeout-minutes: 60 + # 実際の repo write 権限は GitHub App トークンが持つため job の GITHUB_TOKEN は不要。 + permissions: {} + steps: + # 専用 GitHub App の短命トークンを発行。GITHUB_TOKEN と異なり App トークンで + # 作成した PR は ci.yaml 等のワークフローを発火できる(automerge 前提のため必須)。 + - name: Generate GitHub App token + id: app-token + uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3.2.0 + with: + app-id: ${{ secrets.RENOVATE_APP_ID }} + private-key: ${{ secrets.RENOVATE_APP_PRIVATE_KEY }} + # 生成トークンを最小権限に限定(metadata:read は常時付与)。 + # contents : ブランチ・コミット・lockfile 更新 + # pull-requests : PR 作成・automerge 有効化 + # issues : Dependency Dashboard issue の維持 + permission-contents: write + permission-pull-requests: write + permission-issues: write + + # self-host 実行。repo 設定 .github/renovate.json5 は Renovate が自動検出する + # (configurationFile はグローバル設定用なので渡さない)。 + - name: Self-hosted Renovate + uses: renovatebot/github-action@693b9ef15eec82123529a37c782242f091365961 # v46.1.14 + with: + token: ${{ steps.app-token.outputs.token }} + env: + RENOVATE_REPOSITORIES: ${{ github.repository }} + RENOVATE_PLATFORM: github + # App トークンで GitHub Contents API 経由の commit を行う。commit は App bot に + # 自動帰属し "Verified" バッジが付くため、PAT 運用で必要だった gitAuthor 固定は不要。 + RENOVATE_PLATFORM_COMMIT: enabled + # Mend Cloud 無料枠は 3GB cap で OOM kill されていた。ubuntu-24.04 runner は + # 十分なメモリ(16GB)を持つので Renovate プロセス自身のヒープに 6GB 割り当てる。 + # pnpm 子プロセス側の上限は renovate.json5 の toolSettings.nodeMaxMemory(4096) が担保。 + NODE_OPTIONS: --max-old-space-size=6144 + LOG_LEVEL: ${{ inputs.logLevel || 'info' }} + # dryRun=true のとき 'full'、それ以外(schedule 実行含む)は空=通常実行。 + RENOVATE_DRY_RUN: ${{ inputs.dryRun && 'full' || '' }} + # schedule trigger 以外(workflow_dispatch)はユーザの能動的なアクションなので、 + # renovate.json5 の schedule を無視して即時実行する(force で schedule を空に上書き)。 + RENOVATE_FORCE: ${{ github.event_name != 'schedule' && '{"schedule":[]}' || '' }} diff --git a/renovate-todo.md b/renovate-todo.md new file mode 100644 index 000000000..33a4ff67c --- /dev/null +++ b/renovate-todo.md @@ -0,0 +1,72 @@ +# Renovate self-host 移行 TODO(手動セットアップ) + +Mend Cloud 無料枠(1 job = 3GB)の `kernel-out-of-memory` を回避するため、Renovate を +GitHub Actions の self-host(`.github/workflows/renovate.yaml`)へ移行した。runner は 16GB RAM の +ため Mend のメモリ上限から解放される。認証は短命トークンの **専用 GitHub App** を使う。 + +このファイルは下記の手動ステップが完了したら削除すること。 + +## 背景(なぜ App 版か) + +- 過去に PAT ベースの self-host 版が存在したが、全 Dependabot 化の際に削除 → その後 + 「Dependabot が pnpm 11 非対応」で npm を Renovate に差し戻した際、self-host を復活させず + Mend Cloud に戻ったため OOM が再発していた。 +- 今回は PAT より安全な GitHub App(短命トークン・`platformCommit` で Verified コミット)で再構築。 + +--- + +## 手動ステップ(GitHub UI 操作のため要手動) + +### 1. 専用 GitHub App を作成 +GitHub → Settings → Developer settings → GitHub Apps → **New GitHub App** + +- [ ] **Repository permissions** を設定 + - Contents: **Read and write**(ブランチ・コミット・lockfile 更新) + - Pull requests: **Read and write**(PR 作成・automerge 有効化) + - Issues: **Read and write**(Dependency Dashboard issue の維持) + - Metadata: Read-only(必須・自動付与) + - ※ `enabledManagers` は npm/mise/nvm のみでワークフローは触らないため **Workflows 権限は不要** +- [ ] **Webhook** の "Active" を **オフ**(cron / workflow_dispatch 起動なのでイベント購読不要) +- [ ] Where can this app be installed: **Only on this account** +- [ ] 作成後、**Private key を生成**(`.pem` をダウンロード)し、**App ID** を控える +- [ ] **Install App** で `s-hirano-ist/s-private` にインストール + +### 2. Secrets を登録 +```bash +gh secret set RENOVATE_APP_ID --body "" +gh secret set RENOVATE_APP_PRIVATE_KEY < ~/Downloads/.private-key.pem +``` +- [ ] `RENOVATE_APP_ID` 登録 +- [ ] `RENOVATE_APP_PRIVATE_KEY` 登録 + +### 3. リポジトリ設定 +- [ ] Settings → General → Pull Requests → **Allow auto-merge** を有効化 + (`platformAutomerge: true` の前提) + +### 4. Mend Renovate App を撤去(重複 PR 防止) +- [ ] GitHub → Settings → Integrations → Applications → **Renovate** → Configure → + `s-private` をアクセス対象から外す(または Uninstall) + +--- + +## 検証(手動 1〜4 完了後) + +- [ ] **dry-run**: `gh workflow run renovate.yaml -f dryRun=true -f logLevel=debug` + → Actions ログでリポジトリが処理され、OOM もエラーも無く完走することを確認 +- [ ] **本実行**: `gh workflow run renovate.yaml` → App ユーザーが `renovate/*` ブランチで + PR を作成し、`dependencies` ラベルが付くことを確認 +- [ ] **CI 連動**: 作成された Renovate PR 上で既存 `ci.yaml` が発火していることを確認 + (= App トークンがワークフローを起動できている証拠。`GITHUB_TOKEN` では起動しない) +- [ ] **automerge**: devDependencies / mise の patch・minor PR が CI 通過後に自動マージされ、 + main の branch protection と矛盾しないことを確認 +- [ ] **Dashboard**: Dependency Dashboard issue が self-host により更新されることを確認 +- [ ] **重複なし**: Mend 撤去後、Mend 由来の PR が新規に出ないことを数日観察 + +--- + +## 後片付け + +- [ ] 移行確認後、旧 PAT secret `RENOVATE_TOKEN` を削除(App 版では未使用) + `gh secret delete RENOVATE_TOKEN` +- [ ] Mend が残した既存の `renovate/*` リモートブランチを整理(self-host が作り直す) +- [ ] このファイル `renovate-todo.md` を削除