agentsclimarketplace

Bazel expert

Skill kinhluan/rules-quarkus-skills/.agent-skills/bazel-expert

πŸ€– Complete AI expert ecosystem for Modern Java, Quarkus & Bazel development β˜•οΈβš‘οΈ Coverage for Vert.x, GraalVM, Maven/Gradle migration, and more πŸš€

Install
npx -y skills add kinhluan/rules-quarkus-skills --skill bazel-expert

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 3 stars3 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

Expert knowledge for writing idiomatic Bazel rules, Starlark best practices, and build performance optimization. Use for Bazel build system questions.

SKILL.md

9.4 KB, as published. Nobody here has run it

bazel-expert

Keyword: bazel | Platforms: gemini,claude,codex

General Bazel & Starlark Expert Skill - Expert guidance on writing idiomatic Bazel rules and optimizing build performance.

Architectural Mandates

  • Hermeticity: Actions must only depend on declared inputs
  • Granularity: Break large targets into smaller java_library or starlark rules
  • Bzlmod: Always use Bzlmod for external dependency management
  • Visibility: Default visibility = ["//visibility:private"], explicitly widen only as needed

rules_java & Java Toolchains

Toolchain Setup (Bzlmod)

# MODULE.bazel
bazel_dep(name = "rules_java", version = "7.12.4")

java_toolchains = use_extension("@rules_java//java:extensions.bzl", "toolchains")
java_toolchains.toolchain(version = "21")
use_repo(java_toolchains, "remotejdk21_linux")

register_toolchains("@remotejdk21_linux//:jdk")

BUILD.bazel Examples

# Library target with proper granularity
java_library(
    name = "user-service",
    srcs = glob(["src/main/java/**/*.java"]),
    resources = glob(["src/main/resources/**"]),
    deps = [
        "//common/utils:json-utils",
        "@maven//:com_google_guava_guava",
        "@maven//:jakarta_inject_jakarta_inject_api",
    ],
    visibility = ["//services:__subpackages__"],
)

# Test target with testonly deps
java_test(
    name = "user-service-test",
    srcs = glob(["src/test/java/**/*.java"]),
    test_class = "com.example.UserServiceTest",
    deps = [
        ":user-service",
        "@maven//:org_junit_jupiter_junit_jupiter",
        "@maven//:org_assertj_assertj_core",
        "@maven//:org_mockito_mockito_core",
    ],
)

Do vs Don't

# BAD - monolithic target, slow incremental builds
java_library(
    name = "everything",
    srcs = glob(["src/**/*.java"]),
    deps = ["@maven//:all-the-things"],
    visibility = ["//visibility:public"],
)

# GOOD - granular targets, fast incremental builds
java_library(
    name = "user-model",
    srcs = ["src/main/java/com/example/User.java"],
    deps = ["@maven//:jakarta_validation_jakarta_validation_api"],
)

java_library(
    name = "user-repository",
    srcs = ["src/main/java/com/example/UserRepository.java"],
    deps = [":user-model", "@maven//:io_quarkus_quarkus_hibernate_orm_panache"],
)

rules_jvm_external (Maven Dependencies)

Setup with Bzlmod

# MODULE.bazel
bazel_dep(name = "rules_jvm_external", version = "6.6")

maven = use_extension("@rules_jvm_external//:extensions.bzl", "maven")
maven.install(
    name = "maven",
    artifacts = [
        "io.quarkus:quarkus-arc:3.20.1",
        "io.quarkus:quarkus-rest:3.20.1",
        "com.google.guava:guava:33.4.0-jre",
    ],
    fetch_sources = True,
    lock_file = "//:maven_install.json",
)
use_repo(maven, "maven")

BOM Import

maven.install(
    name = "maven",
    bom_imports = [
        "io.quarkus.platform:quarkus-bom:3.20.1",
    ],
    artifacts = [
        # Versions managed by BOM - no version needed
        "io.quarkus:quarkus-arc",
        "io.quarkus:quarkus-rest",
        "io.quarkus:quarkus-hibernate-orm-panache",
    ],
    lock_file = "//:maven_install.json",
)

Re-pinning Dependencies

# After adding/updating artifacts in MODULE.bazel:
RULES_JVM_EXTERNAL_REPIN=1 bazelisk run @maven//:pin

Starlark Best Practices

  • Avoid Macros for Logic: Use rules for complex logic, macros for wrapping
  • Provider Pattern: Use custom Providers to pass complex information between rules
  • Depsets: Always use depsets instead of lists for transitive dependencies

Custom Provider Example

QuarkusExtensionInfo = provider(
    doc = "Information about a Quarkus extension",
    fields = {
        "runtime_jars": "depset of runtime JAR Files",
        "deployment_jars": "depset of deployment JAR Files",
    },
)

