#!/bin/bash # symbol prefixes: # g_ -> global # l_ - local variable # f_ -> function set -euo pipefail GITIAN_CACHE_DIRNAME='.gitian-builder-cache' GO_RELEASE='1.13.3' GO_TARBALL="go${GO_RELEASE}.linux-amd64.tar.gz" GO_TARBALL_URL="https://dl.google.com/go/${GO_TARBALL}" # Defaults DEFAULT_SIGN_COMMAND='gpg --detach-sign' DEFAULT_TENDERMINT_SIGS=${TENDERMINT_SIGS:-'tendermint.sigs'} DEFAULT_GITIAN_REPO='https://github.com/tendermint/gitian-builder' DEFAULT_GBUILD_FLAGS='' DEFAULT_SIGS_REPO='https://github.com/tendermint/tendermint.sigs' # Overrides SIGN_COMMAND=${SIGN_COMMAND:-${DEFAULT_SIGN_COMMAND}} GITIAN_REPO=${GITIAN_REPO:-${DEFAULT_GITIAN_REPO}} GBUILD_FLAGS=${GBUILD_FLAGS:-${DEFAULT_GBUILD_FLAGS}} # Globals g_workdir='' g_gitian_cache='' g_cached_gitian='' g_cached_go_tarball='' g_sign_identity='' g_sigs_dir='' g_flag_commit='' f_help() { cat >&2 <&2 mkdir "${l_builddir}/inputs/" cp -v "${g_cached_go_tarball}" "${l_builddir}/inputs/" done } f_build() { local l_descriptor l_descriptor=$1 bin/gbuild --commit tendermint="$g_commit" ${GBUILD_FLAGS} "$l_descriptor" libexec/stop-target || f_echo_stderr "warning: couldn't stop target" } f_sign_verify() { local l_descriptor l_descriptor=$1 bin/gsign -p "${SIGN_COMMAND}" -s "${g_sign_identity}" --destination="${g_sigs_dir}" --release=${g_release} ${l_descriptor} bin/gverify --destination="${g_sigs_dir}" --release="${g_release}" ${l_descriptor} } f_commit_sig() { local l_release_name l_release_name=$1 pushd "${g_sigs_dir}" git add . || echo "git add failed" >&2 git commit -m "Add ${l_release_name} reproducible build" || echo "git commit failed" >&2 popd } f_prep_docker_image() { pushd $1 bin/make-base-vm --docker --suite bionic --arch amd64 popd } f_ensure_cache() { g_gitian_cache="${g_workdir}/${GITIAN_CACHE_DIRNAME}" [ -d "${g_gitian_cache}" ] || mkdir "${g_gitian_cache}" g_cached_go_tarball="${g_gitian_cache}/${GO_TARBALL}" if [ ! -f "${g_cached_go_tarball}" ]; then f_echo_stderr "${g_cached_go_tarball}: cache miss, caching..." curl -L "${GO_TARBALL_URL}" --output "${g_cached_go_tarball}" fi g_cached_gitian="${g_gitian_cache}/gitian-builder" if [ ! -d "${g_cached_gitian}" ]; then f_echo_stderr "${g_cached_gitian}: cache miss, caching..." git clone ${GITIAN_REPO} "${g_cached_gitian}" fi } f_demangle_platforms() { case "${1}" in all) printf '%s' 'darwin linux windows' ;; linux|darwin|windows) printf '%s' "${1}" ;; *) echo "invalid platform -- ${1}" exit 1 esac } f_echo_stderr() { echo $@ >&2 } while getopts ":cs:h" opt; do case "${opt}" in h) f_help ; exit 0 ;; c) g_flag_commit=y ;; s) g_sign_identity="${OPTARG}" ;; esac done shift "$((OPTIND-1))" g_platforms=$(f_demangle_platforms "${1}") g_workdir="$(pwd)" g_commit="$(git rev-parse HEAD)" g_sigs_dir=${TENDERMINT_SIGS:-"${g_workdir}/${DEFAULT_TENDERMINT_SIGS}"} f_ensure_cache f_prep_docker_image "${g_cached_gitian}" f_prep_build "${g_platforms}" export USE_DOCKER=1 for g_os in ${g_platforms}; do g_release="$(git describe --tags --abbrev=9 | sed 's/^v//')-${g_os}" g_descriptor="${g_workdir}/scripts/gitian-descriptors/gitian-${g_os}.yml" [ -f ${g_descriptor} ] g_builddir="$(f_builddir ${g_os})" pushd "${g_builddir}" f_build "${g_descriptor}" if [ -n "${g_sign_identity}" ]; then f_sign_verify "${g_descriptor}" fi popd if [ -n "${g_sign_identity}" -a -n "${g_flag_commit}" ]; then [ -d "${g_sigs_dir}/.git/" ] && f_commit_sig ${g_release} || f_echo_stderr "couldn't commit, ${g_sigs_dir} is not a git clone" fi done exit 0