This guide provides instructions for developers working on rules_img.
Note: As of v0.2.6, development has been simplified. You no longer need to manually manage lockfiles or build custom binaries. Instead, use Bazel module overrides to work with source-built versions of the Go tools. See Development with Source-Built Tools for details.
- Nix (recommended for reproducible development environment)
- OR manually install:
- Bazel
- Go
- pre-commit
# Enter the development shell
nix develop
# This provides:
# - Bazel with proper configuration
# - Go toolchain
# - pre-commit hooks
# - All other required toolsIf not using Nix, ensure you have all prerequisites installed and set up pre-commit:
# Install pre-commit hooks
pre-commit installFor the best development experience with VSCode, especially when using Nix:
# The repository includes VSCode settings for Bazel+Nix development
# Create a symlink to use them:
ln -sf .vscode/settings-bazel-nix.json .vscode/settings.json
# If not using Nix, you may need to adjust the GOPACKAGESDRIVER path
# from gopackagesdriver-nix.sh to gopackagesdriver.shPre-commit hooks run automatically on git commit. They ensure code quality and consistency.
# Run all pre-commit hooks manually
pre-commit run --all-files
# Run specific hooks
pre-commit run buildifier --all-files
pre-commit run trailing-whitespace --all-files# Format all Bazel files (fix mode)
bazel run //util:buildifier.fix
# Check Bazel file formatting (test mode)
bazel test //util:buildifier.check
# Run Gazelle to update BUILD files
bazel run //util:gazelleGenerated markdown files in docs/ are excluded from trailing whitespace and end-of-file checks.
# Build all targets in the main rules_img module
bazel build //...
# Build all targets in the rules_img_tool module (Go binaries)
bazel build @rules_img_tool//...
# Build specific Go binaries from the rules_img_tool module
bazel build @rules_img_tool//cmd/img # Main CLI tool
bazel build @rules_img_tool//cmd/registry # CAS-integrated registry
bazel build @rules_img_tool//cmd/bes # BES server
bazel build @rules_img_tool//pkg/... # Go libraries# Run all tests
bazel test //...
# Run tests with verbose output
bazel test --test_output=all //...Integration tests are available in the e2e/ directory:
# Run C++ integration tests
cd e2e/cc && bazel test //...
# Run Go integration tests
cd e2e/go && bazel test //...
# Test push functionality
cd e2e/go && bazel run //:pushWhen developing rules_img, you can use a source-built version of the Go img tool instead of prebuilt binaries. This is useful for testing changes to the tool implementation or applying patches. The img tool now also provides the image-pulling functionality used by repository rules, so there is a single tool module (rules_img_tool) to override.
Add a dependency on the tool module and register the source-built toolchain in your MODULE.bazel:
# Add a dependency on the tool module
bazel_dep(name = "rules_img_tool", version = "<version>", dev_dependency = True)
# Register source-built toolchain
register_toolchains(
"@rules_img_tool//toolchain:all",
dev_dependency = True,
)You can override the tool module using various Bazel module override mechanisms:
For local development with modifications:
# Override with local directory
local_path_override(
module_name = "rules_img_tool",
path = "../img_tool", # Path to your local checkout
)For testing against a specific Git commit or branch:
# Override with Git repository
git_override(
module_name = "rules_img_tool",
remote = "https://github.com/your-fork/rules_img.git",
strip_prefix = "img_tool",
commit = "abc123def456", # Specific commit
# Or use: branch = "feature-branch"
)For testing with a custom archive:
archive_override(
module_name = "rules_img_tool",
urls = ["https://github.com/your-fork/rules_img/archive/abc123def456.tar.gz"],
integrity = "sha256-...",
strip_prefix = "rules_img-abc123def456/img_tool", # Note: includes img_tool subdirectory
)For applying patches to a specific version:
single_version_override(
module_name = "rules_img_tool",
patches = ["//patches:img_tool_performance.patch"],
patch_strip = 2, # For patches created from rules_img root (strips img_tool/ prefix)
)# Generate/update all API docs
bazel run //docs:update
# Check if docs are up to date
bazel test //docs:allWhen adding new public rules:
- Create the rule in
img/private/ - Export it in the appropriate public
.bzlfile inimg/ - Add a
bzl_librarytarget inimg/BUILD.bazel - Add documentation generation in
docs/BUILD.bazel - Run
bazel run //docs:update
- Implement the compressor in
img_tool/pkg/compress/ - Add it to the factory in
img_tool/pkg/compress/factory.go - Update the compression attribute in
img/private/layer.bzl - Add the option to
img/settings/BUILD.bazel - Update documentation
# Use Bazel's debugging features for rules
bazel build --sandbox_debug //target:name
# Debug Go binaries in the rules_img_tool module
bazel build --sandbox_debug @rules_img_tool//cmd/img
# Inspect action outputs
bazel aquery //target:name
# Run the img tool directly for debugging
bazel run @rules_img_tool//cmd/img -- --help
# Debug with verbose output
bazel run @rules_img_tool//cmd/img -- pull --helpThe repository uses a dual-module structure:
rules_img/ # Main module - Bazel rules and extensions
├── img/ # Public Bazel rules
│ └── private/ # Implementation details
├── docs/ # Generated documentation
├── img_tool/ # rules_img_tool module - Go code
│ ├── cmd/ # Command-line tools
│ ├── pkg/ # Go libraries
│ └── MODULE.bazel # Separate Bazel module
└── e2e/ # Integration tests and examples
rules_img(root): Contains Bazel rules, extensions, and public APIrules_img_tool(src/): Contains Go binaries and libraries used by the rules
This separation allows for better dependency management and enables the Go tools to be distributed independently.
# Clear Bazel cache
bazel clean --expunge
# Clear specific outputs
bazel clean# Update go.mod and go.sum in the rules_img_tool module
(cd src && go mod tidy)
# Update Bazel's view of Go dependencies
bazel mod tidy
# Update all BUILD files
bazel run //util:gazelle- Ensure you're using the correct GOPACKAGESDRIVER
- Run
bazel build //...andbazel build @rules_img_tool//...to generate all outputs - Make sure your IDE is pointed at the
src/directory for Go development - Restart your IDE/language server
- Check existing issues on GitHub
- Read the API documentation
- Review examples in
benchmark/examples/ - Ask questions in GitHub Discussions