Repository: firebase/firebase-admin-java
Pull request #130 (2018-01-24 19:41:26)

Release preparation script
* Updates the master branch
* Creates a new release branch
* Updates and commits the CHANGELOG.md file
* Run Maven preparation goals


Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 8757ec6..109c30b 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,10 @@
 # Unreleased
-- 
+
+### Initialization
+
+- [fixed] The [`FirebaseOptions.Builder.setStorageBucket()`](https://firebase.google.com/docs/reference/admin/java/reference/com/google/firebase/FirebaseOptions.Builder.html#setStorageBucket(java.lang.String))
+  method now throws a clear exception when invoked with a bucket URL
+  instead of the name.
 
 # v5.8.0
 
diff --git a/prepare_release.sh b/prepare_release.sh
new file mode 100755
index 0000000..47a7f4e
--- /dev/null
+++ b/prepare_release.sh
@@ -0,0 +1,98 @@
+# Copyright 2018 Google Inc.
+#
+# 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.
+
+#!/bin/bash
+
+function parseVersion {
+    if [[ ! "$1" =~ ^([0-9]*)\.([0-9]*)\.([0-9]*)$ ]]; then
+        return 1
+    fi
+    return 0
+}
+
+set -e
+
+if [ -z "$1" ]; then
+    echo "[ERROR] No version number provided."
+    echo "[INFO] Usage: ./prepare_release.sh <VERSION_NUMBER>"
+    exit 1
+fi
+
+
+#############################
+#  VALIDATE VERSION NUMBER  #
+#############################
+
+VERSION="$1"
+if ! parseVersion "$VERSION"; then
+    echo "[ERROR] Illegal version number provided. Version number must match semver."
+    exit 1
+fi
+
+
+#############################
+#  VALIDATE TEST RESOURCES  #
+#############################
+
+if [[ ! -e "integration_cert.json" ]]; then
+    echo "[ERROR] integration_cert.json file is required to run integration tests."
+    exit 1
+fi
+
+if [[ ! -e "integration_apikey.txt" ]]; then
+    echo "[ERROR] integration_apikey.txt file is required to run integration tests."
+    exit 1
+fi
+
+
+###############
+#  INIT REPO  #
+###############
+
+# Ensure the current branch does not have local changes
+if [[ $(git status --porcelain) ]]; then
+    echo "[ERROR] Local changes exist in the current branch. Cannot proceed."
+    #exit 1
+fi
+
+echo "[INFO] Updating the master branch"
+git checkout master
+git pull origin master
+
+TIMESTAMP=$(date +%s)
+RELEASE_BRANCH="release-${TIMESTAMP}"
+echo "[INFO] Creating new release branch: ${RELEASE_BRANCH}"
+git checkout -b ${RELEASE_BRANCH} master
+
+HOST=$(uname)
+echo "[INFO] Updating CHANGELOG.md"
+if [ $HOST == "Darwin" ]; then
+    sed -i "" -e "1 s/# Unreleased//" "CHANGELOG.md"
+else
+    sed -i -e "1 s/# Unreleased//" "CHANGELOG.md"
+fi
+
+echo -e "# Unreleased\n\n-\n\n# v${VERSION}" | cat - CHANGELOG.md > TEMP_CHANGELOG.md
+mv TEMP_CHANGELOG.md CHANGELOG.md
+git add CHANGELOG.md
+git commit -m "Updating CHANGELOG for ${VERSION} release."
+git push origin ${RELEASE_BRANCH}
+
+
+#################################
+#  RUN MAVEN PREPARATION STEPS  #
+#################################
+mvn clean
+mvn release:clean
+mvn release:prepare -DreleaseVersion=${VERSION} -Dtag=v${VERSION}
diff --git a/src/main/java/com/google/firebase/FirebaseOptions.java b/src/main/java/com/google/firebase/FirebaseOptions.java
index 133cdc1..fc4df26 100644
--- a/src/main/java/com/google/firebase/FirebaseOptions.java
+++ b/src/main/java/com/google/firebase/FirebaseOptions.java
@@ -57,13 +57,17 @@ public final class FirebaseOptions {
     this.databaseUrl = builder.databaseUrl;
     this.databaseAuthVariableOverride = builder.databaseAuthVariableOverride;
     this.projectId = builder.projectId;
+    if (!Strings.isNullOrEmpty(builder.storageBucket)) {
+      checkArgument(!builder.storageBucket.startsWith("gs://"),
+          "StorageBucket must not include 'gs://' prefix.");
+    }
     this.storageBucket = builder.storageBucket;
     this.httpTransport = checkNotNull(builder.httpTransport,
         "FirebaseOptions must be initialized with a non-null HttpTransport.");
     this.jsonFactory = checkNotNull(builder.jsonFactory,
         "FirebaseOptions must be initialized with a non-null JsonFactory.");
     this.threadManager = checkNotNull(builder.threadManager,
-        "FirebaseOptions must be initialized with a non-null ThreadManager");
+        "FirebaseOptions must be initialized with a non-null ThreadManager.");
   }
 
   /**
@@ -190,13 +194,17 @@ public final class FirebaseOptions {
 
     /**
      * Sets the name of the Google Cloud Storage bucket for reading and writing application data.
-     * The same credential used to initialize the SDK (see {@link Builder#setCredential}) will be
+     * This should be the full name of the bucket as listed in the
+     * <a href="https://console.cloud.google.com">Google Cloud Platform Console</a>, and must not
+     * include {@code gs://} or any other protocol prefixes.
+     * The same credential used to initialize the SDK (see {@link Builder#setCredentials}) is
      * used to access the bucket.
      *
-     * <p>See <a href="https://firebase.google.com/docs/admin/setup#initialize_the_sdk">
-     * Initialize the SDK</a> for code samples and detailed documentation.
+     * <p>See <a href="https://firebase.google.com/docs/storage/admin/start">
+     * Introduction to the Admin Cloud Storage API</a> for code samples and detailed documentation.
      *
-     * @param storageBucket The name of an existing Google Cloud Storage bucket.
+     * @param storageBucket The full name of an existing Google Cloud Storage bucket, excluding any
+     *     protocol prefixes.
      * @return This <code>Builder</code> instance is returned so subsequent calls can be chained.
      */
     public Builder setStorageBucket(String storageBucket) {


Test patch:
diff --git a/src/test/java/com/google/firebase/FirebaseOptionsTest.java b/src/test/java/com/google/firebase/FirebaseOptionsTest.java
index 1d39fde..b02fbbd 100644
--- a/src/test/java/com/google/firebase/FirebaseOptionsTest.java
+++ b/src/test/java/com/google/firebase/FirebaseOptionsTest.java
@@ -174,6 +174,14 @@ public class FirebaseOptionsTest {
     new FirebaseOptions.Builder().setCredentials(null).build();
   }
 
+  @Test(expected = IllegalArgumentException.class)
+  public void createOptionsWithStorageBucketUrl() throws IOException {
+    new FirebaseOptions.Builder()
+        .setCredentials(GoogleCredentials.fromStream(ServiceAccount.EDITOR.asStream()))
+        .setStorageBucket("gs://mock-storage-bucket")
+        .build();
+  }
+
   @Test(expected = NullPointerException.class)
   public void createOptionsWithNullThreadManager() {
     new FirebaseOptions.Builder()