diff --git a/.circleci/bash_env.sh b/.circleci/bash_env.sh index 8e19111654..f644a8b390 100644 --- a/.circleci/bash_env.sh +++ b/.circleci/bash_env.sh @@ -4,4 +4,5 @@ export GIT_COMMIT=$(git rev-parse --short HEAD) export GIT_COMMIT_YEAR=$(git show -s --format=%cd --date=format:%Y HEAD) export GIT_DIRTY=$(test -n "`git status --porcelain`" && echo "+CHANGES" || true) export GIT_IMPORT=github.com/hashicorp/consul/version -export GOLDFLAGS="-X ${GIT_IMPORT}.GitCommit=${GIT_COMMIT}${GIT_DIRTY}" +export GIT_DATE=$("${CIRCLE_WORKING_DIRECTORY}/build-support/scripts/build-date.sh") # we're using this for build date because it's stable across platform builds +export GOLDFLAGS="-X ${GIT_IMPORT}.GitCommit=${GIT_COMMIT}${GIT_DIRTY} -X $(GIT_IMPORT).BuildDate=$(GIT_DATE)" diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index cb0e6ee075..654fb7c960 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -15,6 +15,7 @@ jobs: runs-on: ubuntu-latest outputs: product-version: ${{ steps.get-product-version.outputs.product-version }} + product-date: ${{ steps.get-product-version.outputs.product-date }} pre-version: ${{ steps.get-product-version.outputs.pre-version }} pkg-version: ${{ steps.get-product-version.outputs.pkg-version }} shared-ldflags: ${{ steps.shared-ldflags.outputs.shared-ldflags }} @@ -24,6 +25,7 @@ jobs: id: get-product-version run: | CONSUL_VERSION=$(build-support/scripts/version.sh -r) + CONSUL_DATE=$(build-support/scripts/build-date.sh -r) ## TODO: This assumes `make version` outputs 1.1.1+ent-prerel IFS="+" read VERSION _other <<< "$CONSUL_VERSION" IFS="-" read _other PREREL_VERSION <<< "$CONSUL_VERSION" @@ -32,12 +34,15 @@ jobs: ## [version]{-prerelease}+ent before then, we'll need to add ## logic to handle presense/absence of the prerelease echo "::set-output name=product-version::${CONSUL_VERSION}" + echo "::set-output name=product-date::${CONSUL_DATE}" echo "::set-output name=pre-version::${PREREL_VERSION}" echo "::set-output name=pkg-version::${VERSION}" - name: Set shared -ldflags id: shared-ldflags - run: echo "::set-output name=shared-ldflags::-X github.com/hashicorp/consul/version.GitCommit=${GITHUB_SHA::8} -X github.com/hashicorp/consul/version.GitDescribe=${{ steps.get-product-version.outputs.product-version }}" + run: | + T="github.com/hashicorp/consul/version" + echo "::set-output name=shared-ldflags::-X ${T}.GitCommit=${GITHUB_SHA::8} -X ${T}.GitDescribe=${{ steps.get-product-version.outputs.product-version }} -X ${T}.BuildDate=${{ steps.get-product-version.outputs.product-date }}" generate-metadata-file: needs: get-product-version diff --git a/build-support/functions/10-util.sh b/build-support/functions/10-util.sh index 6a5f7282d1..e9a6837bab 100644 --- a/build-support/functions/10-util.sh +++ b/build-support/functions/10-util.sh @@ -274,6 +274,42 @@ function git_branch { return ${ret} } + +function git_date { + # Arguments: + # $1 - Path to the git repo (optional - assumes pwd is git repo otherwise) + # + # Returns: + # 0 - success + # * - failure + # + # Notes: + # Echos the date of the last git commit in + + local gdir="$(pwd)" + if test -d "$1" + then + gdir="$1" + fi + + pushd "${gdir}" > /dev/null + + local ret=0 + + # it's tricky to do an RFC3339 format in a cross platform way, so we hardcode UTC + local date_format="%Y-%m-%dT%H:%M:%SZ" + # we're using this for build date because it's stable across platform builds + local date=$(git show -s --format=%cd --date=format:"$date_format" HEAD) + + ##local head="$(git status -b --porcelain=v2 | awk '{if ($1 == "#" && $2 =="branch.head") { print $3 }}')" || ret=1 + + popd > /dev/null + + test ${ret} -eq 0 && echo "$date" + return ${ret} +} + + function is_git_clean { # Arguments: # $1 - Path to git repo @@ -325,7 +361,8 @@ function update_git_env { export GIT_COMMIT=$(git rev-parse --short HEAD) export GIT_DIRTY=$(test -n "$(git status --porcelain)" && echo "+CHANGES") export GIT_IMPORT=github.com/hashicorp/consul/version - export GOLDFLAGS="-X ${GIT_IMPORT}.GitCommit=${GIT_COMMIT}${GIT_DIRTY}" + export GIT_DATE=$(git_date "$1") + export GOLDFLAGS="-X ${GIT_IMPORT}.GitCommit=${GIT_COMMIT}${GIT_DIRTY} -X ${T}.BuildDate=${GIT_DATE}" return 0 } diff --git a/build-support/scripts/build-date.sh b/build-support/scripts/build-date.sh new file mode 100755 index 0000000000..54b02fced7 --- /dev/null +++ b/build-support/scripts/build-date.sh @@ -0,0 +1,78 @@ +#!/bin/bash +SCRIPT_NAME="$(basename ${BASH_SOURCE[0]})" +pushd $(dirname ${BASH_SOURCE[0]}) > /dev/null +SCRIPT_DIR=$(pwd) +pushd ../.. > /dev/null +SOURCE_DIR=$(pwd) +popd > /dev/null +pushd ../functions > /dev/null +FN_DIR=$(pwd) +popd > /dev/null +popd > /dev/null + +source "${SCRIPT_DIR}/functions.sh" + +function usage { +cat <<-EOF +Usage: ${SCRIPT_NAME} [] + +Description: + + This script uses the date of the last checkin on the branch as the build date. This + is to make the date consistent across the various platforms we build on, even if they + start at different times. In practice this is the commit where the version string is set. + +Options: + -s | --source DIR Path to source to build. + Defaults to "${SOURCE_DIR}" + +EOF +} + +function err_usage { + err "$1" + err "" + err "$(usage)" +} + +function main { + declare sdir="${SOURCE_DIR}" + declare -i date=0 + + while test $# -gt 0 + do + case "$1" in + -h | --help ) + usage + return 0 + ;; + -s | --source ) + if test -z "$2" + then + err_usage "ERROR: option -s/--source requires an argument" + return 1 + fi + + if ! test -d "$2" + then + err_usage "ERROR: '$2' is not a directory and not suitable for the value of -s/--source" + return 1 + fi + + sdir="$2" + shift 2 + ;; + *) + err_usage "ERROR: Unknown argument: '$1'" + return 1 + ;; + esac + done + + git_date "${sdir}" || return 1 + + return 0 +} + +main "$@" +exit $?