A simple Python project demonstrating Bazel build system fundamentals with Jenkins CI/CD integration. Perfect for learning how Bazel works with Python code, dependencies, incremental builds, and automated pipelines.
- Basic Bazel concepts: WORKSPACE, BUILD files, targets
- Python with Bazel:
py_libraryandpy_binaryrules - Dependency management: How modules depend on each other
- Incremental builds: Fast rebuilds when nothing changes
- Cross-platform builds: Works on Windows, macOS, and Linux
- CI/CD Integration: Automated builds with Jenkins
- Containerized CI: Jenkins running in Docker with automatic Bazel installation
bazel-python-demo/
βββ WORKSPACE # Bazel project root (empty file)
βββ MODULE.bazel # Bazel module configuration
βββ BUILD.bazel # Build rules and targets
βββ hello.py # Main executable program
βββ math_utils.py # Reusable Python library
βββ Jenkinsfile.bazel # Jenkins CI/CD pipeline
βββ .gitignore # Ignore Bazel output directories
βββ README.md # This documentation
Windows:
# Install Bazel using Chocolatey (run PowerShell as Administrator)
choco install bazelmacOS:
# Install Bazel using Homebrew
brew install bazelLinux (Ubuntu/Debian):
# Install Bazel
sudo apt update
sudo apt install bazel# Clone the repository
git clone https://github.com/b95702041/bazel-python-demo.git
cd bazel-python-demo
# Build and run the program
bazel run //:helloExpected output:
Hello from Python with Bazel!
2 + 3 = 5
4 * 5 = 20
def add(a, b):
return a + b
def multiply(a, b):
return a * bSimple math functions that can be reused by other modules.
from math_utils import add, multiply
def main():
print("Hello from Python with Bazel!")
print(f"2 + 3 = {add(2, 3)}")
print(f"4 * 5 = {multiply(4, 5)}")
if __name__ == "__main__":
main()Imports and uses functions from math_utils.py.
# Create a reusable Python library
py_library(
name = "math_utils",
srcs = ["math_utils.py"],
)
# Create an executable Python program
py_binary(
name = "hello",
srcs = ["hello.py"],
deps = [":math_utils"], # Depends on the math_utils library
)Key concepts:
py_library: Creates a reusable Python modulepy_binary: Creates an executable Python programdeps: Declares dependencies between targetsname: The target name (used withbazel run //:hello)srcs: Source files for this target
This project includes a complete Jenkins CI/CD pipeline that demonstrates automated Bazel builds.
- π§ Install Bazelisk - Automatically installs Bazel using Bazelisk
- π₯ Checkout - Gets latest code from GitHub
- βΉοΈ Bazel Info - Shows Bazel version and configuration
- π§Ή Clean Build - Cleans previous build artifacts
- ποΈ Build All Targets - Builds all Bazel targets
- π§ͺ Run Tests - Executes all Bazel tests
- π Run Application - Executes the Python application
- π Query Targets - Shows all available Bazel targets
Prerequisites:
- Docker Desktop installed
- Jenkins running in Docker container
Run Jenkins in Docker:
docker run -d -p 8080:8080 -p 50000:50000 -v jenkins_home:/var/jenkins_home --name jenkins jenkins/jenkins:ltsConfigure Jenkins Pipeline:
- Create new Pipeline job
- Set Repository URL:
https://github.com/b95702041/bazel-python-demo.git - Set Script Path:
Jenkinsfile.bazel - Run the pipeline
- β Automatic Bazel Installation - Uses Bazelisk for easy setup
- β No Root Privileges Required - Installs to user directory
- β Cross-Platform Compatible - Works in Docker containers
- β Complete Build Lifecycle - Clean, build, test, run
- β Error Handling - Robust cleanup and error reporting
First run (cold build):
INFO: Elapsed time: 66.928s, Critical Path: 7.41s
Second run (cached build):
INFO: Elapsed time: 2.333s, Critical Path: 0.09s
This demonstrates Bazel's incremental build capability - it only rebuilds what has changed.
# Build everything in the project
bazel build //...
# Run a specific target
bazel run //:hello
# See the dependency graph
bazel query //...
# Get detailed build information
bazel query --output=build //:hello
# Clean build artifacts
bazel clean
# Check Bazel version
bazel --versionCreate math_utils_test.py:
import unittest
from math_utils import add, multiply
class TestMathUtils(unittest.TestCase):
def test_add(self):
self.assertEqual(add(2, 3), 5)
def test_multiply(self):
self.assertEqual(multiply(4, 5), 20)
if __name__ == '__main__':
unittest.main()Add to BUILD.bazel:
py_test(
name = "math_utils_test",
srcs = ["math_utils_test.py"],
deps = [":math_utils"],
)Run tests:
bazel test //:math_utils_testThe MODULE.bazel file (Bazel 6.0+) defines module dependencies and is the modern replacement for WORKSPACE. It provides:
- Module metadata
- Dependency declarations
- Version compatibility
- Analysis Phase: Bazel reads BUILD files and creates a dependency graph
- Execution Phase: Bazel executes only the actions needed to build requested targets
- Caching: Results are cached for fast incremental builds
- Parallelization: Independent targets build in parallel
- Fast builds: Incremental and parallel builds
- Reproducible: Same input always produces same output
- Multi-language: Supports many programming languages
- Scalable: Works for small projects to massive codebases
- Remote execution: Can distribute builds across machines
- CI/CD Ready: Perfect for automated build pipelines
This project is part of a multi-repository CI/CD demonstration:
- simple-cicd-demo - Node.js app with npm-based CI/CD
- bazel-python-demo - This Python app with Bazel-based CI/CD
Together, they demonstrate:
- Multi-language CI/CD pipelines
- Different build systems (npm vs Bazel)
- Jenkins integration with Docker
- Polyglot development workflows
- Official Bazel Documentation
- Bazel Python Tutorial
- BUILD File Reference
- Bazel Query Language
- Jenkins Pipeline Documentation
Common issues:
-
"bazel: command not found"
- Make sure Bazel is installed and in your PATH
- In CI/CD, the pipeline automatically installs Bazelisk
-
"No such package" errors
- Check that your BUILD.bazel file is in the right location
- Verify target names match what you're trying to build
-
Python import errors
- Make sure dependencies are declared in BUILD.bazel
- Check that file names match exactly
-
Permission errors on Windows
- Run PowerShell as Administrator when installing Bazel
-
Jenkins pipeline failures
- Check that Bazelisk downloaded successfully
- Verify PATH is set correctly in pipeline stages
- Look for network connectivity issues
Latest Build: β SUCCESS
β
Bazelisk: v1.26.0
β
Bazel: 8.3.1
β
Targets: 2 built successfully
β
Tests: All passed
β
Application: Executed successfully
Feel free to:
- Add more math functions to
math_utils.py - Create additional Python modules
- Add tests for the functions
- Experiment with different Bazel rules
- Improve the Jenkins pipeline
- Add more CI/CD integrations
This project is for educational purposes. Feel free to use and modify as needed.
Next steps: Try adding more Python files, creating tests, exploring Bazel's query capabilities, or integrating with other CI/CD tools!