Permalink
Browse files

feat(bazel): introduce a binary stamping feature (#22176)

This grabs version control metadata and makes it available in the build, eg. to put in the version field for released artifacts

PR Close #22176
  • Loading branch information...
alexeagle authored and vicb committed Feb 13, 2018
1 parent a069e08 commit bba65e0f416ec89bd88c98ecd4d72d7818b54a7b
Showing with 97 additions and 1 deletion.
  1. +35 −0 docs/BAZEL.md
  2. +5 −0 packages/BUILD.bazel
  3. +9 −1 tools/BUILD.bazel
  4. +6 −0 tools/bazel.rc
  5. +42 −0 tools/bazel_stamp_vars.sh
@@ -17,6 +17,14 @@ you run the first build.

[install]: https://bazel.build/versions/master/docs/install.html

### Installation of ibazel

Install interactive bazel runner / fs watcher via:

```
yarn global add @bazel/ibazel
```

## Configuration

The `WORKSPACE` file indicates that our root directory is a
@@ -112,6 +120,33 @@ Apple+Shift+D on Mac) and click on the green play icon next to the configuration
- Open chrome at: [http://localhost:9876/debug.html](http://localhost:9876/debug.html)
- Open chrome inspector

### Debugging Bazel rules

Open `external` directory which contains everything that bazel downloaded while executing the workspace file:
```sh
open $(bazel info output_base)/external
```

See subcommands that bazel executes (helpful for debugging):
```sh
bazel build //packages/core:package -s
```

To debug nodejs_binary executable paths uncomment `find . -name rollup 1>&2` (~ line 96) in
```sh
open $(bazel info output_base)/external/build_bazel_rules_nodejs/internal/node_launcher.sh
```

## Stamping

Bazel supports the ability to include non-hermetic information from the version control system in built artifacts. This is called stamping.
You can see an overview at https://www.kchodorow.com/blog/2017/03/27/stamping-your-builds/
In our repo, here is how it's configured:

1) In `tools/bazel_stamp_vars.sh` we run the `git` commands to generate our versioning info.
1) In `tools/bazel.rc` we register this script as the value for the `workspace_status_command` flag. Bazel will run the script when it needs to stamp a binary.
1) In `tools/BUILD.bazel` we have a target `stamp_data` with the special `stamp=1` attribute, which requests that Bazel run the `workspace_status_command`. The result is written to a text file that can be used as an input to other rules.

## Remote cache

Bazel supports fetching action results from a cache, allowing a clean build to pick up artifacts from prior builds.
@@ -11,3 +11,8 @@ ts_library(
name = "types",
srcs = glob(["*.ts"]),
)

exports_files([
"license-banner.txt",
"README.md",
])
@@ -1 +1,9 @@
# Marker file indicating this folder is a Bazel package
# Executes the workspace_status_command and provides the result.
# See the section on stamping in docs/BAZEL.md
genrule(
name = "stamp_data",
outs = ["stamp_data.txt"],
cmd = "cat bazel-out/volatile-status.txt > $@",
stamp = True,
visibility = ["//:__subpackages__"],
)
@@ -21,6 +21,12 @@ build --symlink_prefix=dist/
# Performance: avoid stat'ing input files
build --watchfs

###############################
# Release support #
###############################

build --workspace_status_command=./tools/bazel_stamp_vars.sh

###############################
# Output #
###############################
@@ -0,0 +1,42 @@
#!/usr/bin/env bash
# Generates the data used by the stamping feature in bazel.
# A genrule with stamp=1 can read the resulting file from bazel-out/volatile-status.txt
# See the section on stamping in docs/BAZEL.md

set -u -e -E -o pipefail

echo "Running: $0" >&2

function onError {
echo "Failed to execute: $0"
echo ""
}

# Setup crash trap
trap 'onError' ERR


echo BUILD_SCM_HASH $(git rev-parse HEAD)

if [[ "$(git tag)" == "" ]]; then
echo "No git tags found, can't stamp the build."
echo "Either fetch the tags:"
echo " git fetch git@github.com:angular/angular.git --tags"
echo "or build without stamping by giving an empty workspace_status_command:"
echo " bazel build --workspace_status_command= ..."
echo ""
fi

BUILD_SCM_VERSION_RAW=$(git describe --abbrev=7 --tags HEAD)

# Find out if there are any uncommitted local changes
# TODO(i): is it ok to use "--untracked-files=no" to ignore untracked files since they should not affect anything?
if [[ $(git status --untracked-files=no --porcelain) ]]; then LOCAL_CHANGES="true"; else LOCAL_CHANGES="false"; fi
echo BUILD_SCM_LOCAL_CHANGES ${LOCAL_CHANGES}

# Reformat `git describe` version string into a more semver-ish string
# From: 5.2.0-rc.0-57-g757f886
# To: 5.2.0-rc.0+57.sha-757f886
# Or: 5.2.0-rc.0+57.sha-757f886.with-local-changes
BUILD_SCM_VERSION="$(echo ${BUILD_SCM_VERSION_RAW} | sed -E 's/-([0-9]+)-g/+\1.sha-/g')""$( if [[ $LOCAL_CHANGES == "true" ]]; then echo ".with-local-changes"; fi)"
echo BUILD_SCM_VERSION ${BUILD_SCM_VERSION}

0 comments on commit bba65e0

Please sign in to comment.