HN 日本語サマリー

← 一覧へ戻る
インフラ・DevOps

ImpactGate: AIが追加する構造的劣化をスコアリングするマージゲート

ImpactGate: A merge gate that scores the structural decay AI adds (github.com)

22 pointsby sagenschneider22 コメント

要約

ImpactGateは、コード変更が導入する構造的劣化(複雑性の増加)を測定・ゲートするツールです。変更の影響度を計算し、しきい値を超えた場合に警告またはビルドをブロックします。CLI、gitフック、GitHub Actions、GitLab CI、Jenkins CIなどのワークフローに統合でき、絶対的なしきい値またはプロジェクトの履歴に基づいたパーセンタイルによるゲート設定が可能です。

全文翻訳

ImpactGate: AIが追加する構造的劣化をスコアリングするマージゲート impact-gate 変更が導入する構造的劣化を測定し、ゲートします。スタンドアロンCLI、gitプリコミットフック、またはGitHub、GitLab、Jenkins CIのプラグインとして実行できます。ウェブサイト: https://impactgate.officefloor.net 構造的劣化とは、既存の構造に複雑性が蓄積することです。ゴッドメソッドが別のブランチを成長させます。ゴッドクラスが別のメソッドを獲得します。 ゲートは、変更の影響度測定を使用して、変更をベース(デフォルトではmain)に対してスコアリングします。影響度 = 変更されたファイル数 * Σ max(WMC_other, 1) * CC * Δlines (変更された関数全体) WMC_otherは、編集中のコンテナに既に存在する複雑性です。これは変更前の状態に基づいて測定されます。そのため、全く新しいファイルやクラスをインポートするのは安価です。以前は何もありませんでした。既に重いクラスに積み重ねるのは高価です。これが劣化のシグナルです。 計算式の根拠については、OfficeFloorブログの「Measuring the Blast Radius of Change」を参照してください。 影響度が高すぎる場合、ゲートは変更の単純化またはコードのリファクタリングを要求します。警告(レポートのみ)またはブロック(ビルド失敗)が可能です。 インストール pip install impact-gate # `impact-gate` コマンドをインストールします または、インストールせずに、公開されているイメージ経由で実行します(gitがバンドルされています。スコアリングするにはリポジトリを/repoにマウントしてください)。 docker run --rm -v "$PWD:/repo" ghcr.io/officefloor/impact-gate \ score --mode range --base origin/main ローカルでハックするには、チェックアウトからインストールしてください。 python -m venv .venv && . .venv/bin/activate pip install -e '. [dev]' # editable install にテスト依存関係を追加 使用方法 # コミットしようとしているコミット(プリコミット): ステージングされた変更 vs HEAD。これはデフォルトです。 impact-gate score # コミットされていないローカル編集: ワーキングツリー vs HEAD。 impact-gate score --mode worktree # CIまたはPRレビュー: コミットされたブランチ vs main (merge-base..HEAD)。 impact-gate score --mode range --base origin/main --format json # しきい値と強制設定。これらは.impact-gate.ymlにも記述できます。 impact-gate score --warn-at 50000 --block-at 200000 --enforcement block 終了コード。 0 は OK または警告(変更は許可されます)を意味します。 2 はブロック(--enforcement block で影響度が高すぎる場合)を意味します。 1 は使用法または環境エラーを意味します。 各レポートには、リファクタリングを検討すべきファイルも、影響度への貢献度順にリストされます。変更レベルの数値がゲートを制御し、ファイルごとのランキングは劣化が集中している場所を示します。これにより、静かにゴッドクラスへと成長しているファイルが、何かをブロックする前に候補として浮上します。 差分がmax_diff_lines(デフォルトで200,000、測定設定内)より大きいソースファイルは、ほぼ常に生成されたダンプまたはベンダー提供のブロブです。ゲートはこれをスキップするため、数値が歪んだり、スコアリングが遅くなったりせず、スキップされたファイルとしてリストされるため、結果がサイレントに間違っていることはありません。 gitプリコミットフックとしての使用 CIの前に、ローカルで各コミットをゲートします。 # .git/hooks/pre-commit をインストールします。各コミット時にステージングされた変更をスコアリングします。 impact-gate install-hook 強制設定付き: .impact-gate.yml でブロックを設定すると、影響度が高すぎるコミットはブロックされます。警告(またはオフ)の場合は、レポートが表示され、コミットは続行されます。 既存のプリコミットフックを上書きするには --force を付けて再実行してください。 プリコミットフレームワークを好みますか? このリポジトリはフック定義を提供しています — .pre-commit-config.yaml に追加してください。 repos: - repo: https://github.com/officefloor/ImpactGate rev: v0.3.0 hooks: - id: impact-gate 分布(カーブ)に対する評価 生のしきい値を設定するのは困難です。典型的な変更の影響度は、言語やプロジェクトによって桁違いに異なります。数値を推測する代わりに、分布に対するパーセンタイルで変更を評価し、パーセンタイルでゲートします。 # プロジェクト自身のインパクト分布をマージされた履歴からビルド(またはリフレッシュ)します。 # .impact-gate-baseline.json を書き込みます。ブランチが進むにつれて再実行してください。 impact-gate baseline --base-ref main # 絶対数ではなく、グレードでゲートします。 impact-gate score --curve --warn-percentile 90 --block-percentile 98 グレードは2つの分布をブレンドします。1つはツールに付属するシードプライアである、20リポジトリのオープンソースコーパスから構築された言語ごとのパーセンタイルテーブルで、テーブルにない言語にはプールされたフォールバックがあります。もう1つはプロジェクトのベースラインで、リポジトリ自身の変更ごとの分布で、マージされたメインラインからウォークされます(コミットされた作業のみ。進行中のブランチは到達しません)。 ブレンドは、nがベースラインの後ろにあるコミット数、K(curve_prior_weight、デフォルト200)がプロジェクトをシードよりも信頼するのに必要な履歴量である場合、w = n / (n + K) でプロジェクトに重みを付けます。 ベースラインファイルがない新しいリポジトリはシードのみで評価されます。深い履歴はそれ自体に依存します。 グレードは、すべてのフォーマットで生の数値の隣に表示されます。 設定は.impact-gate.yml(リポジトリルート)で行います。 warn_at: 50000 # 警告を発する影響度 block_at: 200000 # ブロックする影響度 enforcement: warn # off, warn, or block. warnから開始し、準備ができたらblockに切り替えます。 tolerance: 1.0 # 両方のしきい値に対するCI調整可能な乗数。1より大きいとより寛容になります。 # measure_config: .impact-measure.yml # オプション: グロブと言語のオーバーライドを無視する # グレーディングカーブ(パーセンタイルゲート)。有効にすると、warn_at/block_atは無視され、 # ゲートは以下のパーセンタイルを使用します。 curve_enabled: false # 絶対数ではなく、パーセンタイルグレードでゲートする warn_percentile: 90 # 警告を発するグレード(この値以上) block_percentile: 98 # ブロックするグレード(この値以上) curve_prior_weight: 200 # w = n/(n+K) における K: プロジェクトをシードより信頼するのに必要な履歴量 baseline_file: .impact-gate-baseline.json # `impact-gate baseline` が分布をキャッシュする場所 CLIフラグはファイルをオーバーライドします。CIジョブは--toleranceまたは--warn-atを渡すことができます。これにより、チームはリポジトリを編集せずに許容度を調整できます。 カーブのノブにもフラグがあります: --curve, --warn-percentile, --block-percentile, --baseline-file。 GitHub Actionsでの使用 リポジトリにワークフローを追加します。アクションはPRブランチをベースと比較してスコアリングし、サマリーを書き込みます。 fetch-depth: 0 は、ベースブランチとマージベースが存在するために必要です。 name: Change impact on: pull_request permissions: contents: read pull-requests: write # アクションがPRコメントとしてスコアを投稿できるようにするため jobs: impact: runs-on: ubuntu-latest steps: - uses: actions/checkout@v5 with: fetch-depth: 0 - uses: officefloor/ImpactGate@v0 with: enforcement: warn # 準備ができたらblockに切り替える # warn-at: 50000 # block-at: 200000 # tolerance: 1.0 スコアはジョブサマリーとPRのスティッキーコメント(1つのコメント、実行ごとに更新)として表示されます。 ブロックモードでは、影響度がブロックしきい値を超えるとジョブは失敗します。 マージをゲートするには、ブランチ保護でチェックを必須にします。 コメントにはpull-requests: writeが必要です。それがない場合、実行はパスしますが、コメントはスキップされます。 GitLab CIでの使用 ci/gitlab-ci.yml にすぐに使えるジョブがあります。それを.gitlab-ci.ymlにコピーするか、リモートからインクルードしてください。 include: - remote: 'https://raw.githubusercontent.com/officefloor/ImpactGate/v0/ci/gitlab-ci.yml' これはマージリクエストパイプラインで実行され、公開されているDockerイメージを使用してMRをベース($CI_MERGE_REQUEST_DIFF_BASE_SHA)に対してスコアリングし、CI/CD変数GITLAB_TOKENにapiスコープが設定されている場合は、MRにスティッキーノートを投稿します(1つのノート、実行ごとに更新)。トークンがない場合でも、スコアリングとゲートは行われますが、ノートはスキップされます。 ブロック強制モードでは、影響度が高すぎるとジョブが失敗します。マージをゲートするには、マージリクエスト設定で必須にしてください。 Jenkinsでの使用 ci/Jenkinsfile にパイプラインスニペットがあります。Dockerを備えたエージェントでDockerイメージを実行し、変更をターゲットブランチ(origin/${CHANGE_TARGET:-main})に対してスコアリングし、レポートをアーカイブします。 ブロック強制モードでは、影響度が高すぎるとステージが失敗します。 PR/MRへのスコアの投稿は、SCMインテグレーションに任されています。ツール自体で投稿するには、プロバイダーのトークンと環境を設定してコンテナ内で `impact-gate comment` を実行してください。 ロードマップ コアCLI。ステージング、ワーキングツリー、またはレンジのスコアリング。警告またはブロック。テキスト、JSON、Markdown。完了。 GitHubアクション。コンポジットアクション、ジョブサマリーレポート、スティッキーPRコメント。完了。 ベースラインとグレーディングカーブ。impact-gate baseline はプロジェクト履歴をプロファイルします。ゲートは、s