diff --git a/.bazelrc b/.bazelrc index f7ba2fa2af..9f8d57c87d 100644 --- a/.bazelrc +++ b/.bazelrc @@ -43,7 +43,9 @@ test --nolegacy_external_runfiles ############################### # Releases should always be stamped with version control info -build:release --workspace_status_command=./tools/bazel_stamp_vars.sh +# This command assumes node on the path and is a workaround for +# https://github.com/bazelbuild/bazel/issues/4802 +build:release --workspace_status_command="node ./tools/bazel_stamp_vars.js" ############################### # Output # diff --git a/docs/BAZEL.md b/docs/BAZEL.md index 730ba66e88..44d6c0d05d 100644 --- a/docs/BAZEL.md +++ b/docs/BAZEL.md @@ -133,7 +133,7 @@ Bazel supports the ability to include non-hermetic information from the version 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_stamp_vars.js` we run the `git` commands to generate our versioning info. 1) In `.bazelrc` 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. Note that Bazel has a `--stamp` argument to `yarn bazel build`, but this has no effect since our stamping takes place in Skylark rules. See https://github.com/bazelbuild/bazel/issues/1054 diff --git a/tools/bazel_stamp_vars.js b/tools/bazel_stamp_vars.js new file mode 100644 index 0000000000..3b7052aae4 --- /dev/null +++ b/tools/bazel_stamp_vars.js @@ -0,0 +1,56 @@ +/** + * @license + * Copyright Google Inc. All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.io/license + */ + +// tslint:disable:no-console +// Generates the data used by the stamping feature in bazel. +// See the section on stamping in docs / BAZEL.md +// This script must be a NodeJS script in order to be cross-platform. +// See https://github.com/bazelbuild/bazel/issues/5958 +// Note: git operations, especially git status, take a long time inside mounted docker volumes +// in Windows or OSX hosts (https://github.com/docker/for-win/issues/188). +const execSync = require('child_process').execSync; +function _exec(str) { + return execSync(str).toString().trim(); +} + +console.error('Running', process.argv.join(' ')); + +function onError() { + console.error('Failed to execute:,', process.argv.join(' ')); + console.error(''); +} + +// Setup crash handler +process.on('uncaughtException', onError); + +const BUILD_SCM_HASH = _exec(`git rev-parse HEAD`); +console.log(`BUILD_SCM_HASH ${BUILD_SCM_HASH}`); + +if (_exec(`git tag`) == '') { + console.error(`No git tags found, can't stamp the build.`); + console.error('Please fetch the tags first:'); + console.error(' git fetch git@github.com:angular/angular.git --tags'); +} + +// Find out if there are any uncommitted local changes +const LOCAL_CHANGES = _exec(`git status --untracked-files=no --porcelain`) != ''; +console.log(`BUILD_SCM_LOCAL_CHANGES ${LOCAL_CHANGES}`); + +// Only match the latest tag that is a version such as 6.0.0, 6.0.0-rc.5, etc... +// This will ignore non-version tags which would break unit tests expecting a valid version +// number in the package headers +const BUILD_SCM_VERSION_RAW = + _exec(`git describe --match [0-9].[0-9].[0-9]* --abbrev=7 --tags HEAD`); + +// 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 +const BUILD_SCM_VERSION = BUILD_SCM_VERSION_RAW.replace(/-([0-9]+)-g/, '+$1.sha-') + + (LOCAL_CHANGES ? '.with-local-changes' : ''); +console.log(`BUILD_SCM_VERSION ${BUILD_SCM_VERSION}`); diff --git a/tools/bazel_stamp_vars.sh b/tools/bazel_stamp_vars.sh deleted file mode 100755 index 028877acec..0000000000 --- a/tools/bazel_stamp_vars.sh +++ /dev/null @@ -1,44 +0,0 @@ -#!/usr/bin/env bash -# Generates the data used by the stamping feature in bazel. -# 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 " yarn bazel build --workspace_status_command= ..." - echo "" -fi - -# Only match the latest tag that is a version such as 6.0.0, 6.0.0-rc.5, etc... -# This will ignore non-version tags which would break unit tests expecting a valid version -# number in the package headers -BUILD_SCM_VERSION_RAW=$(git describe --match [0-9].[0-9].[0-9]* --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}