mcpField
B
bazel-build-optimization

bazel-build-optimization

github.com/sickn33開発48.8k169 回インストール今日更新
リポジトリ

bazel-build-optimization について

大規模モノレポでの Bazel ビルド最適化を扱うスキルです。セットアップ、リモートキャッシュと実行、カスタムルール、移行、問題調査に加え、バージョン確認やリモート接続の保護、比較可能なビルド計測も重視します。

主な機能

  1. 01モノレポ向け Bazel 設定
  2. 02リモートキャッシュと実行の設定
  3. 03ビルド時間のプロファイリング
  4. 04カスタム Bazel ルール
  5. 05依存関係とターゲットの分析
  6. 06リモートビルドのセキュリティ確認

活用シーン

  1. 01モノレポ向けの Bazel 設定
  2. 02遅いビルドアクションの調査
  3. 03カスタムビルドルールの作成
  4. 04Bazel 移行の計画

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/sickn33/agentic-awesome-skills --skill bazel-build-optimization

インストール後、Claude Code で/bazel-build-optimizationを入力して読み込まれたか確認します。

詳細

Bazel ビルドの最適化

大規模なモノレポにおける Bazel の本番環境向けパターンです。

このスキルを使用しない場合

  • タスクが Bazel ビルドの最適化に関係しない場合
  • この範囲外の別の分野やツールが必要な場合

手順

  • 目標、制約、必要な入力を明確にします。
  • 関連するベストプラクティスを適用し、結果を検証します。
  • 実行可能な手順と検証方法を提示します。

このスキルを使用する場合

  • モノレポ向けに Bazel をセットアップする場合
  • リモートキャッシュ/実行を設定する場合
  • ビルド時間を最適化する場合
  • カスタム Bazel ルールを記述する場合
  • ビルドの問題をデバッグする場合
  • Bazel に移行する場合

基本概念

1. Bazel のアーキテクチャ
workspace/
├── WORKSPACE.bazel       # External dependencies
├── .bazelrc              # Build configurations
├── .bazelversion         # Bazel version
├── BUILD.bazel           # Root build file
├── apps/
│   └── web/
│       └── BUILD.bazel
├── libs/
│   └── utils/
│       └── BUILD.bazel
└── tools/
    └── bazel/
        └── rules/
2. 主な概念
概念説明
ターゲットビルド可能な単位(ライブラリ、バイナリ、テスト)
パッケージBUILD ファイルを含むディレクトリ
ラベルターゲット識別子 //path/to:target
ルールターゲットのビルド方法を定義します
アスペクトビルドに横断的に適用される動作

バージョンとリモート実行の境界

テンプレートは過去の断片であり、実行可能なワークスペースではありません。固定された Bazel のメジャーバージョン、Bzlmod とレガシーな WORKSPACE のどちらをサポートするか、すべてのルールリポジトリ/ツールチェーン、実際のアーカイブチェックサムを確認してください。スニペットには rules_ts、rules_jest、pip のセットアップが含まれていません。これらの依存関係を作り出したり、sha256="..." を受け入れたりしないでください。リモートキャッシュ/実行やビルドイベントのバックエンドには、ソース、環境、成果物が送信される可能性があります。承認済みのエンドポイント、TLS、スコープを限定した認証情報、および信頼できない PR に対する個別の書き込み権限を必須としてください。ビルド自体もリポジトリルール/アクションを実行します。速度向上を主張する前に、コールド/ウォームキャッシュの状態と同等のターゲットを記録してください。クエリの出力数はパッケージ数であり、アクションノードの総数ではありません。

テンプレート

テンプレート 1: WORKSPACE の設定
# WORKSPACE.bazel
workspace(name = "myproject")

load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")

# Rules for JavaScript/TypeScript
http_archive(
    name = "aspect_rules_js",
    sha256 = "...",
    strip_prefix = "rules_js-1.34.0",
    url = "https://github.com/aspect-build/rules_js/releases/download/v1.34.0/rules_js-v1.34.0.tar.gz",
)

load("@aspect_rules_js//js:repositories.bzl", "rules_js_dependencies")
rules_js_dependencies()

load("@rules_nodejs//nodejs:repositories.bzl", "nodejs_register_toolchains")
nodejs_register_toolchains(
    name = "nodejs",
    node_version = "20.9.0",
)

