incr.sh 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. #!/bin/bash
  2. ##############################################################################
  3. #
  4. # HPCC SYSTEMS software Copyright (C) 2020 HPCC Systems®.
  5. #
  6. # Licensed under the Apache License, Version 2.0 (the "License");
  7. # you may not use this file except in compliance with the License.
  8. # You may obtain a copy of the License at
  9. #
  10. # http://www.apache.org/licenses/LICENSE-2.0
  11. #
  12. # Unless required by applicable law or agreed to in writing, software
  13. # distributed under the License is distributed on an "AS IS" BASIS,
  14. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15. # See the License for the specific language governing permissions and
  16. # limitations under the License.
  17. ##############################################################################
  18. # Use this script to build local images for testing, while leveraging the work already done in the most recent tag
  19. # on the branch that your local branch was based on
  20. #
  21. # Pass in a get commit (that you previously built using this script) if you want to override the default calculation
  22. # of the base build
  23. # NB: INPUT_* may be pre-set as environment variables.
  24. while getopts “d:fhlpt:u:b:” opt; do
  25. case $opt in
  26. l) TAGLATEST=1 ;;
  27. p) PUSH=1 ;;
  28. t) INPUT_BUILD_THREADS=$OPTARG ;;
  29. d) INPUT_DOCKER_REPO=$OPTARG ;;
  30. u) INPUT_BUILD_USER=$OPTARG ;;
  31. b) INPUT_BUILD_TYPE=$OPTARG ;;
  32. f) FORCE=1 ;;
  33. h) echo "Usage: incr.sh [options]"
  34. echo " -d <docker-repo> Specify the repo to publish images to"
  35. echo " -f Force build from scratch"
  36. echo " -b Build type (e.g. Debug / Release)"
  37. echo " -h Display help"
  38. echo " -l Tag the images as the latest"
  39. echo " -p Push images to docker repo"
  40. echo " -t <num-threads> Override the number of build threads"
  41. echo " -u <user> Specify the build user"
  42. exit
  43. ;;
  44. esac
  45. done
  46. shift $(( $OPTIND-1 ))
  47. set -e
  48. # NB: Not used if FORCE build
  49. PREV=$1
  50. DOCKER_REPO=hpccsystems
  51. [[ -n ${INPUT_DOCKER_REPO} ]] && DOCKER_REPO=${INPUT_DOCKER_REPO}
  52. INCR_DOCKER_REPO=${DOCKER_REPO}
  53. BUILD_TYPE=Debug
  54. [[ -n ${INPUT_BUILD_TYPE} ]] && BUILD_TYPE=${INPUT_BUILD_TYPE}
  55. BUILD_THREADS=$INPUT_BUILD_THREADS # If not set, picks up default based on nproc
  56. # BUILD_USER used when building from scatch with force option (-f)
  57. BUILD_USER=hpccsystems
  58. [[ -n ${INPUT_BUILD_USER} ]] && BUILD_USER=${INPUT_BUILD_USER}
  59. HEAD=$(git rev-parse --short HEAD)
  60. BUILD_LABEL="${HEAD}-${BUILD_TYPE}"
  61. if [[ -z "$FORCE" ]] ; then
  62. # Look for an image that matches a commit, exclude images based on dirty working tree.
  63. if [[ -z ${PREV} ]] ; then
  64. docker images ${DOCKER_REPO}/platform-build --format {{.Tag}} | egrep -ve '-dirty.*$' > .candidate-tags || true
  65. PREV=$(git log --format=format:%h-${BUILD_TYPE} $(git describe --abbrev=0 --tags)..HEAD | fgrep -f .candidate-tags | head -n 1)
  66. rm -f .candidate-tags
  67. PREV_COMMIT=$(echo "${PREV}" | sed -e "s/-${BUILD_TYPE}.*$//")
  68. fi
  69. # If not found above, look for latest tagged
  70. if [[ -z ${PREV} ]] ; then
  71. PREV=$(git log --oneline --no-merges | grep "^[0-9a-f]* Split off " | head -1 | sed "s/.*Split off //" | head -1)-rc1
  72. if [[ ! "${BUILD_TYPE}" =~ "Release" ]] ; then
  73. PREV=${PREV}-${BUILD_TYPE}
  74. fi
  75. echo Finding image based on most recent git tag: ${PREV}
  76. INCR_DOCKER_REPO=hpccsystems
  77. docker pull ${INCR_DOCKER_REPO}/platform-build:${PREV}
  78. if [ $? -ne 0 ]; then
  79. echo "Could not locate docker image based on PREV tag: ${PREV} for docker user: ${DOCKER_REPO}"
  80. exit
  81. fi
  82. fi
  83. if [[ -z ${PREV_COMMIT} ]] ; then
  84. PREV_COMMIT=community_$(echo "${PREV}" | sed -e "s/-${BUILD_TYPE}.*$//")
  85. fi
  86. # create empty patch file
  87. echo -n > platform-build-incremental/hpcc.gitpatch
  88. porcelain=$(git status -uno --porcelain)
  89. if [[ -n "${porcelain}" || "${HEAD}" != "${PREV_COMMIT}" ]] ; then
  90. echo "git diff --binary ${PREV_COMMIT} ':!./' > platform-build-incremental/hpcc.gitpatch"
  91. git diff --binary ${PREV_COMMIT} ':!./' > platform-build-incremental/hpcc.gitpatch
  92. # PATCH_MD5 is an ARG of the docker file, which ensures that if different from cached version, image will rebuild from that stage
  93. PATCH_MD5=$(md5sum platform-build-incremental/hpcc.gitpatch | awk '{print $1}')
  94. if [[ -n "${porcelain}" ]] ; then
  95. DIRTY="-dirty-${PATCH_MD5}"
  96. fi
  97. # If working tree is dirty, annotate build tag, so doesn't conflict with base commit
  98. BUILD_LABEL="${BUILD_LABEL}${DIRTY}"
  99. elif [[ "$BUILD_LABEL" == "$PREV" ]] ; then
  100. echo Checking if docker image ${DOCKER_REPO}/platform-core:${BUILD_LABEL} already exists
  101. EXISTING_IMAGE_LABEL=$(git log --format=format:%h-${BUILD_TYPE} $(git describe --abbrev=0 --tags)..HEAD | grep `docker images ${DOCKER_REPO}/platform-build --format {{.Tag}} | head -n 2 | tail -n 1`)
  102. if [[ -n ${EXISTING_IMAGE_LABEL} ]] ; then
  103. PREV=${EXISTING_IMAGE_LABEL}
  104. PREV_COMMIT=$(echo "${PREV}" | sed -e "s/-${BUILD_TYPE}//")
  105. fi
  106. fi
  107. fi
  108. set -e
  109. DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
  110. pushd $DIR 2>&1 > /dev/null
  111. build_image() {
  112. local name=$1
  113. local dockerfolder=$2
  114. # if 2nd arg. present, it names the docker folder, otherwise same as $name
  115. [[ -z ${dockerfolder} ]] && dockerfolder=$name
  116. local label=$BUILD_LABEL
  117. if ! docker pull ${DOCKER_REPO}/${name}:${label} ; then
  118. docker image build -t ${DOCKER_REPO}/${name}:${label} \
  119. --build-arg DOCKER_REPO=${DOCKER_REPO} \
  120. --build-arg BUILD_LABEL=${BUILD_LABEL} \
  121. --build-arg BUILD_TYPE=${BUILD_TYPE} ${@:3} \
  122. ${dockerfolder}/
  123. fi
  124. if [ "$TAGLATEST" = "1" ] ; then
  125. docker tag ${DOCKER_REPO}/${name}:${label} ${DOCKER_REPO}/${name}:latest
  126. if [ "$PUSH" = "1" ] ; then
  127. docker push ${DOCKER_REPO}/${name}:${label}
  128. docker push ${DOCKER_REPO}/${name}:latest
  129. fi
  130. else
  131. if [ "$PUSH" = "1" ] ; then
  132. docker push ${DOCKER_REPO}/${name}:${label}
  133. fi
  134. fi
  135. }
  136. if [[ -n "$FORCE" ]] ; then
  137. echo Building local forced build images [ BUILD_LABEL=${BUILD_LABEL} ]
  138. build_image platform-build platform-build --build-arg BUILD_USER=${BUILD_USER} --build-arg BUILD_TAG=${HEAD} --build-arg BUILD_THREADS=${BUILD_THREADS}
  139. else
  140. echo Building local incremental images [ BUILD_LABEL=${BUILD_LABEL} ] based on ${PREV}
  141. build_image platform-build platform-build-incremental --build-arg DOCKER_REPO=${INCR_DOCKER_REPO} --build-arg PREV_LABEL=${PREV} --build-arg PATCH_MD5=${PATCH_MD5} --build-arg BUILD_THREADS=${BUILD_THREADS}
  142. # rm platform-build-incremental/hpcc.gitpatch
  143. fi
  144. if [[ "${BUILD_TYPE}" =~ "Release" ]] ; then
  145. echo BUILDING: build_image platform-core
  146. build_image platform-core
  147. else
  148. echo BUILDING: build_image platform-core platform-core-debug
  149. build_image platform-core platform-core-debug
  150. fi
  151. echo Built ${DOCKER_REPO}/*:${BUILD_LABEL}