blob: a72f905dded915b49084af47fa210f0d4f6a0148 [file] [log] [blame]
#!/bin/bash
# Copyright 2022 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
################################################################################
# Deploys a Maven library.
#
# NOTE:
# - This must be run from the root of the library workspace.
usage() {
echo "Usage: $0 [-dh] [-n jars_name_prefix] [-u github_url] \\"
echo " <action (install|snapshot|release)> <library name> \\"
echo " <pom file> <version>"
echo " -d: Dry run. Only execute idempotent commands (default: false)."
echo " -h: Help. Print this usage information."
echo " -n: JARs name prefix. Prefix to apply to JAR names (default: "
echo " <library name>)."
echo " -u: GitHub URL. GitHub URL for Javadoc publishing; it is mandatory"
echo " when <action> is \"snaphot\" or \"release\"."
exit 1
}
# Arguments to use for all git invocations.
readonly GIT_ARGS=(
-c user.email=noreply@google.com
-c user.name="Tink Team"
)
# Options.
DRY_RUN="false"
GIT_URL=
JAR_NAME_PREFIX=
# Positional arguments.
LIBRARY_NAME=
POM_FILE=
ARTIFACT_VERSION=
# Other.
BAZEL_CMD="bazel"
MAVEN_ARGS=()
parse_args() {
# Parse options.
while getopts "dhn::u::" opt; do
case "${opt}" in
d) DRY_RUN="true" ;;
n) JAR_NAME_PREFIX="${OPTARG}" ;;
u) GIT_URL="${OPTARG}" ;;
*) usage ;;
esac
done
shift $((OPTIND - 1))
readonly DRY_RUN
readonly JAR_NAME_PREFIX
readonly GIT_URL
# Parse args.
if (( $# < 4 )); then
usage
fi
ACTION="$1"
LIBRARY_NAME="$2"
POM_FILE="$3"
ARTIFACT_VERSION="$4"
# Make sure the version has the correct format.
if [[ ! "${ARTIFACT_VERSION}" =~ (^HEAD$|^[0-9]+\.[0-9]+\.[0-9]$) ]]; then
usage
fi
if [[ ! -f "${POM_FILE}" ]]; then
echo "ERROR: The POM file doesn't exist: ${POM_FILE}" >&2
usage
fi
local -r maven_scripts_dir="$(cd "$(dirname "${POM_FILE}")" && pwd)"
case "${ACTION}" in
install)
MAVEN_ARGS+=( "install:install-file" )
ARTIFACT_VERSION="${ARTIFACT_VERSION}-SNAPSHOT"
;;
snapshot)
if [[ -z "${GIT_URL}" ]]; then
usage
fi
MAVEN_ARGS+=(
"deploy:deploy-file"
"-DrepositoryId=ossrh"
"-Durl=https://oss.sonatype.org/content/repositories/snapshots"
"--settings=${maven_scripts_dir}/settings.xml"
)
ARTIFACT_VERSION="${ARTIFACT_VERSION}-SNAPSHOT"
;;
release)
if [[ -z "${GIT_URL}" ]]; then
usage
fi
MAVEN_ARGS+=(
"gpg:sign-and-deploy-file"
"-DrepositoryId=ossrh"
"-Durl=https://oss.sonatype.org/service/local/staging/deploy/maven2/"
"-Dgpg.keyname=tink-dev@google.com"
"--settings=${maven_scripts_dir}/settings.xml"
)
;;
*)
usage
;;
esac
if command -v "bazelisk" &> /dev/null; then
BAZEL_CMD="bazelisk"
fi
readonly BAZEL_CMD
readonly ACTION
readonly LIBRARY_NAME
readonly POM_FILE
readonly ARTIFACT_VERSION
readonly MAVEN_ARGS
}
do_run_command() {
if ! "$@"; then
echo "*** Failed executing command. ***"
echo "Failed command: $@"
exit 1
fi
return $?
}
print_command() {
printf '%q ' '+' "$@"
echo
}
print_and_do() {
print_command "$@"
do_run_command "$@"
return $?
}
#######################################
# Runs a given command if DRY_RUN isn't true.
# Globals:
# DRY_RUN
# Arguments:
# The command to run and its arguments.
#######################################
do_run_if_not_dry_run() {
print_command "$@"
if [[ "${DRY_RUN}" == "true" ]]; then
echo " *** Dry run, command not executed. ***"
return 0
fi
do_run_command "$@"
return $?
}
echo_output_file() {
local workspace_dir="$1"
local library="$2"
(
cd "${workspace_dir}"
local file="bazel-bin/${library}"
if [[ ! -e "${file}" ]]; then
file="bazel-genfiles/${library}"
fi
if [[ ! -e "${file}" ]]; then
echo "Could not find Bazel output file for ${library}"
exit 1
fi
echo -n "${workspace_dir}/${file}"
)
}
#######################################
# Pusblishes Javadoc to GitHub pages.
#
# Globals:
# ACTION
# GIT_ARGS
# GIT_URL
# LIBRARY_NAME
# ARTIFACT_VERSION
# Arguments:
# workspace_dir: Workspace directory for the library.
# javadoc: Javadoc library name.
#######################################
publish_javadoc_to_github_pages() {
if [[ "${ACTION}" == "install" ]]; then
echo "Local deployment, skipping publishing javadoc to GitHub Pages..."
return 0
fi
local workspace_dir="$1"
local javadoc="$2"
local -r javadoc_file="$(echo_output_file "${workspace_dir}" "${javadoc}")"
print_and_do rm -rf gh-pages
print_and_do git "${GIT_ARGS[@]}" clone \
--quiet --branch=gh-pages "${GIT_URL}" gh-pages > /dev/null
(
print_and_do cd gh-pages
if [ -d "javadoc/${LIBRARY_NAME}/${ARTIFACT_VERSION}" ]; then
print_and_do git "${GIT_ARGS[@]}" rm -rf \
"javadoc/${LIBRARY_NAME}/${ARTIFACT_VERSION}"
fi
print_and_do mkdir -p "javadoc/${LIBRARY_NAME}/${ARTIFACT_VERSION}"
print_and_do unzip "${javadoc_file}" \
-d "javadoc/${LIBRARY_NAME}/${ARTIFACT_VERSION}"
print_and_do rm -rf "javadoc/${LIBRARY_NAME}/${ARTIFACT_VERSION}/META-INF/"
print_and_do git "${GIT_ARGS[@]}" add \
-f "javadoc/${LIBRARY_NAME}/${ARTIFACT_VERSION}"
if [[ "$(git "${GIT_ARGS[@]}" status --porcelain)" ]]; then
# Changes exist.
do_run_if_not_dry_run \
git "${GIT_ARGS[@]}" commit \
-m "${LIBRARY_NAME}-${ARTIFACT_VERSION} Javadoc auto-pushed to gh-pages"
do_run_if_not_dry_run \
git "${GIT_ARGS[@]}" push -fq origin gh-pages > /dev/null
echo -e "Published Javadoc to gh-pages.\n"
else
# No changes exist.
echo -e "No changes in ${LIBRARY_NAME}-${ARTIFACT_VERSION} Javadoc.\n"
fi
)
}
main() {
parse_args "$@"
local -r jars_name_prefix="${JAR_NAME_PREFIX:-${LIBRARY_NAME}}"
local -r library="${jars_name_prefix}.jar"
local -r src_jar="${jars_name_prefix}-src.jar"
local -r javadoc="${jars_name_prefix}-javadoc.jar"
local -r workspace_dir="$(pwd)"
print_and_do "${BAZEL_CMD}" build "${library}" "${src_jar}" "${javadoc}"
local -r library_file="$(echo_output_file "${workspace_dir}" "${library}")"
local -r src_jar_file="$(echo_output_file "${workspace_dir}" "${src_jar}")"
local -r javadoc_file="$(echo_output_file "${workspace_dir}" "${javadoc}")"
# Update the version in the POM file.
do_run_if_not_dry_run sed -i \
's/VERSION_PLACEHOLDER/'"${ARTIFACT_VERSION}"'/' "${POM_FILE}"
do_run_if_not_dry_run mvn "${MAVEN_ARGS[@]}" -Dfile="${library_file}" \
-Dsources="${src_jar_file}" -Djavadoc="${javadoc_file}" \
-DpomFile="${POM_FILE}"
# Add the placeholder back in the POM file.
do_run_if_not_dry_run sed -i \
's/'"${ARTIFACT_VERSION}"'/VERSION_PLACEHOLDER/' "${POM_FILE}"
publish_javadoc_to_github_pages "${workspace_dir}" "${javadoc}"
}
main "$@"