有名テック企業の技術ブログを、ひとつのフィードで。
フィード
31件
こんにちは。タイミーのデータエンジニアリング部 DSグループでMLOpsを担当しているYukitomoです。 私たちのチームでは多くのPythonアプリをモノレポで管理していますが、Dependabotによる依存関係更新PRが多すぎることが運用課題でした。本記事では、Renovateへの移行によって「更新PRの粒度と数をコントロールできる運用」を実現するまでの設計判断と、Python + uv環境特有の注意点を共有します。 この記事の想定読者 Pythonのモノレポ環境で、複数のアプリケーションやライブラリを運用している方 Dependabotが生成する大量の更新PRの対応に疲弊しており、運用を効率化したい方 Renovateへの移行を検討している、または導入したが設定(packageRules)のベストプラクティスに悩んでいる方 パッケージマネージャーに uv を採用している(または検討している)方 要約(TL;DR:この記事でわかること) 本記事では、Python + uv環境でRenovateを運用する際の課題とその解決策(新しすぎるパッケージの除外設定、Google Cloud WIFにおけるブランチ名の文字数制限の回避など)を整理し、実践的なrenovate.json5の設定ノウハウを解説します。 背景 近年はサプライチェーン攻撃が現実的なリスクになっており、Trivyの侵害以降も Python モジュールや JS ライブラリを狙った攻撃が継続して観測されています。PyPI など外部エコシステムに依存する以上、これまで以上に「依存関係をどう安全に運用するか」を真面目に考える必要があります。 一方で、依存関係を「安全に」保つには、継続的にアップデートを回し続ける必要があります。ここで次の課題になるのが、運用対象が増えたときに更新対応のコストがスケールしてしまう点です。 私たちもDependabot運用の効率化を進めてきましたが*1、アプリごとにパッケージ管理へ移行した結果、モノレポ内のpyproject.tomlが増えました。2026年5月時点では、DSグループだけでも約70のPythonアプリケーション/ライブラリを扱っています。Dependabotは脆弱性の検知とPR作成を行ってくれる一方で、依存関係ごとにPRが分割されます。そのため、対象が増えるほど対応コストが急増します。 そこでこの課題を解決するため、Renovateを導入し「更新をまとめて扱える運用」へ切り替える方針にしました。本記事では、公式ドキュメントや公開されている設定例を参考にしつつ、私たちが重視した設定ポイントを整理します。 この記事の前提 言語: Python 依存関係ファイル: pyproject.toml / uv.lock 動作環境: GitHub & Google Cloud 目的: Renovateで「脆弱性対応」と「定常アップデート」を破綻なく回す(PRの数と粒度をコントロールする) 設定ファイル(.renovaterc.json5) 設計方針 私たちが設定で重視したのは以下の3点です。 PRの粒度をコントロールする — patch / minor / vulnerability を適切にグルーピングし、PRの本数を削減する サプライチェーンリスクを軽減する — 公開直後のバージョンを即座に採用しない 小さく始める — まず許可リスト方式で必要な更新だけを有効化し、段階的に広げる 全体像 以下が設定ファイルの抜粋です(各設定の詳細は後述)。 // .renovaterc.json5 より一部抜粋 { extends: ["config:best-practices"], minimumReleaseAge: "N days", lockFileMaintenance: { enabled: true, branchTopic: "lfm", // GCP WIF 127-byte limitに対応するためブランチ名を省略 minimumReleaseAgeBehaviour: "timestamp-optional" // 一時的な対応 }, vulnerabilityAlerts: { groupName: "maintenance", groupSlug: "maint", minimumReleaseAge: "14 days", }, packageRules: [ // packageFileDirをブランチ名に含めつつGCP WIF 127-byte limitに対応するためブランチ名を省略 { matchFileNames: ["base_containers/base/**"], additionalBranchPrefix: "{{{replace 'base_containers/base/' 'b_b/' packageFileDir}}}/", }, // packageRuleを一旦無効化 { matchPackageNames: ["**"], enabled: false }, // グルーピング ---------------------------------------------------- // ルール 1: { matchUpdateTypes: ["patch"], enabled: true, groupName: "maintenance", groupSlug: "maint", }, // ルール 2: { matchUpdateTypes: ["minor"], matchJsonata: ["isVulnerabilityAlert = false"] enabled: true, groupName: "minor updates", groupSlug: "minor", dependencyDashboardApproval: true }, // ルール 3: { matchPackageNames: ["**"], matchJsonata: ["isVulnerabilityAlert = true"] enabled: true, // この2つは vulnerabilityAlerts で設定した値で上書きされます groupName: "maintenance", groupSlug: "maint", }, // マイナーレベルでの破壊的な更新の抑制 ただし脆弱性対応を除く { matchJsonata: ["isBreaking = true and not(isVulnerabilityAlert)"], enabled: false, }, ], // バージョンの更新 bumpVersions: [ { bumpType: "patch", filePatterns: ["{{packageFileDir}}/pyproject.toml"], matchStrings: ["version\\s*=\\s*\"(?<version>[^\"]+)\""] }, { bumpType: "patch", filePatterns: ["{{packageFileDir}}/uv.lock"], matchStrings: ["name = \"[^\"]+\"\\nversion = \"(?<version>[^\"]+)\"\\nsource = \\{ (?:editable|virtual) = \"\\.\" \\}"] } ] } 設定項目の説明 <h3 id="configbest-practices-を土台にす