Setup a GO Bazel Monorepo (using bzlmod)

Gustavo Gordillo - Jun 28 - - Dev Community

In this article I will describe how to set up your own Bazel repository. Using the bzlmod the new external dependency system introduced in Bazel 5+.

Also I will add a GO hello world project to show how could you add other projects to the monorepo.

Bazel logo

Let's start

The first thing you need to do is create a new directory. I will call it bazel-intro.

Inside the bazel-intro directory create a MODULE.bazel and a BUILD file:

  • MODULE.bazel: According to the official docs The MODULE.bazel file should be located at the root of the workspace directory (next to the WORKSPACE file). Unlike with the WORKSPACE file, you don’t need to specify your transitive dependencies; instead, you should only specify direct dependencies, and the MODULE.bazel files of your dependencies will be processed to discover transitive dependencies automatically. We are not going to add the WORKSPACE file.

Folder structure:

  • bazel-intro
    • MODULE.bazel
    • BUILD

Fill MODULE.bazel file

Since we are going to use GO, we need to add this lines to our MODULE.bazel file:

bazel_dep(name = "gazelle", version = "0.37.0")
bazel_dep(name = "rules_go", version = "0.48.1")

Enter fullscreen mode Exit fullscreen mode

The gazelle "dependency" enables us to use gazelle, which is a build file generator that helps us to create/update BUILDS files for every project inside our monorepo. And rules_go enables us to build GO code in bazel. You can find the more recent versions here.

According to the rules_go and gazelle docs you need to add to your MODULE.bazel file:

GO extensions

go_sdk = use_extension("@rules_go//go:extensions.bzl", "go_sdk")

# Download an SDK for the host OS & architecture as well as common remote execution platforms.
go_sdk.download(version = "1.20.3")
Enter fullscreen mode Exit fullscreen mode

Gazelle

go_deps = use_extension("@gazelle//:extensions.bzl", "go_deps")
go_deps.from_file(go_mod = "//:go.mod")
use_repo(go_deps, 
         "com_github_gofiber_fiber_v2", 
)
Enter fullscreen mode Exit fullscreen mode

In the last line you may see that we add to the rule use_repo:

  • com_github_gofiber_fiber_v2: I add this dependency here because we will setup a Fiber http server later (our GO project).

Important: If you need to add more dependecies you could do it here. For example:

Adding more deps example:

Lets say we want to add com_github_joho_godotenv to our project

use_repo(go_deps, 
         "com_github_gofiber_fiber_v2", 
         "com_github_joho_godotenv" 
)
Enter fullscreen mode Exit fullscreen mode

Filling BUILD file

Remember the build file we create at the begining? We are going to populate it with the next lines of code. In your top-level BUILD file add:

load("@gazelle//:def.bzl", "gazelle")
gazelle(name = "gazelle")

Enter fullscreen mode Exit fullscreen mode

This will add gazelle.

Creating a project

Folder structure:

  • bazel-intro
    • services
      • app
        • main.go
    • MODULE.bazel
    • BUILD

Create a project is simple.

  1. Create a directory called services.
  2. Inside services folder create a folder called app.
  3. Inside app folder create a main.go file.
  4. Add the next code to your main.go file:
package main

import (
    "log"

    "github.com/gofiber/fiber/v2"
)

func main() {
    app := fiber.New()

    app.Get("/", func (c *fiber.Ctx) error {
        return c.SendString("Hello, World!")
    })

    log.Fatal(app.Listen(":3000"))
}
Enter fullscreen mode Exit fullscreen mode

Creating go.mod and go.sum

In your terminal type go mod init something:

For example:

go mod init bazel-intro/services

Enter fullscreen mode Exit fullscreen mode

and then go mod tidy.

Let's gazelle and build :)

Run in your terminal:

bazel run //:gazelle
Enter fullscreen mode Exit fullscreen mode

then

bazel build //...
Enter fullscreen mode Exit fullscreen mode

and finally

bazel run services/app
Enter fullscreen mode Exit fullscreen mode

And that is all! 🎉🎉
You should see the fiber http server running

Go fiber http server running

. .