1#!/bin/bash
2# Copyright 2017 The gRPC Authors
3#
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#
8#     http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
15
16set -eu -o pipefail
17
18if [ $# -ne 2 ]; then
19  cat <<EOF
20Usage: $0 PROFILEID DIR
21  PROFILEID The Sonatype profile to use for staging repository
22            Obtain profile ID from https://oss.sonatype.org:
23             * Build Promotion > Staging Profiles
24             * Select profile based on name (e.g., 'io.grpc')
25             * Copy hex identifier from URL after "#stagingProfiles;"
26  DIR       Directory to upload to Sonatype as a new staging repository
27
28~/.config/sonatype-upload: Configuration file for Sonatype username and password
29  USERNAME=yourusername
30  PASSWORD=yourpass
31
32Sonatype provides a "user token" that is a randomly generated username/password.
33It does allow access to your account, however. You can create one via:
34 * Log in to https://oss.sonatype.org
35 * Click your username at the top right and click to Profile
36 * Change the drop-down from "Summary" to "User Token"
37 * Click "Access User Token"
38EOF
39  exit 1
40fi
41
42PROFILE_ID="$1"
43DIR="$2"
44if [ -z "$DIR" ]; then
45  echo "Must specify non-empty directory name"
46  exit 1
47fi
48
49CONF="$HOME/.config/sonatype-upload"
50[ -f "$CONF" ] && . "$CONF"
51
52USERNAME="${USERNAME:-}"
53PASSWORD="${PASSWORD:-}"
54
55if [ -z "$USERNAME" -o -z "$PASSWORD" ]; then
56  # TODO(ejona86): if people would use it, could prompt for values to avoid
57  # having passwords in plain-text.
58  echo "You must create '$CONF' with keys USERNAME and PASSWORD" >&2
59  exit 1
60fi
61
62STAGING_URL="https://oss.sonatype.org/service/local/staging"
63
64# We go through the effort of using deloyByRepositoryId/ because it is
65# _substantially_ faster to upload files than deploy/maven2/. When using
66# deploy/maven2/ a repository is implicitly created, but the response doesn't
67# provide its name.
68
69USERPASS="$USERNAME:$PASSWORD"
70
71# https://oss.sonatype.org/nexus-staging-plugin/default/docs/index.html
72#
73# Example returned data:
74#   <promoteResponse>
75#     <data>
76#       <stagedRepositoryId>iogrpc-1082</stagedRepositoryId>
77#       <description>Release upload</description>
78#     </data>
79#   </promoteResponse>
80echo "Creating staging repo"
81REPOID="$(
82  XML="
83  <promoteRequest>
84    <data>
85      <description>Release upload</description>
86    </data>
87  </promoteRequest>"
88  curl -s -X POST -d "$XML" -u "$USERPASS" -H "Content-Type: application/xml" \
89    "$STAGING_URL/profiles/$PROFILE_ID/start" |
90  grep stagedRepositoryId |
91  sed 's/.*<stagedRepositoryId>\(.*\)<\/stagedRepositoryId>.*/\1/'
92  )"
93echo "Repository id: $REPOID"
94
95for X in $(cd "$DIR" && find -type f | cut -b 3-); do
96  echo "Uploading $X"
97  curl -T "$DIR/$X" -u "$USERPASS" -H "Content-Type: application/octet-stream" \
98    "$STAGING_URL/deployByRepositoryId/$REPOID/$X"
99done
100
101echo "Closing staging repo"
102XML="
103<promoteRequest>
104  <data>
105    <stagedRepositoryId>$REPOID</stagedRepositoryId>
106    <description>Auto-close via upload script</description>
107  </data>
108</promoteRequest>"
109curl -X POST -d "$XML" -u "$USERPASS" -H "Content-Type: application/xml" \
110  "$STAGING_URL/profiles/$PROFILE_ID/finish"
111