This guide helps you complete your Bazel migration after running the migration script.
For small projects, running bazel run //:gazelle will generate BUILD.bazel files for your entire codebase, and you're done. However, for larger projects with complex dependencies, Gazelle may generate incorrect BUILD files or encounter issues. In such cases, a gradual migration approach works better—migrate packages one at a time by progressively removing entries from .bazelignore, starting from foundational packages with no internal dependencies.
Critical: Migrate packages in dependency order, starting from the foundation.
Foundational packages <- Migrate FIRST (no internal dependencies)
^
Core packages <- Migrate SECOND (depend on foundational)
^
Application packages <- Migrate LAST (depend on core)
For Go projects:
# List all packages
go list ./...
# See what a package imports
go list -f '{{.Imports}}' ./pkg/mypackage
# Find packages with no internal dependencies (good starting points)
go list -f '{{if not .Imports}}{{.ImportPath}}{{end}}' ./...For Python projects:
# Analyze imports (requires pipdeptree or similar)
pipdeptree --local-only
# Or manually check imports in each module
grep -r "^from \. import\|^from \.\." src/Solution: Use Gazelle directives in your root BUILD.bazel:
# gazelle:prefix <your-module-path>
# gazelle:exclude vendor
# gazelle:exclude testdataSolution: Ensure all external dependencies are declared:
For Go, run:
go mod tidy
bazel run //:gazelle -- update-repos -from_file=go.modFor Python, ensure requirements.in is complete:
pip-compile requirements.in
bazel run //:gazelleSolution: Use .bazelignore to exclude problematic directories temporarily:
# .bazelignore
problematic_dir/
legacy_code/
Common causes:
- File path assumptions: Tests assume they run from project root
- Fix: Use
runfilesto locate test data
- Fix: Use
- Missing test data: Data files not included in test target
- Fix: Add
dataattribute to test rule
- Fix: Add
- Environment differences: Different env vars in Bazel sandbox
- Fix: Set
envattribute or use--test_env
- Fix: Set
Issue: go:embed directives not working
go_library(
name = "mylib",
srcs = ["lib.go"],
embedsrcs = ["templates/*"], # Add embedded files
)Issue: Build tags not respected
# In BUILD.bazel or via gazelle directive
# gazelle:build_tags integrationIssue: Imports not resolving
Ensure your BUILD.bazel has correct imports:
py_library(
name = "mylib",
srcs = ["mylib.py"],
imports = [".."], # Adjust import path
)After migrating each package:
# 1. Build the package
bazel build //path/to/package/...
# 2. Run tests
bazel test //path/to/package/...
# 3. Check that the old build still works (during transition)
go build ./path/to/package/...
go test ./path/to/package/...
# or for Python:
python -m pytest path/to/package/For each package you migrate:
- Remove package from
.bazelignore - Run
bazel run //:gazelle - Review generated BUILD.bazel file
- Run
bazel build //package/... - Run
bazel test //package/... - Commit changes
- Update dependent packages if needed
If you need to undo the migration:
# See what changed
git diff
# Revert all Bazel files
git checkout -- MODULE.bazel .bazelrc BUILD.bazel .bazelignore
# Or reset everything
git checkout -- .Once fully migrated:
- Update CI/CD to use Bazel
- Remove old build configurations (Makefile, setup.py, etc.) if no longer needed
- Consider enabling remote caching for faster builds
- Explore Bazel's advanced features (aspects, transitions, etc.)