4 # Licensed to the Apache Software Foundation (ASF) under one or more
5 # contributor license agreements. See the NOTICE file distributed with
6 # this work for additional information regarding copyright ownership.
7 # The ASF licenses this file to You under the Apache License, Version 2.0
8 # (the "License"); you may not use this file except in compliance with
9 # the License. You may obtain a copy of the License at
11 # http://www.apache.org/licenses/LICENSE-2.0
13 # Unless required by applicable law or agreed to in writing, software
14 # distributed under the License is distributed on an "AS IS" BASIS,
15 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 # See the License for the specific language governing permissions and
17 # limitations under the License.
19 DRY_RUN
=${DRY_RUN:-1} #default to dry run
20 GPG
="gpg --pinentry-mode loopback --no-tty --batch"
21 # Maven Profiles for publishing snapshots and release to Maven Central and Dist
22 PUBLISH_PROFILES
=("-P" "apache-release,release")
31 function read_config
{
36 read -r -p "$PROMPT [$DEFAULT]: " REPLY
37 local RETVAL
="${REPLY:-$DEFAULT}"
38 if [ -z "$RETVAL" ]; then
39 error
"$PROMPT must be provided."
44 function parse_version
{
45 grep -e '<version>.*</version>' | \
46 head -n 2 |
tail -n 1 | cut
-d'>' -f2 | cut
-d '<' -f1
54 echo "========================"
57 echo "Log file: $LOG_FILE"
59 "$@" 1>"$LOG_FILE" 2>&1
63 echo "Command FAILED. Check full logs for details."
70 function fcreate_secure
{
77 function check_for_tag
{
78 curl
-s --head --fail "$ASF_GITHUB_REPO/releases/tag/$1" > /dev
/null
81 function wait_for_tag
{
82 # Confirm the tag synchronizes to github. This can take a couple minutes,
83 # but usually it just takes a few seconds.
84 local max_propagation_time
=300
86 while ! check_for_tag
"$1"; do
87 if (( max_propagation_time
<= 0 )); then
88 echo "ERROR: Taking more than 5 minutes to propagate Release Tag $1 to github mirror." >&2
89 echo "Please wait and resume other create-release steps when $1 is available in github." >&2
92 echo "Waiting up to $max_propagation_time seconds for tag to propagate to github mirror..."
94 max_propagation_time
=$
((max_propagation_time
- prop_delay
))
98 # API compare version.
99 function get_api_diff_version
{
103 rev=$
(echo "$version" | cut
-d .
-f 3)
104 if [ "$rev" != 0 ]; then
106 short_version
="$(echo "$version" | cut -d . -f 1-2)"
107 api_diff_tag
="rel/${short_version}.$((rev - 1))"
110 major
="$(echo "$version" | cut -d . -f 1)"
111 minor
="$(echo "$version" | cut -d . -f 2)"
112 if [ "$minor" != 0 ]; then
113 api_diff_tag
="rel/${major}.$((minor - 1)).0"
115 api_diff_tag
="rel/$((major - 1)).0.0"
118 api_diff_tag
="$(read_config "api_diff_tag
" "$api_diff_tag")"
122 # Get all branches that begin with 'branch-', the hbase convention for
123 # release branches, sort them and then pop off the most recent.
124 function get_release_info
{
125 PROJECT
="$(read_config "PROJECT
" "$PROJECT")"
128 if [[ -z "${ASF_REPO}" ]]; then
129 ASF_REPO
="https://gitbox.apache.org/repos/asf/${PROJECT}.git"
131 if [[ -z "${ASF_REPO_WEBUI}" ]]; then
132 ASF_REPO_WEBUI
="https://gitbox.apache.org/repos/asf?p=${PROJECT}.git"
134 if [[ -z "${ASF_GITHUB_REPO}" ]]; then
135 ASF_GITHUB_REPO
="https://github.com/apache/${PROJECT}"
137 if [ -z "$GIT_BRANCH" ]; then
138 # If no branch is specified, find out the latest branch from the repo.
139 GIT_BRANCH
="$(git ls-remote --heads "$ASF_REPO" |
140 grep refs/heads/branch- |
147 GIT_BRANCH
="$(read_config "GIT_BRANCH
" "$GIT_BRANCH")"
150 # Find the current version for the branch.
152 version
="$(curl -s "$ASF_REPO_WEBUI;a
=blob_plain
;f
=pom.xml
;hb
=refs
/heads
/$GIT_BRANCH" |
154 echo "Current branch VERSION is $version."
156 NEXT_VERSION
="$version"
158 SHORT_VERSION
="$(echo "$version" | cut -d . -f 1-2)"
159 if [[ ! "$version" =~ .
*-SNAPSHOT ]]; then
160 RELEASE_VERSION
="$version"
162 RELEASE_VERSION
="${version/-SNAPSHOT/}"
166 REV
="$(echo "${RELEASE_VERSION}" | cut -d . -f 3)"
168 # Find out what RC is being prepared.
169 # - If the current version is "x.y.0", then this is RC0 of the "x.y.0" release.
170 # - If not, need to check whether the previous version has been already released or not.
171 # - If it has, then we're building RC0 of the current version.
172 # - If it has not, we're building the next RC of the previous version.
174 if [ "$REV" != 0 ]; then
175 local PREV_REL_REV
=$
((REV
- 1))
176 PREV_REL_TAG
="rel/${SHORT_VERSION}.${PREV_REL_REV}"
177 if check_for_tag
"$PREV_REL_TAG"; then
180 NEXT_VERSION
="${SHORT_VERSION}.${REV}-SNAPSHOT"
182 RELEASE_VERSION
="${SHORT_VERSION}.${PREV_REL_REV}"
183 RC_COUNT
="$(git ls-remote --tags "$ASF_REPO" "${RELEASE_VERSION}RC
*" | wc -l)"
184 # This makes a 'number' of it.
185 RC_COUNT
=$
((RC_COUNT
))
189 NEXT_VERSION
="${SHORT_VERSION}.${REV}-SNAPSHOT"
193 RELEASE_VERSION
="$(read_config "RELEASE_VERSION
" "$RELEASE_VERSION")"
194 NEXT_VERSION
="$(read_config "NEXT_VERSION
" "$NEXT_VERSION")"
195 export RELEASE_VERSION NEXT_VERSION
197 RC_COUNT
="$(read_config "RC_COUNT
" "$RC_COUNT")"
198 RELEASE_TAG
="${RELEASE_VERSION}RC${RC_COUNT}"
199 RELEASE_TAG
="$(read_config "RELEASE_TAG
" "$RELEASE_TAG")"
201 # Check if the RC already exists, and if re-creating the RC, skip tag creation.
203 if check_for_tag
"$RELEASE_TAG"; then
204 read -r -p "$RELEASE_TAG already exists. Continue anyway [y/n]? " ANSWER
205 if [ "$ANSWER" != "y" ]; then
212 export RELEASE_TAG SKIP_TAG
214 GIT_REF
="$RELEASE_TAG"
216 echo "This is a dry run. If tag does not actually exist, please confirm the ref that will be built for testing."
217 GIT_REF
="$(read_config "GIT_REF
" "$GIT_REF")"
221 API_DIFF_TAG
="$(get_api_diff_version "$RELEASE_VERSION")"
223 # Gather some user information.
224 ASF_USERNAME
="$(read_config "ASF_USERNAME
" "$LOGNAME")"
226 GIT_NAME
="$(git config user.name || echo "")"
227 GIT_NAME
="$(read_config "GIT_NAME
" "$GIT_NAME")"
229 GIT_EMAIL
="$ASF_USERNAME@apache.org"
230 GPG_KEY
="$(read_config "GPG_KEY
" "$GIT_EMAIL")"
231 export API_DIFF_TAG ASF_USERNAME GIT_NAME GIT_EMAIL GPG_KEY
236 GIT_BRANCH: $GIT_BRANCH
237 RELEASE_VERSION: $RELEASE_VERSION
238 NEXT_VERSION: $NEXT_VERSION
239 RELEASE_TAG: $RELEASE_TAG $([[ "$GIT_REF" != "$RELEASE_TAG" ]] && printf "\n%s\n" "GIT_REF: $GIT_REF")
240 API_DIFF_TAG: $API_DIFF_TAG
241 ASF_USERNAME: $ASF_USERNAME
244 GIT_EMAIL: $GIT_EMAIL
245 DRY_RUN: $(is_dry_run && echo "yes" || echo "NO, THIS BUILD WILL BE PUBLISHED!")
249 read -r -p "Is this info correct [y/n]? " ANSWER
250 if [ "$ANSWER" != "y" ]; then
255 if ! is_dry_run
; then
256 if [ -z "$ASF_PASSWORD" ]; then
257 stty
-echo && printf "ASF_PASSWORD: " && read -r ASF_PASSWORD
&& printf '\n' && stty
echo
260 ASF_PASSWORD
="***INVALID***"
263 if [ -z "$GPG_PASSPHRASE" ]; then
264 stty
-echo && printf "GPG_PASSPHRASE: " && read -r GPG_PASSPHRASE
&& printf '\n' && stty
echo
270 export GPG_PASSPHRASE
273 function is_dry_run
{
277 function check_get_passwords
{
279 if [ -z "${!env}" ]; then
280 echo "The environment variable $env is not set. Please enter the password or passphrase."
282 # shellcheck disable=SC2229
283 stty
-echo && printf "%s : " "$env" && read -r "$env" && printf '\n' && stty
echo
285 # shellcheck disable=SC2163
290 function check_needed_vars
{
293 if [ -z "${!env}" ]; then
294 echo "$env must be set to run this script"
297 # shellcheck disable=SC2163
301 (( missing
> 0 )) && exit_with_usage
305 function init_locale
{
309 Darwin
*) locale_value
="en_US.UTF-8";;
310 Linux
*) locale_value
="C.UTF-8";;
311 *) error
"unknown OS";;
313 export LC_ALL
="$locale_value"
314 export LANG
="$locale_value"
317 # Initializes JAVA_VERSION to the version of the JVM in use.
319 if [ -z "$JAVA_HOME" ]; then
320 error
"JAVA_HOME is not set."
322 JAVA_VERSION
=$
("${JAVA_HOME}"/bin
/javac
-version 2>&1 | cut
-d " " -f 2)
323 echo "java version: $JAVA_VERSION"
327 function init_python
{
328 if ! [ -x "$(command -v python2)" ]; then
329 error
'python2 needed by yetus. Install or add link? E.g: sudo ln -sf /usr/bin/python2.7 /usr/local/bin/python2'
331 echo "python version: $(python2 --version)"
336 if [ -n "$MAVEN_HOME" ]; then
337 MVN
=("${MAVEN_HOME}/bin/mvn")
338 elif [ "$(type -P mvn)" ]; then
341 error
"MAVEN_HOME is not set nor is mvn on the current path."
346 echo -n "mvn version: "
347 "${MVN[@]}" --version
351 function init_yetus
{
352 declare YETUS_VERSION
353 if [ -z "${YETUS_HOME}" ]; then
354 error
"Missing Apache Yetus."
356 # Work around yetus bug by asking test-patch for the version instead of rdm.
357 YETUS_VERSION
=$
("${YETUS_HOME}/bin/test-patch" --version)
358 echo "Apache Yetus version ${YETUS_VERSION}"
361 function configure_maven
{
362 # Add timestamps to mvn logs.
363 MAVEN_OPTS
="-Dorg.slf4j.simpleLogger.showDateTime=true -Dorg.slf4j.simpleLogger.dateTimeFormat=HH:mm:ss ${MAVEN_OPTS}"
364 # Suppress gobs of "Download from central:" messages
365 MAVEN_OPTS
="-Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn ${MAVEN_OPTS}"
366 MAVEN_LOCAL_REPO
="${REPO:-$(pwd)/$(mktemp -d hbase-repo-XXXXX)}"
367 [[ -d "$MAVEN_LOCAL_REPO" ]] || mkdir
-p "$MAVEN_LOCAL_REPO"
368 MAVEN_SETTINGS_FILE
="${MAVEN_LOCAL_REPO}/tmp-settings.xml"
369 MVN
=("${MVN[@]}" --settings "${MAVEN_SETTINGS_FILE}")
370 export MVN MAVEN_OPTS MAVEN_SETTINGS_FILE MAVEN_LOCAL_REPO
371 export ASF_USERNAME ASF_PASSWORD
372 # reference passwords from env rather than storing in the settings.xml file.
373 cat <<'EOF' > "$MAVEN_SETTINGS_FILE"
374 <?xml version="1.0" encoding="UTF-8"?>
375 <settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
376 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
377 xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd">
378 <localRepository>/${env.MAVEN_LOCAL_REPO}</localRepository>
380 <server><id>apache.snapshots.https</id><username>${env.ASF_USERNAME}</username>
381 <password>${env.ASF_PASSWORD}</password></server>
382 <server><id>apache.releases.https</id><username>${env.ASF_USERNAME}</username>
383 <password>${env.ASF_PASSWORD}</password></server>
384 <server><id>gpg.passphrase</id>
385 <passphrase>${env.GPG_PASSPHRASE}</passphrase></server>
390 <activeByDefault>true</activeByDefault>
393 <gpg.keyname>${env.GPG_KEY}</gpg.keyname>
401 # clone of the repo, deleting anything that exists in the working directory named after the project.
402 # optionally with auth details for pushing.
403 function git_clone_overwrite
{
405 if [ -z "${PROJECT}" ] || [ "${PROJECT}" != "${PROJECT#/}" ]; then
406 error
"Project name must be defined and not start with a '/'. PROJECT='${PROJECT}'"
410 if [[ -z "${GIT_REPO}" ]]; then
411 asf_repo
="gitbox.apache.org/repos/asf/${PROJECT}.git"
412 echo "[INFO] clone will be of the gitbox repo for ${PROJECT}."
413 if [ -n "${ASF_USERNAME}" ] && [ -n "${ASF_PASSWORD}" ]; then
415 encoded_username
=$
(python
-c "import urllib; print urllib.quote('''$ASF_USERNAME''')")
416 encoded_password
=$
(python
-c "import urllib; print urllib.quote('''$ASF_PASSWORD''')")
417 GIT_REPO
="https://$encoded_username:$encoded_password@${asf_repo}"
419 GIT_REPO
="https://${asf_repo}"
422 echo "[INFO] clone will be of provided git repo."
424 # N.B. we use the shared flag because the clone is short lived and if a local repo repo was
425 # given this will let us refer to objects there directly instead of hardlinks or copying.
426 # The option is silently ignored for non-local repositories. see the note on git help clone
427 # for the --shared option for details.
428 git clone
--shared -b "${GIT_BRANCH}" -- "${GIT_REPO}" "${PROJECT}"
429 # If this was a host local git repo then add in an alternates and remote that will
430 # work back on the host if the RM needs to do any post-processing steps, i.e. pushing the git tag
431 # for more info see 'git help remote' and 'git help repository-layout'.
432 if [ -n "$HOST_GIT_REPO" ]; then
433 echo "${HOST_GIT_REPO}/objects" >> "${PROJECT}/.git/objects/info/alternates"
434 (cd "${PROJECT}"; git remote add
host "${HOST_GIT_REPO}")
438 # Writes report into cwd!
439 function generate_api_report
{
441 local previous_tag
="$2"
442 local release_tag
="$3"
443 local previous_version
444 # Generate api report.
445 "${project}"/dev-support
/checkcompatibility.py
--annotation \
446 org.apache.yetus.audience.InterfaceAudience.Public \
447 "$previous_tag" "$release_tag"
448 previous_version
="$(echo "${previous_tag}" | sed -e 's/rel\///')"
449 cp "${project}/target/compat-check/report.html" "./api_compare_${previous_version}_to_${release_tag}.html"
452 # Look up the Jira name associated with project.
453 # Currently all the 'hbase-*' projects share the same HBASE jira name. This works because,
454 # by convention, the HBASE jira "Fix Version" field values have the sub-project name pre-pended,
455 # as in "hbase-operator-tools-1.0.0".
456 # TODO: For non-hbase-related projects, enhance this to use Jira API query instead of text lookup.
457 function get_jira_name
{
461 hbase
*) jira_name
="HBASE";;
464 if [[ -z "$jira_name" ]]; then
465 error
"Sorry, can't determine the Jira name for project $project"
470 # Update the CHANGES.md
471 # DOES NOT DO COMMITS! Caller should do that.
472 # requires yetus to have a defined home already.
473 # yetus requires python2 to be on the path.
474 function update_releasenotes
{
475 local project_dir
="$1"
476 local jira_fix_version
="$2"
478 jira_project
="$(get_jira_name "$
(basename "$project_dir")")"
479 "${YETUS_HOME}/bin/releasedocmaker" -p "${jira_project}" --fileversions -v "${jira_fix_version}" \
480 -l --sortorder=newer
--skip-credits
482 # First clear out the changes written by previous RCs.
483 if [ -f "${project_dir}/CHANGES.md" ]; then
485 "/^## Release ${jira_fix_version}/,/^## Release/ {//!d; /^## Release ${jira_fix_version}/d;}" \
486 "${project_dir}/CHANGES.md" || true
488 if [ -f "${project_dir}/RELEASENODES.md" ]; then
490 "/^# ${jira_project} ${jira_fix_version} Release Notes/,/^# ${jira_project}/{//!d; /^# ${jira_project} ${jira_fix_version} Release Notes/d;}" \
491 "${project_dir}/RELEASENOTES.md" || true
494 # The releasedocmaker call above generates RELEASENOTES.X.X.X.md and CHANGELOG.X.X.X.md.
495 if [ -f "${project_dir}/CHANGES.md" ]; then
496 # To insert into project's CHANGES.md...need to cut the top off the
497 # CHANGELOG.X.X.X.md file removing license and first line and then
498 # insert it after the license comment closing where we have a
499 # DO NOT REMOVE marker text!
500 sed -i -e '/## Release/,$!d' "CHANGELOG.${jira_fix_version}.md"
501 sed -i -e "/DO NOT REMOVE/r CHANGELOG.${jira_fix_version}.md" "${project_dir}/CHANGES.md"
503 mv "CHANGELOG.${jira_fix_version}.md" "${project_dir}/CHANGES.md"
505 if [ -f "${project_dir}/RELEASENOTES.md" ]; then
506 # Similar for RELEASENOTES but slightly different.
507 sed -i -e '/Release Notes/,$!d' "RELEASENOTES.${jira_fix_version}.md"
508 sed -i -e "/DO NOT REMOVE/r RELEASENOTES.${jira_fix_version}.md" \
509 "${project_dir}/RELEASENOTES.md"
511 mv "RELEASENOTES.${jira_fix_version}.md" "${project_dir}/RELEASENOTES.md"
516 # Takes as arguments first the project name -- e.g. hbase or hbase-operator-tools
517 # -- and then the version string. Expects to find checkout adjacent to this script
518 # named for 'project', the first arg passed.
519 # Expects the following three defines in the environment:
520 # - GPG needs to be defined, with the path to GPG: defaults 'gpg'.
521 # - The passphrase in the GPG_PASSPHRASE variable: no default (we don't make .asc file).
522 # - GIT_REF which is the tag to create the tgz from: defaults to 'master'.
524 # $ GPG_PASSPHRASE="XYZ" GIT_REF="master" make_src_release hbase-operator-tools 1.0.0
526 # Tar up the src and sign and hash it.
529 local base_name
="${project}-${version}"
530 rm -rf "${base_name}"-src*
531 tgz
="${base_name}-src.tar.gz"
532 cd "${project}" ||
exit
534 git archive
--format=tar.gz
--output="../${tgz}" --prefix="${base_name}/" "${GIT_REF:-master}"
536 echo "$GPG_PASSPHRASE" |
$GPG --passphrase-fd 0 --armour --output "${tgz}.asc" \
537 --detach-sig "${tgz}"
538 echo "$GPG_PASSPHRASE" |
$GPG --passphrase-fd 0 --print-md SHA512
"${tgz}" > "${tgz}.sha512"
541 # Make binary release.
542 # Takes as arguments first the project name -- e.g. hbase or hbase-operator-tools
543 # -- and then the version string. Expects to find checkout adjacent to this script
544 # named for 'project', the first arg passed.
545 # Expects the following three defines in the environment:
546 # - GPG needs to be defined, with the path to GPG: defaults 'gpg'.
547 # - The passphrase in the GPG_PASSPHRASE variable: no default (we don't make .asc file).
548 # - GIT_REF which is the tag to create the tgz from: defaults to 'master'.
549 # - MVN Default is "mvn -B --settings $MAVEN_SETTINGS_FILE".
551 # $ GPG_PASSPHRASE="XYZ" GIT_REF="master" make_src_release hbase-operator-tools 1.0.0
552 make_binary_release
() {
555 local base_name
="${project}-${version}"
556 rm -rf "${base_name}"-bin*
557 cd "$project" ||
exit
560 # Three invocations of maven. This seems to work. One to
561 # populate the repo, another to build the site, and then
562 # a third to assemble the binary artifact. Trying to do
563 # all in the one invocation fails; a problem in our
564 # assembly spec to in maven. TODO. Meantime, three invocations.
565 "${MVN[@]}" clean
install -DskipTests
566 "${MVN[@]}" site
-DskipTests
568 "${MVN[@]}" install assembly
:single
-DskipTests -Dcheckstyle.skip
=true
"${PUBLISH_PROFILES[@]}"
570 # Check there is a bin gz output. The build may not produce one: e.g. hbase-thirdparty.
571 local f_bin_prefix
="./${PROJECT}-assembly/target/${base_name}"
572 if ls "${f_bin_prefix}"*-bin.
tar.gz
&>/dev
/null
; then
573 cp "${f_bin_prefix}"*-bin.
tar.gz ..
575 for i
in "${base_name}"*-bin.
tar.gz
; do
576 echo "$GPG_PASSPHRASE" |
$GPG --passphrase-fd 0 --armour --output "$i.asc" --detach-sig "$i"
577 echo "$GPG_PASSPHRASE" |
$GPG --passphrase-fd 0 --print-md SHA512
"${i}" > "$i.sha512"
581 echo "No ${f_bin_prefix}*-bin.tar.gz product; expected?"
585 # "Wake up" the gpg agent so it responds properly to maven-gpg-plugin, and doesn't cause timeout.
586 # Specifically this is done between invocation of 'mvn site' and 'mvn assembly:single', because
587 # the 'site' build takes long enough that the gpg-agent does become unresponsive and the following
588 # 'assembly' build (where gpg signing occurs) experiences timeout, without this "kick".
589 function kick_gpg_agent
{
590 # All that's needed is to run gpg on a random file
593 echo "This is a test file" > "$i"
594 echo "$GPG_PASSPHRASE" |
$GPG --passphrase-fd 0 --armour --output "$i.asc" --detach-sig "$i"
598 # Do maven command to set version into local pom
599 function maven_set_version
{ #input: <version_to_set>
600 local this_version
="$1"
601 echo "${MVN[@]}" versions
:set -DnewVersion="$this_version"
602 "${MVN[@]}" versions
:set -DnewVersion="$this_version" |
grep -v "no value" # silence logs
605 # Do maven command to read version from local pom
606 function maven_get_version
{
607 # shellcheck disable=SC2016
608 "${MVN[@]}" -q -N -Dexec.executable
="echo" -Dexec.args
='${project.version}' exec:exec
611 # Do maven deploy to snapshot or release artifact repository, with checks.
612 function maven_deploy
{ #inputs: <snapshot|release> <log_file_path>
613 # Invoke with cwd=$PROJECT
614 local deploy_type
="$1"
615 local mvn_log_file
="$2" #secondary log file used later to extract staged_repo_id
616 if [[ "$deploy_type" != "snapshot" && "$deploy_type" != "release" ]]; then
617 error
"unrecognized deploy type, must be 'snapshot'|'release'"
619 if [[ -z "$mvn_log_file" ]] ||
! touch "$mvn_log_file"; then
620 error
"must provide writable maven log output filepath"
622 # shellcheck disable=SC2153
623 if [[ "$deploy_type" == "snapshot" ]] && ! [[ "$RELEASE_VERSION" =~
-SNAPSHOT$
]]; then
624 error
"Snapshots must have a version with suffix '-SNAPSHOT'; you gave version '$RELEASE_VERSION'"
625 elif [[ "$deploy_type" == "release" ]] && [[ "$RELEASE_VERSION" =~ SNAPSHOT
]]; then
626 error
"Non-snapshot release version must not include the word 'SNAPSHOT'; you gave version '$RELEASE_VERSION'"
628 # Publish ${PROJECT} to Maven repo
629 # shellcheck disable=SC2154
630 echo "Publishing ${PROJECT} checkout at '$GIT_REF' ($git_hash)"
631 echo "Publish version is $RELEASE_VERSION"
632 # Coerce the requested version
633 maven_set_version
"$RELEASE_VERSION"
634 # Prepare for signing
636 declare -a mvn_goals
=(clean
install)
637 if ! is_dry_run
; then
638 mvn_goals
=("${mvn_goals[@]}" deploy
)
640 echo "${MVN[@]}" -DskipTests -Dcheckstyle.skip
=true
"${PUBLISH_PROFILES[@]}" \
642 echo "Logging to ${mvn_log_file}. This will take a while..."
643 rm -f "$mvn_log_file"
644 # The tortuous redirect in the next command allows mvn's stdout and stderr to go to mvn_log_file,
645 # while also sending stderr back to the caller.
646 # shellcheck disable=SC2094
647 if ! "${MVN[@]}" -DskipTests -Dcheckstyle.skip
=true
"${PUBLISH_PROFILES[@]}" \
648 "${mvn_goals[@]}" 1>> "$mvn_log_file" 2> >( tee -a "$mvn_log_file" >&2 ); then
649 error
"Deploy build failed, for details see log at '$mvn_log_file'."
651 echo "BUILD SUCCESS."
658 function get_host_os
() {
659 uname
-s |
tr '[:lower:]' '[:upper:]'