def _quarkus_extension_impl(ctx):
    runtime = depset(
        direct = [ctx.file.runtime_jar],
        transitive = [dep[QuarkusExtensionInfo].runtime_jars for dep in ctx.attr.deps],
    )
    return [QuarkusExtensionInfo(runtime_jars = runtime, deployment_jars = ...)]

Depset Do vs Don't

# BAD - O(NΒ²) when collecting transitive deps
all_jars = []
for dep in ctx.attr.deps:
    all_jars += dep[JavaInfo].transitive_runtime_jars.to_list()

# GOOD - O(1) depset merging, lazy evaluation
all_jars = depset(transitive = [
    dep[JavaInfo].transitive_runtime_jars for dep in ctx.attr.deps
])

Performance Optimization

  • Param Files: Use ctx.actions.args().use_param_file("@%s") for long command lines
  • Remote Execution: Ensure rules are compatible with remote execution
  • Action Mnemonics: Use descriptive mnemonic and progress_message for debugging

Build Performance Decision Tree

SymptomDiagnosisFix
Full rebuild on small changeTarget too coarseSplit into smaller java_library targets
Slow first build, fast incrementalExpected behaviorEnable remote cache: --remote_cache=grpc://...
Slow even with cacheCache missesRun --execution_log_json_file=log.json, check non-hermetic inputs
"Argument list too long"Too many classpath entriesUse ctx.actions.args().use_param_file("@%s")
OOM during analysisToo many targetsUse --host_jvm_args=-Xmx8g, reduce glob() scope
Flaky test resultsNon-hermetic testAdd tags = ["no-sandbox"] to debug, then fix inputs

Remote Cache & Execution

# .bazelrc - remote cache setup
build --remote_cache=grpc://cache.example.com:9092
build --remote_upload_local_results=true
build --remote_timeout=60

# Remote execution (requires RBE)
build:remote --remote_executor=grpc://rbe.example.com:8980
build:remote --jobs=200
build:remote --spawn_strategy=remote

Troubleshooting

"no matching toolchains found for //target"

# Diagnosis: Java toolchain not registered
bazel query @rules_java//toolchains:all

# Fix: Register in MODULE.bazel
register_toolchains("@remotejdk21_linux//:jdk")

"dependency not found" after adding to maven.install

# Cause: lock file out of date
RULES_JVM_EXTERNAL_REPIN=1 bazelisk run @maven//:pin

# Verify target name (underscores replace dots/hyphens/colons):
# io.quarkus:quarkus-arc β†’ @maven//:io_quarkus_quarkus_arc
bazel query @maven//:all | grep quarkus

Circular dependency between targets

# BAD - A depends on B, B depends on A
java_library(name = "A", deps = [":B"])
java_library(name = "B", deps = [":A"])

# FIX - Extract shared code into a third target
java_library(name = "shared", srcs = ["Shared.java"])
java_library(name = "A", deps = [":shared"])
java_library(name = "B", deps = [":shared"])

Remote cache not being hit

# Debug: compare action keys
bazel build //target --execution_log_json_file=exec1.json
# Change something, rebuild
bazel build //target --execution_log_json_file=exec2.json
# Diff to find non-hermetic inputs
diff <(jq '.actionKey' exec1.json) <(jq '.actionKey' exec2.json)

Build is hermetic locally but fails on CI

Common causes:

  1. Absolute paths leaking β†’ use ctx.actions.args() with map_each to relativize
  2. Timestamp in outputs β†’ ensure tools produce deterministic output
  3. Different host platform β†’ specify --platforms=//platforms:linux_x86_64
  4. Missing data attribute β†’ runtime files must be declared in data, not srcs

Decision Trees

When to use macro vs rule

Need custom providers or actions?
  YES β†’ Write a rule
  NO β†’ Does it wrap existing rules with defaults?
    YES β†’ Write a macro
    NO β†’ Does it need to inspect file contents or run tools?
      YES β†’ Write a rule
      NO β†’ Macro is fine

When to use genrule vs custom rule

Is the action a single shell command?
  YES β†’ genrule (but avoid for Java - use java_binary + rule)
  NO β†’ Custom rule
Does it need to integrate with Java toolchain?
  YES β†’ Custom rule (access ctx.toolchains)
  NO β†’ genrule may suffice

🌐 Bazel Knowledge Sources

Directive: Use web_fetch to find the latest macro signatures or Bzlmod extensions if a build fails with toolchain or dependency errors.

References

Skill Interoperability

The bazel-expert πŸ— skill provides the core build infrastructure for:

  • rules-quarkus πŸ”§: Integrates Quarkus build and augmentation logic into the Bazel ecosystem.

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.