github.com/sl1pm4t/consul@v1.4.5-0.20190325224627-74c31c540f9c/build-support/functions/30-release.sh (about) 1 function tag_release { 2 # Arguments: 3 # $1 - Path to top level consul source 4 # $2 - Version string to use for tagging the release 5 # $3 - Alternative GPG key id used for signing the release commit (optional) 6 # 7 # Returns: 8 # 0 - success 9 # * - error 10 # 11 # Notes: 12 # If the RELEASE_UNSIGNED environment variable is set then no gpg signing will occur 13 14 if ! test -d "$1" 15 then 16 err "ERROR: '$1' is not a directory. tag_release must be called with the path to the top level source as the first argument'" 17 return 1 18 fi 19 20 if test -z "$2" 21 then 22 err "ERROR: tag_release must be called with a version number as the second argument" 23 return 1 24 fi 25 26 # determine whether the gpg key to use is being overridden 27 local gpg_key=${HASHICORP_GPG_KEY} 28 if test -n "$3" 29 then 30 gpg_key=$3 31 fi 32 33 pushd "$1" > /dev/null 34 local ret=0 35 36 local branch_to_tag=$(git_branch) || ret=1 37 38 # perform an usngined release if requested (mainly for testing locally) 39 if test ${ret} -ne 0 40 then 41 err "ERROR: Failed to determine git branch to tag" 42 elif is_set "$RELEASE_UNSIGNED" 43 then 44 ( 45 git commit --allow-empty -a -m "Release v${2}" && 46 git tag -a -m "Version ${2}" "v${2}" "${branch_to_tag}" 47 ) 48 ret=$? 49 # perform a signed release (official releases should do this) 50 elif have_gpg_key ${gpg_key} 51 then 52 ( 53 git commit --allow-empty -a --gpg-sign=${gpg_key} -m "Release v${2}" && 54 git tag -a -m "Version ${2}" -s -u ${gpg_key} "v${2}" "${branch_to_tag}" 55 ) 56 ret=$? 57 # unsigned release not requested and gpg key isn't useable 58 else 59 err "ERROR: GPG key ${gpg_key} is not in the local keychain - to continue set RELEASE_UNSIGNED=1 in the env" 60 ret=1 61 fi 62 popd > /dev/null 63 return $ret 64 } 65 66 function package_binaries { 67 # Arguments: 68 # $1 - Path to the directory containing the built binaries 69 # $2 - Destination path of the packaged binaries 70 # $3 - Version 71 # 72 # Returns: 73 # 0 - success 74 # * - error 75 76 local sdir="$1" 77 local ddir="$2" 78 local vers="$3" 79 local ret=0 80 81 82 if ! test -d "${sdir}" 83 then 84 err "ERROR: '$1' is not a directory. package_binaries must be called with the path to the directory containing the binaries" 85 return 1 86 fi 87 88 rm -rf "${ddir}" > /dev/null 2>&1 89 mkdir -p "${ddir}" >/dev/null 2>&1 90 for platform in $(find "${sdir}" -mindepth 1 -maxdepth 1 -type d ) 91 do 92 local os_arch=$(basename $platform) 93 local dest="${ddir}/${CONSUL_PKG_NAME}_${vers}_${os_arch}.zip" 94 status "Compressing ${os_arch} directory into ${dest}" 95 pushd "${platform}" > /dev/null 96 zip "${ddir}/${CONSUL_PKG_NAME}_${vers}_${os_arch}.zip" ./* 97 ret=$? 98 popd > /dev/null 99 100 if test "$ret" -ne 0 101 then 102 break 103 fi 104 done 105 106 return ${ret} 107 } 108 109 function package_release_one { 110 # Arguments: 111 # $1 - Path to the top level Consul source 112 # $2 - Version to use in the names of the zip files (optional) 113 # $3 - Subdirectory under pkg/dist to use (optional) 114 # 115 # Returns: 116 # 0 - success 117 # * - error 118 119 if ! test -d "$1" 120 then 121 err "ERROR: '$1' is not a directory. package_release must be called with the path to the top level source as the first argument'" 122 return 1 123 fi 124 125 local sdir="$1" 126 local ret=0 127 local vers="$2" 128 local extra_dir_name="$3" 129 local extra_dir="" 130 131 if test -n "${extra_dir_name}" 132 then 133 extra_dir="${extra_dir_name}/" 134 fi 135 136 if test -z "${vers}" 137 then 138 vers=$(get_version "${sdir}" true false) 139 ret=$? 140 if test "$ret" -ne 0 141 then 142 err "ERROR: failed to determine the version." 143 return $ret 144 fi 145 fi 146 147 package_binaries "${sdir}/pkg/bin/${extra_dir}" "${sdir}/pkg/dist/${extra_dir}" "${vers}" 148 return $? 149 } 150 151 function package_release { 152 # Arguments: 153 # $1 - Path to the top level Consul source 154 # $2 - Version to use in the names of the zip files (optional) 155 # 156 # Returns: 157 # 0 - success 158 # * - error 159 160 package_release_one "$1" "$2" "" 161 return $? 162 } 163 164 function shasum_release { 165 # Arguments: 166 # $1 - Path to the dist directory 167 # $2 - Version of the release 168 # 169 # Returns: 170 # 0 - success 171 # * - failure 172 173 local sdir="$1" 174 local vers="$2" 175 176 if ! test -d "$1" 177 then 178 err "ERROR: sign_release requires a path to the dist dir as the first argument" 179 return 1 180 fi 181 182 if test -z "${vers}" 183 then 184 err "ERROR: sign_release requires a version to be specified as the second argument" 185 return 1 186 fi 187 188 local hfile="${CONSUL_PKG_NAME}_${vers}_SHA256SUMS" 189 190 shasum_directory "${sdir}" "${sdir}/${hfile}" 191 return $? 192 } 193 194 function sign_release { 195 # Arguments: 196 # $1 - Path to distribution directory 197 # $2 - Version 198 # $2 - Alternative GPG key to use for signing 199 # 200 # Returns: 201 # 0 - success 202 # * - failure 203 204 local sdir="$1" 205 local vers="$2" 206 207 if ! test -d "${sdir}" 208 then 209 err "ERROR: sign_release requires a path to the dist dir as the first argument" 210 return 1 211 fi 212 213 if test -z "${vers}" 214 then 215 err "ERROR: sign_release requires a version to be specified as the second argument" 216 return 1 217 fi 218 219 local hfile="${CONSUL_PKG_NAME}_${vers}_SHA256SUMS" 220 221 status_stage "==> Signing ${hfile}" 222 gpg_detach_sign "${1}/${hfile}" "$3" || return 1 223 return 0 224 } 225 226 function check_release_one { 227 # Arguments: 228 # $1 - Path to the release files 229 # $2 - Version to expect 230 # $3 - boolean whether to expect the signature file 231 # $4 - Release Name (optional) 232 # 233 # Returns: 234 # 0 - success 235 # * - failure 236 237 declare -i ret=0 238 239 declare -a expected_files 240 241 declare log_extra="" 242 243 if test -n "$4" 244 then 245 log_extra="for $4 " 246 fi 247 248 expected_files+=("${CONSUL_PKG_NAME}_${2}_SHA256SUMS") 249 echo "check sig: $3" 250 if is_set "$3" 251 then 252 expected_files+=("${CONSUL_PKG_NAME}_${2}_SHA256SUMS.sig") 253 fi 254 255 expected_files+=("${CONSUL_PKG_NAME}_${2}_darwin_386.zip") 256 expected_files+=("${CONSUL_PKG_NAME}_${2}_darwin_amd64.zip") 257 expected_files+=("${CONSUL_PKG_NAME}_${2}_freebsd_386.zip") 258 expected_files+=("${CONSUL_PKG_NAME}_${2}_freebsd_amd64.zip") 259 expected_files+=("${CONSUL_PKG_NAME}_${2}_linux_386.zip") 260 expected_files+=("${CONSUL_PKG_NAME}_${2}_linux_amd64.zip") 261 expected_files+=("${CONSUL_PKG_NAME}_${2}_linux_arm.zip") 262 expected_files+=("${CONSUL_PKG_NAME}_${2}_linux_arm64.zip") 263 expected_files+=("${CONSUL_PKG_NAME}_${2}_solaris_amd64.zip") 264 expected_files+=("${CONSUL_PKG_NAME}_${2}_windows_386.zip") 265 expected_files+=("${CONSUL_PKG_NAME}_${2}_windows_amd64.zip") 266 267 declare -a found_files 268 269 status_stage "==> Verifying release contents ${log_extra}- ${2}" 270 debug "Expecting Files:" 271 for fname in "${expected_files[@]}" 272 do 273 debug " $fname" 274 done 275 276 pushd "$1" > /dev/null 277 for actual_fname in $(ls) 278 do 279 local found=0 280 for i in "${!expected_files[@]}" 281 do 282 local expected_fname="${expected_files[i]}" 283 if test "${expected_fname}" == "${actual_fname}" 284 then 285 # remove from the expected_files array 286 unset 'expected_files[i]' 287 288 # append to the list of found files 289 found_files+=("${expected_fname}") 290 291 # mark it as found so we dont error 292 found=1 293 break 294 fi 295 done 296 297 if test $found -ne 1 298 then 299 err "ERROR: Release build has an extra file: ${actual_fname}" 300 ret=1 301 fi 302 done 303 304 for fname in "${expected_files[@]}" 305 do 306 err "ERROR: Release build is missing a file: $fname" 307 ret=1 308 done 309 310 if test $ret -eq 0 311 then 312 if ! shasum -c -s "${CONSUL_PKG_NAME}_${2}_SHA256SUMS" 313 then 314 err "ERROR: Failed SHA-256 hash verification" 315 shasum -c "${CONSUL_PKG_NAME}_${2}_SHA256SUMS" 316 ret=1 317 fi 318 fi 319 320 if test $ret -eq 0 && is_set "${3}" 321 then 322 if ! gpg --verify "${CONSUL_PKG_NAME}_${2}_SHA256SUMS.sig" "${CONSUL_PKG_NAME}_${2}_SHA256SUMS" > /dev/null 2>&1 323 then 324 err "ERROR: Failed GPG verification of SHA256SUMS signature" 325 ret=1 326 fi 327 fi 328 329 if test $ret -eq 0 330 then 331 status "Release build contents:" 332 for fname in "${found_files[@]}" 333 do 334 echo " $fname" 335 done 336 fi 337 338 popd > /dev/null 339 340 return $ret 341 } 342 343 function check_release { 344 # Arguments: 345 # $1 - Path to the release files 346 # $2 - Version to expect 347 # $3 - boolean whether to expect the signature file 348 # 349 # Returns: 350 # 0 - success 351 # * - failure 352 353 check_release_one "$1" "$2" "$3" 354 return ${ret} 355 } 356 357 358 function build_consul_release { 359 build_consul "$1" "" "$2" 360 } 361 362 function build_release { 363 # Arguments: (yeah there are lots) 364 # $1 - Path to the top level Consul source 365 # $2 - boolean whether to tag the release yet 366 # $3 - boolean whether to build the binaries 367 # $4 - boolean whether to generate the sha256 sums 368 # $5 - version to set within version.go and the changelog 369 # $6 - release date to set within the changelog 370 # $7 - release version to set 371 # $8 - alternative gpg key to use for signing operations (optional) 372 # 373 # Returns: 374 # 0 - success 375 # * - error 376 377 debug "Source Dir: $1" 378 debug "Tag Release: $2" 379 debug "Build Release: $3" 380 debug "Sign Release: $4" 381 debug "Version: $5" 382 debug "Release Date: $6" 383 debug "Release Vers: $7" 384 debug "GPG Key: $8" 385 386 if ! test -d "$1" 387 then 388 err "ERROR: '$1' is not a directory. build_release must be called with the path to the top level source as the first argument'" 389 return 1 390 fi 391 392 if test -z "$2" -o -z "$3" -o -z "$4" 393 then 394 err "ERROR: build_release requires 4 arguments to be specified: <path to consul source> <tag release bool?> <build binaries bool?> <shasum 256 bool?>" 395 return 1 396 fi 397 398 local sdir="$1" 399 local do_tag="$2" 400 local do_build="$3" 401 local do_sha256="$4" 402 local gpg_key="$8" 403 404 if test -z "${gpg_key}" 405 then 406 gpg_key=${HASHICORP_GPG_KEY} 407 fi 408 409 if ! is_set "${RELEASE_UNSIGNED}" 410 then 411 if ! have_gpg_key "${gpg_key}" 412 then 413 err "ERROR: Aborting build because no useable GPG key is present. Set RELEASE_UNSIGNED=1 to bypass this check" 414 return 1 415 fi 416 fi 417 418 if ! is_git_clean "${sdir}" true && ! is_set "${ALLOW_DIRTY_GIT}" 419 then 420 err "ERROR: Refusing to build because Git is dirty. Set ALLOW_DIRTY_GIT=1 in the environment to proceed anyways" 421 return 1 422 fi 423 424 local set_vers="$5" 425 local set_date="$6" 426 local set_release="$7" 427 428 if test -z "${set_vers}" 429 then 430 set_vers=$(get_version "${sdir}" false false) 431 set_release=$(parse_version "${sdir}" true false true) 432 fi 433 434 if is_set "${do_tag}" && ! set_release_mode "${sdir}" "${set_vers}" "${set_date}" "${set_release}" 435 then 436 err "ERROR: Failed to put source into release mode" 437 return 1 438 fi 439 440 local vers="$(get_version ${sdir} true false)" 441 if test $? -ne 0 442 then 443 err "Please specify a version (couldn't find one based on build tags)." 444 return 1 445 fi 446 447 # Make sure we arent in dev mode 448 unset CONSUL_DEV 449 450 if is_set "${do_build}" 451 then 452 status_stage "==> Refreshing Docker Build Images" 453 refresh_docker_images "${sdir}" 454 if test $? -ne 0 455 then 456 err "ERROR: Failed to refresh docker images" 457 return 1 458 fi 459 460 status_stage "==> Building Legacy UI for version ${vers}" 461 build_ui_legacy "${sdir}" "${UI_LEGACY_BUILD_TAG}" 462 if test $? -ne 0 463 then 464 err "ERROR: Failed to build the legacy ui" 465 return 1 466 fi 467 468 status_stage "==> Building UI for version ${vers}" 469 # passing the version to override the version determined via tags 470 build_ui "${sdir}" "${UI_BUILD_TAG}" "${vers}" 471 if test $? -ne 0 472 then 473 err "ERROR: Failed to build the ui" 474 return 1 475 fi 476 status "UI Built with Version: $(ui_version "${sdir}/pkg/web_ui/v2/index.html")" 477 478 status_stage "==> Building Static Assets for version ${vers}" 479 build_assetfs "${sdir}" "${GO_BUILD_TAG}" 480 if test $? -ne 0 481 then 482 err "ERROR: Failed to build the static assets" 483 return 1 484 fi 485 486 if is_set "${do_tag}" 487 then 488 git add "${sdir}/agent/bindata_assetfs.go" 489 if test $? -ne 0 490 then 491 err "ERROR: Failed to git add the assetfs file" 492 return 1 493 fi 494 fi 495 fi 496 497 if is_set "${do_tag}" 498 then 499 status_stage "==> Tagging version ${vers}" 500 tag_release "${sdir}" "${vers}" "${gpg_key}" 501 if test $? -ne 0 502 then 503 err "ERROR: Failed to tag the release" 504 return 1 505 fi 506 507 update_git_env "${sdir}" 508 fi 509 510 if is_set "${do_build}" 511 then 512 status_stage "==> Building Consul for version ${vers}" 513 build_consul_release "${sdir}" "${GO_BUILD_TAG}" 514 if test $? -ne 0 515 then 516 err "ERROR: Failed to build the Consul binaries" 517 return 1 518 fi 519 520 status_stage "==> Packaging up release binaries" 521 package_release "${sdir}" "${vers}" 522 if test $? -ne 0 523 then 524 err "ERROR: Failed to package the release binaries" 525 return 1 526 fi 527 fi 528 529 status_stage "==> Generating SHA 256 Hashes for Binaries" 530 shasum_release "${sdir}/pkg/dist" "${vers}" 531 if test $? -ne 0 532 then 533 err "ERROR: Failed to generate SHA 256 hashes for the release" 534 return 1 535 fi 536 537 if is_set "${do_sha256}" 538 then 539 sign_release "${sdir}/pkg/dist" "${vers}" "${gpg_key}" 540 if test $? -ne 0 541 then 542 err "ERROR: Failed to sign the SHA 256 hashes file" 543 return 1 544 fi 545 fi 546 547 check_release "${sdir}/pkg/dist" "${vers}" "${do_sha256}" 548 return $? 549 }