From bba65e0f416ec89bd88c98ecd4d72d7818b54a7b Mon Sep 17 00:00:00 2001 From: Alex Eagle Date: Tue, 13 Feb 2018 08:20:35 -0800 Subject: [PATCH] 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 --- docs/BAZEL.md | 35 ++++++++++++++++++++++++++++++++ packages/BUILD.bazel | 5 +++++ tools/BUILD.bazel | 10 +++++++++- tools/bazel.rc | 6 ++++++ tools/bazel_stamp_vars.sh | 42 +++++++++++++++++++++++++++++++++++++++ 5 files changed, 97 insertions(+), 1 deletion(-) create mode 100755 tools/bazel_stamp_vars.sh diff --git a/docs/BAZEL.md b/docs/BAZEL.md index 2425d885dc..2794e47e78 100644 --- a/docs/BAZEL.md +++ b/docs/BAZEL.md @@ -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. diff --git a/packages/BUILD.bazel b/packages/BUILD.bazel index 6eabba7244..2a5869794c 100644 --- a/packages/BUILD.bazel +++ b/packages/BUILD.bazel @@ -11,3 +11,8 @@ ts_library( name = "types", srcs = glob(["*.ts"]), ) + +exports_files([ + "license-banner.txt", + "README.md", +]) diff --git a/tools/BUILD.bazel b/tools/BUILD.bazel index 71b169e14f..72655ac4ed 100644 --- a/tools/BUILD.bazel +++ b/tools/BUILD.bazel @@ -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__"], +) diff --git a/tools/bazel.rc b/tools/bazel.rc index ea6c92f0f4..3069d9c4c6 100644 --- a/tools/bazel.rc +++ b/tools/bazel.rc @@ -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 # ############################### diff --git a/tools/bazel_stamp_vars.sh b/tools/bazel_stamp_vars.sh new file mode 100755 index 0000000000..2d05c58365 --- /dev/null +++ b/tools/bazel_stamp_vars.sh @@ -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}