load("@aspect_rules_js//npm:repositories.bzl", "npm_translate_lock")
npm_translate_lock(
    name = "npm",
    pnpm_lock = "//:pnpm-lock.yaml",
    verify_node_modules_ignored = "//:.bazelignore",
)

load("@npm//:repositories.bzl", "npm_repositories")
npm_repositories()

# Rules for Python
http_archive(
    name = "rules_python",
    sha256 = "...",
    strip_prefix = "rules_python-0.27.0",
    url = "https://github.com/bazelbuild/rules_python/releases/download/0.27.0/rules_python-0.27.0.tar.gz",
)

load("@rules_python//python:repositories.bzl", "py_repositories")
py_repositories()
テンプレート 2: .bazelrc の設定
# .bazelrc

# Build settings
build --enable_platform_specific_config
build --incompatible_enable_cc_toolchain_resolution
build --experimental_strict_conflict_checks

# Performance
build --jobs=auto
build --local_cpu_resources=HOST_CPUS*.75
build --local_ram_resources=HOST_RAM*.75

# Caching
build --disk_cache=~/.cache/bazel-disk
build --repository_cache=~/.cache/bazel-repo

# Remote caching (optional)
build:remote-cache --remote_cache=grpcs://cache.example.com
build:remote-cache --remote_upload_local_results=true
build:remote-cache --remote_timeout=3600

# Remote execution (optional)
build:remote-exec --remote_executor=grpcs://remote.example.com
build:remote-exec --remote_instance_name=projects/myproject/instances/default
build:remote-exec --jobs=500

# Platform configurations
build:linux --platforms=//platforms:linux_x86_64
build:macos --platforms=//platforms:macos_arm64

# CI configuration
build:ci --config=remote-cache
build:ci --build_metadata=ROLE=CI
build:ci --bes_results_url=https://results.example.com/invocation/
build:ci --bes_backend=grpcs://bes.example.com

# Test settings
test --test_output=errors
test --test_summary=detailed

# Coverage
coverage --combined_report=lcov
coverage --instrumentation_filter="//..."

# Convenience aliases
build:opt --compilation_mode=opt
build:dbg --compilation_mode=dbg

# Import user settings
try-import %workspace%/user.bazelrc
テンプレート 3: TypeScript ライブラリの BUILD
# libs/utils/BUILD.bazel
load("@aspect_rules_ts//ts:defs.bzl", "ts_project")
load("@aspect_rules_js//js:defs.bzl", "js_library")
load("@npm//:defs.bzl", "npm_link_all_packages")

npm_link_all_packages(name = "node_modules")

ts_project(
    name = "utils_ts",
    srcs = glob(["src/**/*.ts"]),
    declaration = True,
    source_map = True,
    tsconfig = "//:tsconfig.json",
    deps = [
        ":node_modules/@types/node",
    ],
)

js_library(
    name = "utils",
    srcs = [":utils_ts"],
    visibility = ["//visibility:public"],
)

# Tests
load("@aspect_rules_jest//jest:defs.bzl", "jest_test")

jest_test(
    name = "utils_test",
    config = "//:jest.config.js",
    data = [
        ":utils",
        "//:node_modules/jest",
    ],
    node_modules = "//:node_modules",
)
テンプレート 4: Python ライブラリの BUILD
# libs/ml/BUILD.bazel
load("@rules_python//python:defs.bzl", "py_library", "py_test", "py_binary")
load("@pip//:requirements.bzl", "requirement")

py_library(
    name = "ml",
    srcs = glob(["src/**/*.py"]),
    deps = [
        requirement("numpy"),
        requirement("pandas"),
        requirement("scikit-learn"),
        "//libs/utils:utils_py",
    ],
    visibility = ["//visibility:public"],
)

py_test(
    name = "ml_test",
    srcs = glob(["tests/**/*.py"]),
    deps = [
        ":ml",
        requirement("pytest"),
    ],
    size = "medium",
    timeout = "moderate",
)

