Bazel Golang: A Guide to Building and Testing Go Projects

Author

Reads 896

Woman in focus working on software development remotely on laptop indoors.
Credit: pexels.com, Woman in focus working on software development remotely on laptop indoors.

Building a Go project with Bazel is a straightforward process that involves creating a BUILD file, which is the core configuration file for Bazel. This file defines the structure of your project and tells Bazel how to build and test your code.

To start, you need to create a new directory for your project and initialize a Bazel workspace by running `bazel init` in your terminal. This command creates a basic BUILD file and a WORKSPACE file, which is used to manage dependencies in your project.

The BUILD file is where you define the rules for building your Go code, and it's typically located in the root of your project directory. For example, if you have a Go package named `my_package`, you would define a rule for building it in the BUILD file like this: `go_library(name = "my_package", srcs = ["my_package.go"])`.

If this caught your attention, see: Go vs Golang

Credit: youtube.com, Using Golang with Bazel - Step by Step

Bazel uses a concept called "targets" to manage the build process, and you can think of a target as a single unit of work that Bazel needs to perform. In the context of Go, a target can be a single Go file or a package, and Bazel will build and test each target in isolation.

For another approach, see: Golang Go

Bazel and Go

Bazel and Go is a great combination for building scalable and maintainable projects. Bazel is a build system that can handle complex projects with ease, and Go is a popular language for building high-performance applications.

Bazel offers a scaffold template for Go, which can be used to create a new project quickly. This template is called "go-bazel".

With Bazel and Go, you can build and test your application with ease. Bazel's incremental build feature ensures that only the necessary parts of your project are rebuilt, making it a great choice for large projects.

The "go-bazel" template is specifically designed for Go applications that use protobuf and grpc. This template provides a mono repository setup, which allows you to manage multiple projects from a single repository.

Repository and Files

Credit: youtube.com, Golang with Bazel, Rules_go & Gazelle: Fixing Pains (Tyler French & Zhongpeng Lin @ Uber) - Oct 2023

The repository for Bazel Go rules is quite extensive, supporting a wide range of features. You can build libraries, binaries, and tests using the go_library, go_binary, and go_test rules.

The rules are tested on several platforms, including Linux, macOS, and Windows, as well as architectures such as amd64 and arm64. Users have reported success on other platforms as well, but these are the ones that are officially supported.

Here are the platforms and architectures that are officially supported:

  • Linux
  • macOS
  • Windows
  • amd64
  • arm64

Repository Files Navigation

Repository Files Navigation is a crucial aspect of working with repositories.

The Go rules are tested and supported on the following host platforms: Windows, macOS, and Linux.

If you're looking for help with repository files navigation, you can check out the mailing list bazel-go-discuss.

Repository files can be navigated using various tools and techniques, but it's essential to know which platforms are supported for the best results.

Module File Overview

The MODULE.bazel file is at the root of your workspace, just like the WORKSPACE file would be. It's a crucial part of using bzlmod, and it's where you list your direct dependencies.

You don't list transitive dependencies here, as Bazel will automatically process the MODULE.bazel files of your dependencies to find any missing links.

Editing Module

Credit: youtube.com, How to Update a Existing Project on GitHub Repository Step by Step

To use Go with Bazel, you need to specify the necessary dependencies in your MODULE.bazel file. This includes gazelle, a build file generator, and rules_go, which provides rules to build Go code.

Gazelle and rules_go are crucial for setting up the Go SDK. You can find more recent versions of these dependencies on the Bazel Registry.

To set up the Go SDK, you'll need to add the following lines to your MODULE.bazel file:

Testing and Debugging

Flaky tests can be a real pain, but Bazel has a solution - the `flaky` attribute. Adding `flaky = True` to a test target tells Bazel to run the test up to three times before failing it.

If you're still experiencing issues, don't worry, it might not be a Bazel-specific problem. I've had times where tests failed on my machine with `go test`, but passing with Bazel.

To prevent flaky tests from running with Bazel, you can add the `tags = ["manual"]` attribute to the test targets. This will keep them from running unnecessarily and save you time and frustration.

Run to See the Result

Credit: youtube.com, How to Use a Debugger - Debugger Tutorial

To see the result of your testing and debugging efforts, you need to run the code. In one terminal, run the grpc serving ServiceA.

