• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/bin/bash
2
3# Copyright 2022 Google LLC
4#
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9#      http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16################################################################################
17
18# Deploys a Maven library.
19#
20# NOTE:
21#   - This must be run from the root of the library workspace.
22
23usage() {
24  cat <<EOF
25Usage: $0 [-dh] [-n jars_name_prefix] [-u github_url] [-c bazel_cache_name]
26          <action (install|snapshot|release)> <library name>
27          <pom file> <version>"
28  -d: Dry run. Only execute idempotent commands (default: false).
29  -n: JARs name prefix. Prefix to apply to JAR names (default: <library name>).
30  -u: GitHub URL. GitHub URL for Javadoc publishing; it is mandatory when
31      <action> is "snaphot" or "release".
32  -c: Bazel cache to use; credentials are expected to be in the file
33      ./cache_key.
34  -h: Help. Print this usage information.
35EOF
36  exit 1
37}
38
39# Arguments to use for all git invocations.
40readonly GIT_ARGS=(
41  -c user.email=noreply@google.com
42  -c user.name="Tink Team"
43)
44
45to_absolute_path() {
46  local -r path="$1"
47  echo "$(cd "$(dirname "${path}")" && pwd)/$(basename "${path}")"
48}
49
50# Options.
51DRY_RUN="false"
52GIT_URL=
53JAR_NAME_PREFIX=
54
55# Positional arguments.
56LIBRARY_NAME=
57POM_FILE=
58ARTIFACT_VERSION=
59
60# Other.
61BAZEL_CMD="bazel"
62MAVEN_ARGS=()
63CACHE_FLAGS=()
64
65parse_args() {
66  # Parse options.
67  while getopts "dhn::u::c:" opt; do
68    case "${opt}" in
69      d) DRY_RUN="true" ;;
70      n) JAR_NAME_PREFIX="${OPTARG}" ;;
71      u) GIT_URL="${OPTARG}" ;;
72      c) CACHE_FLAGS=(
73           "--remote_cache=https://storage.googleapis.com/${OPTARG}"
74           "--google_credentials=$(to_absolute_path ./cache_key)"
75         ) ;;
76      *) usage ;;
77    esac
78  done
79  shift $((OPTIND - 1))
80
81  readonly DRY_RUN
82  readonly JAR_NAME_PREFIX
83  readonly GIT_URL
84  readonly CACHE_FLAGS
85
86  # Parse args.
87  if (( $# < 4 )); then
88    usage
89  fi
90  ACTION="$1"
91  LIBRARY_NAME="$2"
92  POM_FILE="$3"
93  ARTIFACT_VERSION="$4"
94
95  # Make sure the version has the correct format.
96  if [[ ! "${ARTIFACT_VERSION}" =~ (^HEAD$|^[0-9]+\.[0-9]+\.[0-9]$) ]]; then
97    usage
98  fi
99
100  if [[ ! -f "${POM_FILE}" ]]; then
101    echo "ERROR: The POM file doesn't exist: ${POM_FILE}" >&2
102    usage
103  fi
104
105  local -r maven_scripts_dir="$(cd "$(dirname "${POM_FILE}")" && pwd)"
106  case "${ACTION}" in
107    install)
108      MAVEN_ARGS+=( "install:install-file" )
109      ARTIFACT_VERSION="${ARTIFACT_VERSION}-SNAPSHOT"
110      ;;
111    snapshot)
112      if [[ -z "${GIT_URL}" ]]; then
113        usage
114      fi
115      MAVEN_ARGS+=(
116        "deploy:deploy-file"
117        "-DrepositoryId=ossrh"
118        "-Durl=https://oss.sonatype.org/content/repositories/snapshots"
119        "--settings=${maven_scripts_dir}/settings.xml"
120      )
121      ARTIFACT_VERSION="${ARTIFACT_VERSION}-SNAPSHOT"
122      ;;
123    release)
124      if [[ -z "${GIT_URL}" ]]; then
125        usage
126      fi
127      MAVEN_ARGS+=(
128        "gpg:sign-and-deploy-file"
129        "-DrepositoryId=ossrh"
130        "-Durl=https://oss.sonatype.org/service/local/staging/deploy/maven2/"
131        "-Dgpg.keyname=tink-dev@google.com"
132        "--settings=${maven_scripts_dir}/settings.xml"
133      )
134      ;;
135    *)
136      usage
137      ;;
138  esac
139
140  if command -v "bazelisk" &> /dev/null; then
141    BAZEL_CMD="bazelisk"
142  fi
143  readonly BAZEL_CMD
144
145  readonly ACTION
146  readonly LIBRARY_NAME
147  readonly POM_FILE
148  readonly ARTIFACT_VERSION
149  readonly MAVEN_ARGS
150}
151
152do_run_command() {
153  if ! "$@"; then
154    echo "*** Failed executing command. ***"
155    echo "Failed command: $@"
156    exit 1
157  fi
158  return $?
159}
160
161print_command() {
162  printf '%q ' '+' "$@"
163  echo
164}
165
166print_and_do() {
167  print_command "$@"
168  do_run_command "$@"
169  return $?
170}
171
172#######################################
173# Runs a given command if DRY_RUN isn't true.
174# Globals:
175#   DRY_RUN
176# Arguments:
177#   The command to run and its arguments.
178#######################################
179do_run_if_not_dry_run() {
180  print_command "$@"
181  if [[ "${DRY_RUN}" == "true" ]]; then
182    echo "  *** Dry run, command not executed. ***"
183    return 0
184  fi
185  do_run_command "$@"
186  return $?
187}
188
189echo_output_file() {
190  local workspace_dir="$1"
191  local library="$2"
192
193  (
194    cd "${workspace_dir}"
195    local file="bazel-bin/${library}"
196    if [[ ! -e "${file}" ]]; then
197       file="bazel-genfiles/${library}"
198    fi
199    if [[ ! -e "${file}" ]]; then
200      echo "Could not find Bazel output file for ${library}"
201      exit 1
202    fi
203    echo -n "${workspace_dir}/${file}"
204  )
205}
206
207#######################################
208# Pusblishes Javadoc to GitHub pages.
209#
210# Globals:
211#   ACTION
212#   GIT_ARGS
213#   GIT_URL
214#   LIBRARY_NAME
215#   ARTIFACT_VERSION
216# Arguments:
217#   workspace_dir: Workspace directory for the library.
218#   javadoc: Javadoc library name.
219#######################################
220publish_javadoc_to_github_pages() {
221  if [[ "${ACTION}" == "install" ]]; then
222    echo "Local deployment, skipping publishing javadoc to GitHub Pages..."
223    return 0
224  fi
225
226  local workspace_dir="$1"
227  local javadoc="$2"
228
229  local -r javadoc_file="$(echo_output_file "${workspace_dir}" "${javadoc}")"
230
231  print_and_do rm -rf gh-pages
232  print_and_do git "${GIT_ARGS[@]}" clone \
233    --quiet --branch=gh-pages "${GIT_URL}" gh-pages > /dev/null
234  (
235    print_and_do cd gh-pages
236    if [ -d "javadoc/${LIBRARY_NAME}/${ARTIFACT_VERSION}" ]; then
237      print_and_do git "${GIT_ARGS[@]}" rm -rf \
238          "javadoc/${LIBRARY_NAME}/${ARTIFACT_VERSION}"
239    fi
240    print_and_do mkdir -p "javadoc/${LIBRARY_NAME}/${ARTIFACT_VERSION}"
241    print_and_do unzip "${javadoc_file}" \
242      -d "javadoc/${LIBRARY_NAME}/${ARTIFACT_VERSION}"
243    print_and_do rm -rf "javadoc/${LIBRARY_NAME}/${ARTIFACT_VERSION}/META-INF/"
244    print_and_do git "${GIT_ARGS[@]}" add \
245      -f "javadoc/${LIBRARY_NAME}/${ARTIFACT_VERSION}"
246    if [[ "$(git "${GIT_ARGS[@]}" status --porcelain)" ]]; then
247      # Changes exist.
248      do_run_if_not_dry_run \
249        git "${GIT_ARGS[@]}" commit \
250        -m "${LIBRARY_NAME}-${ARTIFACT_VERSION} Javadoc auto-pushed to gh-pages"
251
252      do_run_if_not_dry_run \
253        git "${GIT_ARGS[@]}" push -fq origin gh-pages > /dev/null
254      echo -e "Published Javadoc to gh-pages.\n"
255    else
256      # No changes exist.
257      echo -e "No changes in ${LIBRARY_NAME}-${ARTIFACT_VERSION} Javadoc.\n"
258    fi
259  )
260}
261
262main() {
263  parse_args "$@"
264
265  local -r jars_name_prefix="${JAR_NAME_PREFIX:-${LIBRARY_NAME}}"
266  local -r library="${jars_name_prefix}.jar"
267  local -r src_jar="${jars_name_prefix}-src.jar"
268  local -r javadoc="${jars_name_prefix}-javadoc.jar"
269
270  local -r workspace_dir="$(pwd)"
271
272  print_and_do "${BAZEL_CMD}" build "${CACHE_FLAGS[@]}" "${library}" \
273    "${src_jar}" "${javadoc}"
274
275  local -r library_file="$(echo_output_file "${workspace_dir}" "${library}")"
276  local -r src_jar_file="$(echo_output_file "${workspace_dir}" "${src_jar}")"
277  local -r javadoc_file="$(echo_output_file "${workspace_dir}" "${javadoc}")"
278
279  # Update the version in the POM file.
280  do_run_if_not_dry_run sed -i \
281    's/VERSION_PLACEHOLDER/'"${ARTIFACT_VERSION}"'/' "${POM_FILE}"
282
283  do_run_if_not_dry_run mvn "${MAVEN_ARGS[@]}" -Dfile="${library_file}" \
284    -Dsources="${src_jar_file}" -Djavadoc="${javadoc_file}" \
285    -DpomFile="${POM_FILE}"
286
287  # Add the placeholder back in the POM file.
288  do_run_if_not_dry_run sed -i \
289    's/'"${ARTIFACT_VERSION}"'/VERSION_PLACEHOLDER/' "${POM_FILE}"
290
291  publish_javadoc_to_github_pages "${workspace_dir}" "${javadoc}"
292}
293
294main "$@"
295