py_binary(
    name = "train",
    srcs = ["train.py"],
    deps = [":ml"],
    data = ["//data:training_data"],
)
テンプレート 5: Docker 用のカスタムルール
# tools/bazel/rules/docker.bzl
def _docker_image_impl(ctx):
    dockerfile = ctx.file.dockerfile
    base_image = ctx.attr.base_image
    layers = ctx.files.layers

    # Build the image
    output = ctx.actions.declare_file(ctx.attr.name + ".tar")

    args = ctx.actions.args()
    args.add("--dockerfile", dockerfile)
    args.add("--output", output)
    args.add("--base", base_image)
    args.add_all("--layer", layers)

    ctx.actions.run(
        inputs = [dockerfile] + layers,
        outputs = [output],
        executable = ctx.executable._builder,
        arguments = [args],
        mnemonic = "DockerBuild",
        progress_message = "Building Docker image %s" % ctx.label,
    )

    return [DefaultInfo(files = depset([output]))]

docker_image = rule(
    implementation = _docker_image_impl,
    attrs = {
        "dockerfile": attr.label(
            allow_single_file = [".dockerfile", "Dockerfile"],
            mandatory = True,
        ),
        "base_image": attr.string(mandatory = True),
        "layers": attr.label_list(allow_files = True),
        "_builder": attr.label(
            default = "//tools/docker:builder",
            executable = True,
            cfg = "exec",
        ),
    },
)
テンプレート 6: クエリと依存関係の分析
# Find all dependencies of a target
bazel query "deps(//apps/web:web)"

# Find reverse dependencies (what depends on this)
bazel query "rdeps(//..., //libs/utils:utils)"

# Find all targets in a package
bazel query "//libs/..."

# Find changed targets since commit
bazel query "rdeps(//..., set($(git diff --name-only HEAD~1 | sed 's/.*/"&"/' | tr '\n' ' ')))"

# Generate dependency graph
bazel query "deps(//apps/web:web)" --output=graph | dot -Tpng > deps.png

# Find all test targets
bazel query "kind('.*_test', //...)"

# Find targets with specific tag
bazel query "attr(tags, 'integration', //...)"

# Compute build graph size
bazel query "deps(//...)" --output=package | wc -l
テンプレート 7: リモート実行のセットアップ
# platforms/BUILD.bazel
platform(
    name = "linux_x86_64",
    constraint_values = [
        "@platforms//os:linux",
        "@platforms//cpu:x86_64",
    ],
    exec_properties = {
        "container-image": "docker://gcr.io/myproject/bazel-worker:latest",
        "OSFamily": "Linux",
    },
)

platform(
    name = "remote_linux",
    parents = [":linux_x86_64"],
    exec_properties = {
        "Pool": "default",
        "dockerNetwork": "standard",
    },
)

# toolchains/BUILD.bazel
toolchain(
    name = "cc_toolchain_linux",
    exec_compatible_with = [
        "@platforms//os:linux",
        "@platforms//cpu:x86_64",
    ],
    target_compatible_with = [
        "@platforms//os:linux",
        "@platforms//cpu:x86_64",
    ],
    toolchain = "@remotejdk11_linux//:jdk",
    toolchain_type = "@bazel_tools//tools/jdk:runtime_toolchain_type",
)

パフォーマンスの最適化

# Profile build
bazel build //... --profile=profile.json
bazel analyze-profile profile.json

# Identify slow actions
bazel build //... --execution_log_json_file=exec_log.json

# Memory profiling
bazel build //... --memory_profile=memory.json

# Skip analysis cache
bazel build //... --notrack_incremental_state

ベストプラクティス

推奨事項
  • 粒度の細かいターゲットを使用する - キャッシュ効率が向上します
  • 依存関係を固定する - 再現可能なビルドを実現します
  • リモートキャッシュを有効にする - ビルド成果物を共有できます
  • 可視性を適切に設定する - アーキテクチャを適用します
  • ディレクトリごとに BUILD ファイルを作成する - 標準的な規約です
禁止事項
  • deps に glob を使用しない - 明示するほうが適切です
  • bazel- ディレクトリをコミットしない* - .gitignore に追加します
  • WORKSPACE のセットアップを省略しない - ビルドの基盤です
  • ビルドの警告を無視しない - 技術的負債になります

リソース

制限事項

  • タスクが上記の範囲に明確に該当する場合にのみ、このスキルを使用してください。
  • 出力を、環境固有の検証、テスト、専門家によるレビューの代わりとして扱わないでください。
  • 必要な入力、権限、安全上の境界、または成功基準が不足している場合は、作業を中止して確認を求めてください。

コメント