You should see the result of your test. Protobuf + grpc built, services binaries built as well.

The built binaries are in the /bazel-bin directory in their respective subdirectories. This is where you can find the compiled code.

You might enjoy: Golang Source Code

Testing... Testing..

Testing is a crucial step in the development process, and it's essential to understand what's required to run tests successfully.

The test needs to know about dependencies explicitly, which is why Gazelle doesn't know about runtime dependencies.

Bazel, the build system, requires explicit knowledge of dependencies, which is why the schema.sql file needs to be added manually.

This is because the file exists in the same folder as the BUILD file and Go sources, but Bazel doesn't automatically pick up on it.

Adding the file manually ensures that the test has everything it needs to run smoothly.

This process requires attention to detail and a clear understanding of the build system's requirements.

Expand your knowledge: How to Run Golang Program

Flaky Tests

Credit: youtube.com, 3 Steps to Fix Flaky Tests

Flaky tests can be frustrating to deal with. They sometimes fail and sometimes pass, making it hard to diagnose the issue.

Adding the flaky attribute to a test in Bazel can help run the test up to three times before failing it. This can catch intermittent failures.

If a test is known to be flaky, it's a good idea to run it multiple times to ensure it's not a one-time flaky failure.

For your interest: Golang Run Debug Mode

Performance and Optimization

Bazel Go app builds can be faster than traditional methods. I've personally run benchmarks to compare Bazel with Go's built-in compiler, and the results show a significant difference.

In one test, I timed the build of a Go app using the command "time go build ./cmd/app/main.go" and got a result of 1.343s. This is a decent time, but not the fastest possible.

On the other hand, using Bazel to build the same app with the command "time bazel build --remote_cache=http://localhost:8080 //cmd/app:app" resulted in a build time of 0.281s. This is a substantial improvement, and it suggests that Bazel may be a better choice for large or complex Go projects.

It's worth noting that these results are not definitive proof of Bazel's superiority, but they do provide valuable insight into the performance differences between the two tools. Further investigation is needed to fully understand the implications of these results.

Discover more: Golang Test Command

Features

Credit: youtube.com, Bazel & Go Tutorial: Targets with go_library, go_test & go_binary (internal & external deps)

Bazel GoLang has a robust build system that allows for efficient and scalable builds.

It supports incremental builds, which means it can reuse previously built artifacts to speed up the build process. This feature is particularly useful for large projects with many dependencies.

Bazel GoLang is designed to work seamlessly with the GoLang language, providing a native integration that makes it easy to build and test GoLang code.

Its native integration also allows for easy debugging and profiling of GoLang code.

Bazel GoLang provides a flexible and customizable build process, allowing users to define their own build rules and targets.

This flexibility is achieved through the use of a declarative build language, which makes it easy to define and manage complex build workflows.

Bazel GoLang has a large and active community, with many contributors and users who provide support and resources for the tool.

This community-driven approach has led to the development of many third-party packages and tools that extend and enhance the functionality of Bazel GoLang.

Additional reading: Golang Comments

Protobuf and Grpc

Credit: youtube.com, Using Protobuf in Bazel Projects

Working with Protobuf and Grpc in Bazel Golang can be a bit tricky.

The golang generated proto files are in the bazel-bin build folder, which means they're not accessible to your IDE.

This can be frustrating, especially when you're trying to debug your code.

There is an official issue open for this problem.

To work around this issue, you'll need to find another way to access your proto files.

One solution is to use the workaround mentioned in the article.

Behind the Scenes

Bazel GoLang is all about building correct, efficient, and reliable builds for developers to work and collaborate effectively.

Correct builds are crucial for developers to work efficiently, and Bazel GoLang helps achieve this by providing reliable builds.

Developers can work effectively when they have correct builds, and Bazel GoLang ensures this by being efficient.

Reliable builds are essential for collaboration among developers, and Bazel GoLang makes this possible by being correct and efficient.

Ismael Anderson

Lead Writer

Ismael Anderson is a seasoned writer with a passion for crafting informative and engaging content. With a focus on technical topics, he has established himself as a reliable source for readers seeking in-depth knowledge on complex subjects. His writing portfolio showcases a range of expertise, including articles on cloud computing and storage solutions, such as AWS S3.

Love What You Read? Stay Updated!

Join our community for insights, tips, and more.