...

Text file src/oss.terrastruct.com/d2/ci/release/build.sh

Documentation: oss.terrastruct.com/d2/ci/release

     1#!/bin/sh
     2set -eu
     3if [ ! -e "$(dirname "$0")/../../ci/sub/.git" ]; then
     4  set -x
     5  git submodule update --init
     6  set +x
     7fi
     8. "$(dirname "$0")/../../ci/sub/lib.sh"
     9cd -- "$(dirname "$0")/../.."
    10
    11help() {
    12  cat <<EOF
    13usage: $0 [--rebuild] [--local] [--dry-run] [--run=regex] [--host-only] [--lockfile-force]
    14          [--install] [--uninstall]
    15
    16$0 builds D2 release archives into ./ci/release/build/<version>/d2-<VERSION>-<OS>-<ARCH>.tar.gz
    17
    18The version is detected via git describe which will use the git tag for the current
    19commit if available.
    20
    21Flags:
    22
    23--rebuild
    24  By default build.sh will avoid rebuilding finished assets if they already exist but if you
    25  changed something and need to force rebuild, use this flag.
    26
    27--local
    28  By default build.sh uses \$CI_D2_LINUX_AMD64, \$CI_D2_LINUX_ARM64,
    29  \$CI_D2_MACOS_AMD64 and \$CI_D2_MACOS_ARM64 to build the release
    30  archives. It's required for now due to the following issue:
    31  https://github.com/terrastruct/d2/issues/31
    32  With --local, build.sh will cross compile locally. warning: This is only for testing
    33  purposes, do not use in production!
    34
    35--host-only
    36  Use to build the release archive for the host OS-ARCH only. All logging is done to stderr
    37  so in a script you can read from stdout to get the path to the release archive.
    38
    39--run=regex
    40  Use to run only the OS-ARCH jobs that match the given regex. e.g. --run=linux only runs
    41  the linux jobs. --run=linux-amd64 only runs the linux-amd64 job.
    42
    43--version vX.X.X
    44  Use to overwrite the version detected from git.
    45
    46--lockfile-force
    47  Forcefully take ownership of remote builder lockfiles.
    48
    49--install
    50  Ensure a release using --host-only and install it.
    51
    52--uninstall
    53  Ensure a release using --host-only and uninstall it.
    54
    55--push-docker
    56  Push the built docker image. Unfortunately dockerx requires the multi-arch images be
    57  pushed if required in the same invocation as build. dockerx cannot load multi-arch
    58  images into the daemon for push later. It's not slow though to use --push-docker after
    59  building the image as nearly all artifacts are cached.
    60  Automatically set if called from release.sh
    61
    62--latest-docker
    63  Mark the built image with the latest tag. Automatically set if called from release.sh
    64EOF
    65}
    66
    67main() {
    68  while flag_parse "$@"; do
    69    case "$FLAG" in
    70      h|help)
    71        help
    72        return 0
    73        ;;
    74      rebuild)
    75        flag_noarg && shift "$FLAGSHIFT"
    76        REBUILD=1
    77        ;;
    78      local)
    79        flag_noarg && shift "$FLAGSHIFT"
    80        LOCAL=1
    81        ;;
    82      dry-run)
    83        flag_noarg && shift "$FLAGSHIFT"
    84        DRY_RUN=1
    85        ;;
    86      run)
    87        flag_reqarg && shift "$FLAGSHIFT"
    88        JOBFILTER=$FLAGARG
    89        ;;
    90      host-only)
    91        flag_noarg && shift "$FLAGSHIFT"
    92        HOST_ONLY=1
    93        LOCAL=1
    94        ;;
    95      version)
    96        flag_nonemptyarg && shift "$FLAGSHIFT"
    97        VERSION=$FLAGARG
    98        ;;
    99      lockfile-force)
   100        flag_noarg && shift "$FLAGSHIFT"
   101        LOCKFILE_FORCE=1
   102        ;;
   103      install)
   104        flag_noarg && shift "$FLAGSHIFT"
   105        INSTALL=1
   106        HOST_ONLY=1
   107        LOCAL=1
   108        ;;
   109      uninstall)
   110        flag_noarg && shift "$FLAGSHIFT"
   111        UNINSTALL=1
   112        HOST_ONLY=1
   113        LOCAL=1
   114        ;;
   115      push-docker)
   116        flag_noarg && shift "$FLAGSHIFT"
   117        PUSH_DOCKER=1
   118        ;;
   119      latest-docker)
   120        flag_noarg && shift "$FLAGSHIFT"
   121        LATEST_DOCKER=1
   122        ;;
   123      *)
   124        flag_errusage "unrecognized flag $FLAGRAW"
   125        ;;
   126    esac
   127  done
   128  shift "$FLAGSHIFT"
   129  if [ $# -gt 0 ]; then
   130    flag_errusage "no arguments are accepted"
   131  fi
   132
   133  VERSION=${VERSION:-$(git_describe_ref)}
   134  BUILD_DIR=ci/release/build/$VERSION
   135  sh_c mkdir -p "$BUILD_DIR"
   136  sh_c rm -f ci/release/build/latest
   137  sh_c ln -s "$VERSION" ci/release/build/latest
   138  if [ -n "${HOST_ONLY-}" ]; then
   139    ensure_os
   140    ensure_arch
   141    runjob "$OS/$ARCH" "build"
   142
   143    if [ -n "${INSTALL-}" ]; then
   144      sh_c make -sC "ci/release/build/$VERSION/$OS-$ARCH/d2-$VERSION" install
   145    elif [ -n "${UNINSTALL-}" ]; then
   146      sh_c make -sC "ci/release/build/$VERSION/$OS-$ARCH/d2-$VERSION" uninstall
   147    fi
   148    return 0
   149  fi
   150
   151  runjob linux/amd64 'OS=linux ARCH=amd64 build' &
   152  runjob linux/arm64 'OS=linux ARCH=arm64 build' &
   153  runjob macos/amd64 'OS=macos ARCH=amd64 build' &
   154  runjob macos/arm64 'OS=macos ARCH=arm64 build' &
   155  runjob windows/amd64 'OS=windows ARCH=amd64 build' &
   156  runjob windows/arm64 'OS=windows ARCH=arm64 build' &
   157  waitjobs
   158
   159  runjob linux/docker build_docker &
   160  runjob windows/amd64/msi 'OS=windows ARCH=amd64 build_windows_msi' &
   161  waitjobs
   162}
   163
   164build() {
   165  HW_BUILD_DIR="$BUILD_DIR/$OS-$ARCH/d2-$VERSION"
   166  ARCHIVE="$BUILD_DIR/d2-$VERSION-$OS-$ARCH.tar.gz"
   167
   168  if [ -e "$ARCHIVE" -a -z "${REBUILD-}" ]; then
   169    log "skipping as already built at $ARCHIVE"
   170    return 0
   171  fi
   172
   173  if [ -n "${LOCAL-}" ]; then
   174    build_local
   175    return 0
   176  fi
   177
   178  case $OS in
   179    macos)
   180      case $ARCH in
   181        amd64)
   182          REMOTE_HOST=$CI_D2_MACOS_AMD64 build_remote_macos
   183          ;;
   184        arm64)
   185          REMOTE_HOST=$CI_D2_MACOS_ARM64 build_remote_macos
   186          ;;
   187        *)
   188          warn "no builder for OS=$OS ARCH=$ARCH, building locally..."
   189          build_local
   190          ;;
   191      esac
   192      ;;
   193    linux)
   194      case $ARCH in
   195        amd64)
   196          REMOTE_HOST=$CI_D2_LINUX_AMD64 build_remote_linux
   197          ;;
   198        arm64)
   199          REMOTE_HOST=$CI_D2_LINUX_ARM64 build_remote_linux
   200          ;;
   201        *)
   202          warn "no builder for OS=$OS ARCH=$ARCH, building locally..."
   203          build_local
   204          ;;
   205      esac
   206      ;;
   207    *)
   208      warn "no builder for OS=$OS, building locally..."
   209      build_local
   210      ;;
   211  esac
   212}
   213
   214build_local() {
   215  export DRY_RUN \
   216    HW_BUILD_DIR \
   217    VERSION \
   218    OS \
   219    ARCH \
   220    ARCHIVE
   221  sh_c ./ci/release/_build.sh
   222}
   223
   224build_remote_macos() {(
   225  sh_c lockfile_ssh "$REMOTE_HOST" .d2-build-lock
   226  sh_c gitsync "$REMOTE_HOST" src/d2
   227  sh_c ssh "$REMOTE_HOST" "COLOR=${COLOR-} \
   228TERM=${TERM-} \
   229DRY_RUN=${DRY_RUN-} \
   230HW_BUILD_DIR=$HW_BUILD_DIR \
   231VERSION=$VERSION \
   232OS=$OS \
   233ARCH=$ARCH \
   234ARCHIVE=$ARCHIVE \
   235PATH=\\\"/usr/local/bin:/usr/local/sbin:/opt/homebrew/bin:/opt/homebrew/sbin\\\${PATH+:\\\$PATH}\\\" \
   236./src/d2/ci/release/_build.sh"
   237  sh_c mkdir -p "$HW_BUILD_DIR"
   238  sh_c rsync --archive --human-readable "$REMOTE_HOST:src/d2/$ARCHIVE" "$ARCHIVE"
   239)}
   240
   241build_remote_linux() {(
   242  sh_c lockfile_ssh "$REMOTE_HOST" .d2-build-lock
   243  sh_c gitsync "$REMOTE_HOST" src/d2
   244  sh_c ssh "$REMOTE_HOST" "COLOR=${COLOR-} \
   245TERM=${TERM-} \
   246DRY_RUN=${DRY_RUN-} \
   247HW_BUILD_DIR=$HW_BUILD_DIR \
   248VERSION=$VERSION \
   249OS=$OS \
   250ARCH=$ARCH \
   251ARCHIVE=$ARCHIVE \
   252./src/d2/ci/release/build_in_docker.sh"
   253  sh_c mkdir -p "$HW_BUILD_DIR"
   254  sh_c rsync --archive --human-readable "$REMOTE_HOST:src/d2/$ARCHIVE" "$ARCHIVE"
   255)}
   256
   257build_docker() {
   258  if [ -n "${LOCAL-}" ]; then
   259    sh_c ./ci/release/docker/build.sh \
   260      --version="$VERSION" \
   261      ${PUSH_DOCKER:+--push} \
   262      ${LATEST_DOCKER:+--latest}
   263    return 0
   264  fi
   265
   266  sh_c lockfile_ssh "$CI_D2_LINUX_ARM64" .d2-build-lock
   267  sh_c gitsync "$CI_D2_LINUX_ARM64" src/d2
   268  sh_c rsync --archive --human-readable \
   269    "$BUILD_DIR/d2-$VERSION"-linux-*.tar.gz \
   270    "$CI_D2_LINUX_ARM64:src/d2/$BUILD_DIR/"
   271  sh_c ssh "$CI_D2_LINUX_ARM64" \
   272    "D2_DOCKER_IMAGE=${D2_DOCKER_IMAGE-}" \
   273    "RELEASE=${RELEASE-}" \
   274    ./src/d2/ci/release/docker/build.sh \
   275    --version="$VERSION" \
   276    ${PUSH_DOCKER:+--push} \
   277    ${LATEST_DOCKER:+--latest}
   278}
   279
   280build_windows_msi() {
   281  REMOTE_HOST=$CI_D2_WINDOWS_AMD64
   282
   283  ln -sf "../build/$VERSION/windows-amd64/d2-$VERSION/bin/d2.exe" ./ci/release/windows/d2.exe
   284  sh_c rsync --archive --human-readable --copy-links --delete ./ci/release/windows/ "'$REMOTE_HOST:windows/'"
   285  if ! echo "$VERSION" | grep '[0-9]\.[0-9]\.[0-9]'; then
   286    WIX_VERSION=0.0.0
   287  else
   288    WIX_VERSION=$VERSION
   289  fi
   290  sh_c ssh "$REMOTE_HOST" "'cd ./windows && wix build -arch x64 -d D2Version=$WIX_VERSION ./d2.wxs'"
   291
   292  # --files-from shouldn't be necessary but for some reason selecting d2.msi directly
   293  # makes rsync error with:
   294  # ERROR: rejecting unrequested file-list name: ./windows/d2.msi
   295  # rsync error: requested action not supported (code 4) at flist.c(1027) [Receiver=3.2.7]
   296  rsync_files=$(mktempd)/rsync-files
   297  echo d2.msi >$rsync_files
   298  sh_c rsync --archive --human-readable --files-from "$rsync_files" "'$REMOTE_HOST:windows/'" "./ci/release/build/$VERSION/d2-$VERSION-$OS-$ARCH.msi"
   299}
   300
   301main "$@"

View as plain text