github.com/fiagdao/tendermint@v0.32.11-0.20220824195748-2087fcc480c1/scripts/gitian-build.sh (about)

     1  #!/bin/bash
     2  
     3  # symbol prefixes:
     4  # g_ -> global
     5  # l_ - local variable
     6  # f_ -> function
     7  
     8  set -euo pipefail
     9  
    10  GITIAN_CACHE_DIRNAME='.gitian-builder-cache'
    11  GO_RELEASE='1.13.3'
    12  GO_TARBALL="go${GO_RELEASE}.linux-amd64.tar.gz"
    13  GO_TARBALL_URL="https://dl.google.com/go/${GO_TARBALL}"
    14  
    15  # Defaults
    16  
    17  DEFAULT_SIGN_COMMAND='gpg --detach-sign'
    18  DEFAULT_TENDERMINT_SIGS=${TENDERMINT_SIGS:-'tendermint.sigs'}
    19  DEFAULT_GITIAN_REPO='https://github.com/tendermint/gitian-builder'
    20  DEFAULT_GBUILD_FLAGS=''
    21  DEFAULT_SIGS_REPO='https://github.com/tendermint/tendermint.sigs'
    22  
    23  # Overrides
    24  
    25  SIGN_COMMAND=${SIGN_COMMAND:-${DEFAULT_SIGN_COMMAND}}
    26  GITIAN_REPO=${GITIAN_REPO:-${DEFAULT_GITIAN_REPO}}
    27  GBUILD_FLAGS=${GBUILD_FLAGS:-${DEFAULT_GBUILD_FLAGS}}
    28  
    29  # Globals
    30  
    31  g_workdir=''
    32  g_gitian_cache=''
    33  g_cached_gitian=''
    34  g_cached_go_tarball=''
    35  g_sign_identity=''
    36  g_sigs_dir=''
    37  g_flag_commit=''
    38  
    39  
    40  f_help() {
    41    cat >&2 <<EOF
    42  Usage: $(basename $0) [-h] PLATFORM
    43  Launch a gitian build from the current source directory for the given PLATFORM.
    44  The following platforms are supported:
    45    darwin
    46    linux
    47    windows
    48    all
    49  
    50    Options:
    51     -h               display this help and exit
    52     -c               clone the signatures repository and commit signatures;
    53                      ignored if sign identity is not supplied
    54     -s IDENTITY      sign build as IDENTITY
    55  
    56  If a GPG identity is supplied via the -s flag, the build will be signed and verified.
    57  The signature will be saved in '${DEFAULT_TENDERMINT_SIGS}/'. An alternative output directory
    58  for signatures can be supplied via the environment variable \$TENDERMINT_SIGS.
    59  
    60  The default signing command used to sign the build is '$DEFAULT_SIGN_COMMAND'.
    61  An alternative signing command can be supplied via the environment
    62  variable \$SIGN_COMMAND.
    63  EOF
    64  }
    65  
    66  
    67  f_builddir() {
    68    printf '%s' "${g_workdir}/gitian-build-$1"
    69  }
    70  
    71  f_prep_build() {
    72    local l_platforms \
    73      l_os \
    74      l_builddir
    75  
    76    l_platforms="$1"
    77  
    78    if [ -n "${g_flag_commit}" -a ! -d "${g_sigs_dir}" ]; then
    79      git clone ${DEFAULT_SIGS_REPO} "${g_sigs_dir}"
    80    fi
    81  
    82    for l_os in ${l_platforms}; do
    83      l_builddir="$(f_builddir ${l_os})"
    84  
    85      f_echo_stderr "Preparing build directory $(basename ${l_builddir}), restoring files from cache"
    86      cp -ar "${g_cached_gitian}" "${l_builddir}" >&2
    87      mkdir "${l_builddir}/inputs/"
    88      cp -v "${g_cached_go_tarball}" "${l_builddir}/inputs/"
    89    done
    90  }
    91  
    92  f_build() {
    93    local l_descriptor
    94  
    95    l_descriptor=$1
    96  
    97    bin/gbuild --commit tendermint="$g_commit" ${GBUILD_FLAGS} "$l_descriptor"
    98    libexec/stop-target || f_echo_stderr "warning: couldn't stop target"
    99  }
   100  
   101  f_sign_verify() {
   102    local l_descriptor
   103  
   104    l_descriptor=$1
   105  
   106    bin/gsign -p "${SIGN_COMMAND}" -s "${g_sign_identity}" --destination="${g_sigs_dir}" --release=${g_release} ${l_descriptor}
   107    bin/gverify --destination="${g_sigs_dir}" --release="${g_release}" ${l_descriptor}
   108  }
   109  
   110  f_commit_sig() {
   111    local l_release_name
   112  
   113    l_release_name=$1
   114  
   115    pushd "${g_sigs_dir}"
   116    git add . || echo "git add failed" >&2
   117    git commit -m "Add ${l_release_name} reproducible build" || echo "git commit failed" >&2
   118    popd
   119  }
   120  
   121  f_prep_docker_image() {
   122    pushd $1
   123    bin/make-base-vm --docker --suite bionic --arch amd64
   124    popd
   125  }
   126  
   127  f_ensure_cache() {
   128    g_gitian_cache="${g_workdir}/${GITIAN_CACHE_DIRNAME}"
   129    [ -d "${g_gitian_cache}" ] || mkdir "${g_gitian_cache}"
   130  
   131    g_cached_go_tarball="${g_gitian_cache}/${GO_TARBALL}"
   132    if [ ! -f "${g_cached_go_tarball}" ]; then
   133    f_echo_stderr "${g_cached_go_tarball}: cache miss, caching..."
   134      curl -L "${GO_TARBALL_URL}" --output "${g_cached_go_tarball}"
   135    fi
   136  
   137    g_cached_gitian="${g_gitian_cache}/gitian-builder"
   138    if [ ! -d "${g_cached_gitian}" ]; then
   139    f_echo_stderr "${g_cached_gitian}: cache miss, caching..."
   140      git clone ${GITIAN_REPO} "${g_cached_gitian}"
   141    fi
   142  }
   143  
   144  f_demangle_platforms() {
   145    case "${1}" in
   146    all)
   147      printf '%s' 'darwin linux windows' ;;
   148    linux|darwin|windows)
   149      printf '%s' "${1}" ;;
   150    *)
   151      echo "invalid platform -- ${1}"
   152      exit 1
   153    esac
   154  }
   155  
   156  f_echo_stderr() {
   157    echo $@ >&2
   158  }
   159  
   160  
   161  while getopts ":cs:h" opt; do
   162    case "${opt}" in
   163      h)  f_help ; exit 0 ;;
   164      c)  g_flag_commit=y ;;
   165      s)  g_sign_identity="${OPTARG}" ;;
   166    esac
   167  done
   168  
   169  shift "$((OPTIND-1))"
   170  
   171  g_platforms=$(f_demangle_platforms "${1}")
   172  g_workdir="$(pwd)"
   173  g_commit="$(git rev-parse HEAD)"
   174  g_sigs_dir=${TENDERMINT_SIGS:-"${g_workdir}/${DEFAULT_TENDERMINT_SIGS}"}
   175  
   176  f_ensure_cache
   177  
   178  f_prep_docker_image "${g_cached_gitian}"
   179  
   180  f_prep_build "${g_platforms}"
   181  
   182  export USE_DOCKER=1
   183  for g_os in ${g_platforms}; do
   184    g_release="$(git describe --tags --abbrev=9 | sed 's/^v//')-${g_os}"
   185    g_descriptor="${g_workdir}/scripts/gitian-descriptors/gitian-${g_os}.yml"
   186    [ -f ${g_descriptor} ]
   187    g_builddir="$(f_builddir ${g_os})"
   188  
   189    pushd "${g_builddir}"
   190    f_build "${g_descriptor}"
   191    if [ -n "${g_sign_identity}" ]; then
   192      f_sign_verify "${g_descriptor}"
   193    fi
   194    popd
   195  
   196    if [ -n "${g_sign_identity}" -a -n "${g_flag_commit}" ]; then
   197      [ -d "${g_sigs_dir}/.git/" ] && f_commit_sig ${g_release} || f_echo_stderr "couldn't commit, ${g_sigs_dir} is not a git clone"
   198    fi
   199  done
   200  
   201  exit 0