description: "bzlmod makes bazel extremely appealing and isn't hard to grasp for anyone already familiar with go modules. My frustration with make for complex builds led me to bazel."
summary: "bzlmod makes bazel extremely appealing and isn't hard to grasp for anyone already familiar with go modules. My frustration with make for complex builds led me to bazel."
description: "Maxing out your CPU for fun and profit with dense graphs, or how I'm attempting to follow through on my plan to work on projects with more visual outputs"
summary: "Maxing out your CPU for fun and profit with dense graphs, or how I'm attempting to follow through on my plan to work on projects with more visual outputs"
description: "Note-taking and the tools we use to do it can present an overwhelming abundance of possibility. Explicitly modelling your notes as tools can grant clarity when creating and organizing your knowledge."
summary: "Note-taking and the tools we use to do it can present an overwhelming abundance of possibility. Explicitly modelling your notes as tools can grant clarity when creating and organizing your knowledge."
description: "Versioning is a critical part of delivering software to users. With bazel, you can derive per-build values and inject them anywhere in your build process."
summary: "Versioning is a critical part of delivering software to users. With bazel, you can derive per-build values and inject them anywhere in your build process."
summary: "Versioning is a critical part of delivering software to users. With bazel, you can derive per-build values and inject them anywhere in your build process."
showFullContent: false
showFullContent: false
tags:
tags:
- bazel
- bazel
@ -20,22 +21,22 @@ In my [last post](/2024/09/the-joy-of-versioning/) I spent some time talking abo
That post was pretty light on direct `bazel` usage but I promise, it'll pay off. Here, we're going to cover how to use these tags *in* your builds to tag docker images or inject build information into compiled binaries.
That post was pretty light on direct `bazel` usage but I promise, it'll pay off. Here, we're going to cover how to use these tags *in* your builds to tag docker images or inject build information into compiled binaries.
I'm assuming that you've read the [first bazel post](/2023/08/beautiful-builds-with-bazel/) in this series, or that you've already got your bazel + bzlmod setup going.
I'm assuming that you've read the [first bazel post](/2023/08/beautiful-builds-with-bazel/) in this series, or that you've already got your bazel + bzlmod setup going.
## Stamping and you
## Stamping and you
Bazel includes functionality that it calls "stamping". Bazel has to separate this into its own conceptual space because one of the core design principles is build reproducibility: for bazel's caching to work, inputs have to be deterministic and ideally change infrequently between runs.
Bazel includes functionality that it calls "stamping". Bazel has to separate this into its own conceptual space because one of the core design principles is build reproducibility: for bazel's caching to work, inputs have to be deterministic and ideally change infrequently between runs.
Bazel's [documentation](https://bazel.build/docs/user-manual#workspace-status) covers the bare essentials, with a small caveat. Stamping requires a script , the "workplace status" script, that emits space-separated key-value pairs, e.g. `STABLE_KEY_NAME VALUE`. An example script is included below.
Bazel's [documentation](https://bazel.build/docs/user-manual#workspace-status) covers the bare essentials, with a small caveat. Stamping requires a script , the "workplace status" script, that emits space-separated key-value pairs, e.g. `STABLE_KEY_NAME VALUE`. An example script is included below.
@ -46,52 +47,52 @@ One important detail that the documentation doesn't cover is that your workspace
Still not sure why, but if you simply do `bazel --workplace_status_command=status.sh`, `bazel` will *only* look for it in your `$PATH`.
Still not sure why, but if you simply do `bazel --workplace_status_command=status.sh`, `bazel` will *only* look for it in your `$PATH`.
## Build Injection
## Build Injection
Using the variables created by your workspace status script ends up being incredibly simple, if you're using `rules_go`. the `x_defs` parameter lets you override values at compile-time, exactly for cases like this.
Using the variables created by your workspace status script ends up being incredibly simple, if you're using `rules_go`. the `x_defs` parameter lets you override values at compile-time, exactly for cases like this.
```
```
x_defs = {
x_defs = {
"Version": "{STABLE_STAMP_VERSION}",
"Version": "{STABLE_STAMP_VERSION}",
"Build": "{STABLE_STAMP_COMMIT}",
"Build": "{STABLE_STAMP_COMMIT}",
},
},
```
```
This is equivalent to the Go build flag `-ldflags "-X PACKAGENAME.Version=whatever -X PACKAGENAME.BUILD=whatever"`. It's important to note that the raw Go flags require a fully qualified package name be specified. Bazel is smart enough to derive the necessary package name on its own, all you have to do is tell it which variable needs to be overriden with what value.
This is equivalent to the Go build flag `-ldflags "-X PACKAGENAME.Version=whatever -X PACKAGENAME.BUILD=whatever"`. It's important to note that the raw Go flags require a fully qualified package name be specified. Bazel is smart enough to derive the necessary package name on its own, all you have to do is tell it which variable needs to be overriden with what value.
## Putting it all together
## Putting it all together
The final, full invocation for stamping your builds should look something like this.
The final, full invocation for stamping your builds should look something like this.
```
```
wikilink-obsidian-resolver on main [⇡] via 🐹 v1.22.2
wikilink-obsidian-resolver on main [⇡] via 🐹 v1.22.2
❯ bazel run --stamp --workspace_status_command=tools/workspace_status.sh //cmd/version
❯ bazel run --stamp --workspace_status_command=tools/workspace_status.sh //cmd/version
description: "As a collection of Markdown documents grows organically, maintaining consistency is important. JSONSchema offers a way to automatically ensure frontmatter stays up to spec."
summary: "As a collection of Markdown documents grows organically, maintaining consistency is important. JSONSchema offers a way to automatically ensure frontmatter stays up to spec."
showFullContent: false
showFullContent: false
tags:
tags:
- yaml
- yaml
@ -21,7 +21,7 @@ Over my time using Obsidian, I've independently authored around 400 notes. Over
2023/06/01 10:31:27 validation error: &fmt.wrapError{msg:"error validating target: jsonschema: '' does not validate with https://schemas.ndumas.com/obsidian/note.schema.json#/required: missing properties: 'title', 'description', 'tags'", err:(*jsonschema.ValidationError)(0xc0000b3740)}
2023/06/01 10:31:27 validation error: &fmt.wrapError{msg:"error validating target: jsonschema: '' does not validate with https://schemas.ndumas.com/obsidian/note.schema.json#/required: missing properties: 'title', 'summary', 'tags'", err:(*jsonschema.ValidationError)(0xc0000b3740)}
2023/06/01 10:31:27 error count for "schema-bad.md": 1
2023/06/01 10:31:27 error count for "schema-bad.md": 1
2023/06/01 10:31:27 scanning "schema-good.md"
2023/06/01 10:31:27 scanning "schema-good.md"
```
```
You get a relatively detailed description of why validation failed and a non-zero exit code, exactly what you need to prevent malformed data from entering your pipeline.
You get a relatively detailed summary of why validation failed and a non-zero exit code, exactly what you need to prevent malformed data from entering your pipeline.
### how to schema library?
### how to schema library?
You might notice that when I specify a schema, it's hosted at `schemas.ndumas.com`. [Here](https://code.ndumas.com/ndumas/json-schemas) you can find the repository powering that domain.
You might notice that when I specify a schema, it's hosted at `schemas.ndumas.com`. [Here](https://code.ndumas.com/ndumas/json-schemas) you can find the repository powering that domain.