diff --git a/.github/resources/firebase.asc.gpg b/.github/resources/firebase.asc.gpg
new file mode 100644
index 000000000..a946776c7
Binary files /dev/null and b/.github/resources/firebase.asc.gpg differ
diff --git a/.github/resources/integ-service-account.json.gpg b/.github/resources/integ-service-account.json.gpg
new file mode 100644
index 000000000..da547f44d
Binary files /dev/null and b/.github/resources/integ-service-account.json.gpg differ
diff --git a/.github/resources/settings.xml b/.github/resources/settings.xml
new file mode 100644
index 000000000..708bbcb75
--- /dev/null
+++ b/.github/resources/settings.xml
@@ -0,0 +1,29 @@
+
+
+
+ false
+
+
+
+ ossrh
+ ${env.NEXUS_OSSRH_USERNAME}
+ ${env.NEXUS_OSSRH_PASSWORD}
+
+
+
+
+
+ release
+
+ true
+
+
+ gpg
+ B652FFD3865AF7A75830876F5F55C8F6985BB9DD
+ ${env.GPG_PASSPHRASE}
+
+
+
+
diff --git a/.github/scripts/generate_changelog.sh b/.github/scripts/generate_changelog.sh
new file mode 100755
index 000000000..e393f40e4
--- /dev/null
+++ b/.github/scripts/generate_changelog.sh
@@ -0,0 +1,79 @@
+#!/bin/bash
+
+# Copyright 2020 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.
+
+set -e
+set -u
+
+function printChangelog() {
+ local TITLE=$1
+ shift
+ # Skip the sentinel value.
+ local ENTRIES=("${@:2}")
+ if [ ${#ENTRIES[@]} -ne 0 ]; then
+ echo "### ${TITLE}"
+ echo ""
+ for ((i = 0; i < ${#ENTRIES[@]}; i++))
+ do
+ echo "* ${ENTRIES[$i]}"
+ done
+ echo ""
+ fi
+}
+
+if [[ -z "${GITHUB_SHA}" ]]; then
+ GITHUB_SHA="HEAD"
+fi
+
+LAST_TAG=`git describe --tags $(git rev-list --tags --max-count=1) 2> /dev/null` || true
+if [[ -z "${LAST_TAG}" ]]; then
+ echo "[INFO] No tags found. Including all commits up to ${GITHUB_SHA}."
+ VERSION_RANGE="${GITHUB_SHA}"
+else
+ echo "[INFO] Last release tag: ${LAST_TAG}."
+ COMMIT_SHA=`git show-ref -s ${LAST_TAG}`
+ echo "[INFO] Last release commit: ${COMMIT_SHA}."
+ VERSION_RANGE="${COMMIT_SHA}..${GITHUB_SHA}"
+ echo "[INFO] Including all commits in the range ${VERSION_RANGE}."
+fi
+
+echo ""
+
+# Older versions of Bash (< 4.4) treat empty arrays as unbound variables, which triggers
+# errors when referencing them. Therefore we initialize each of these arrays with an empty
+# sentinel value, and later skip them.
+CHANGES=("")
+FIXES=("")
+FEATS=("")
+MISC=("")
+
+while read -r line
+do
+ COMMIT_MSG=`echo ${line} | cut -d ' ' -f 2-`
+ if [[ $COMMIT_MSG =~ ^change(\(.*\))?: ]]; then
+ CHANGES+=("$COMMIT_MSG")
+ elif [[ $COMMIT_MSG =~ ^fix(\(.*\))?: ]]; then
+ FIXES+=("$COMMIT_MSG")
+ elif [[ $COMMIT_MSG =~ ^feat(\(.*\))?: ]]; then
+ FEATS+=("$COMMIT_MSG")
+ else
+ MISC+=("${COMMIT_MSG}")
+ fi
+done < <(git log ${VERSION_RANGE} --oneline)
+
+printChangelog "Breaking Changes" "${CHANGES[@]}"
+printChangelog "New Features" "${FEATS[@]}"
+printChangelog "Bug Fixes" "${FIXES[@]}"
+printChangelog "Miscellaneous" "${MISC[@]}"
diff --git a/.github/scripts/package_artifacts.sh b/.github/scripts/package_artifacts.sh
new file mode 100755
index 000000000..6e993066e
--- /dev/null
+++ b/.github/scripts/package_artifacts.sh
@@ -0,0 +1,36 @@
+#!/bin/bash
+
+# Copyright 2020 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.
+
+set -e
+set -u
+
+gpg --quiet --batch --yes --decrypt --passphrase="${FIREBASE_SERVICE_ACCT_KEY}" \
+ --output integration_cert.json .github/resources/integ-service-account.json.gpg
+
+echo "${FIREBASE_API_KEY}" > integration_apikey.txt
+
+# Does the following:
+# 1. Runs the Checkstyle plugin (validate phase)
+# 2. Compiles the source (compile phase)
+# 3. Runs the unit tests (test phase)
+# 4. Packages the artifacts - src, bin, javadocs (package phase)
+# 5. Runs the integration tests (verify phase)
+mvn -B clean verify
+
+# Maven target directory can consist of many files. Just copy the jar artifacts
+# into a new directory for upload.
+mkdir -p dist
+cp target/*.jar dist/
diff --git a/.github/scripts/publish_artifacts.sh b/.github/scripts/publish_artifacts.sh
new file mode 100755
index 000000000..f4a2f1734
--- /dev/null
+++ b/.github/scripts/publish_artifacts.sh
@@ -0,0 +1,35 @@
+#!/bin/bash
+
+# Copyright 2020 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.
+
+set -e
+set -u
+
+gpg --quiet --batch --yes --decrypt --passphrase="${GPG_PRIVATE_KEY}" \
+ --output firebase.asc .github/resources/firebase.asc.gpg
+
+gpg --import firebase.asc
+
+# Does the following:
+# 1. Compiles the source (compile phase)
+# 2. Packages the artifacts - src, bin, javadocs (package phase)
+# 3. Signs the artifacts (verify phase)
+# 4. Publishes artifacts via Nexus (deploy phase)
+mvn -B clean deploy \
+ -Dcheckstyle.skip \
+ -DskipTests \
+ -Prelease \
+ --settings .github/resources/settings.xml
+
diff --git a/.github/scripts/publish_preflight_check.sh b/.github/scripts/publish_preflight_check.sh
new file mode 100755
index 000000000..7a191518d
--- /dev/null
+++ b/.github/scripts/publish_preflight_check.sh
@@ -0,0 +1,146 @@
+#!/bin/bash
+
+# Copyright 2020 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.
+
+
+###################################### Outputs #####################################
+
+# 1. version: The version of this release including the 'v' prefix (e.g. v1.2.3).
+# 2. changelog: Formatted changelog text for this release.
+
+####################################################################################
+
+set -e
+set -u
+
+function echo_info() {
+ local MESSAGE=$1
+ echo "[INFO] ${MESSAGE}"
+}
+
+function echo_warn() {
+ local MESSAGE=$1
+ echo "[WARN] ${MESSAGE}"
+}
+
+function terminate() {
+ echo ""
+ echo_warn "--------------------------------------------"
+ echo_warn "PREFLIGHT FAILED"
+ echo_warn "--------------------------------------------"
+ exit 1
+}
+
+
+echo_info "Starting publish preflight check..."
+echo_info "Git revision : ${GITHUB_SHA}"
+echo_info "Workflow triggered by : ${GITHUB_ACTOR}"
+echo_info "GitHub event : ${GITHUB_EVENT_NAME}"
+
+
+echo_info ""
+echo_info "--------------------------------------------"
+echo_info "Extracting release version"
+echo_info "--------------------------------------------"
+echo_info ""
+
+echo_info "Loading version from: pom.xml"
+readonly RELEASE_VERSION=`mvn help:evaluate -Dexpression=project.version -q -DforceStdout` || true
+if [[ -z "${RELEASE_VERSION}" ]]; then
+ echo_warn "Failed to extract release version from: pom.xml"
+ terminate
+fi
+
+if [[ ! "${RELEASE_VERSION}" =~ ^([0-9]*)\.([0-9]*)\.([0-9]*)$ ]]; then
+ echo_warn "Malformed release version string: ${RELEASE_VERSION}. Exiting."
+ terminate
+fi
+
+echo_info "Extracted release version: ${RELEASE_VERSION}"
+echo "::set-output name=version::v${RELEASE_VERSION}"
+
+
+echo_info ""
+echo_info "--------------------------------------------"
+echo_info "Checking previous releases"
+echo_info "--------------------------------------------"
+echo_info ""
+
+readonly MAVEN_CENTRAL_URL="https://repo1.maven.org/maven2/com/google/firebase/firebase-admin/${RELEASE_VERSION}"
+readonly MAVEN_STATUS=`curl -s -o /dev/null -L -w "%{http_code}" ${MAVEN_CENTRAL_URL}`
+if [[ $MAVEN_STATUS -eq 404 ]]; then
+ echo_info "Release version ${RELEASE_VERSION} not found in Maven Central."
+elif [[ $MAVEN_STATUS -eq 200 ]]; then
+ echo_warn "Release version ${RELEASE_VERSION} already present in Maven Central."
+ terminate
+else
+ echo_warn "Unexpected ${MAVEN_STATUS} response from Maven Central. Exiting."
+ terminate
+fi
+
+
+echo_info ""
+echo_info "--------------------------------------------"
+echo_info "Checking release tag"
+echo_info "--------------------------------------------"
+echo_info ""
+
+echo_info "---< git fetch --depth=1 origin +refs/tags/*:refs/tags/* >---"
+git fetch --depth=1 origin +refs/tags/*:refs/tags/*
+echo ""
+
+readonly EXISTING_TAG=`git rev-parse -q --verify "refs/tags/v${RELEASE_VERSION}"` || true
+if [[ -n "${EXISTING_TAG}" ]]; then
+ echo_warn "Tag v${RELEASE_VERSION} already exists. Exiting."
+ echo_warn "If the tag was created in a previous unsuccessful attempt, delete it and try again."
+ echo_warn " $ git tag -d v${RELEASE_VERSION}"
+ echo_warn " $ git push --delete origin v${RELEASE_VERSION}"
+
+ readonly RELEASE_URL="https://github.com/firebase/firebase-admin-java/releases/tag/v${RELEASE_VERSION}"
+ echo_warn "Delete any corresponding releases at ${RELEASE_URL}."
+ terminate
+fi
+
+echo_info "Tag v${RELEASE_VERSION} does not exist."
+
+
+echo_info ""
+echo_info "--------------------------------------------"
+echo_info "Generating changelog"
+echo_info "--------------------------------------------"
+echo_info ""
+
+echo_info "---< git fetch origin master --prune --unshallow >---"
+git fetch origin master --prune --unshallow
+echo ""
+
+echo_info "Generating changelog from history..."
+readonly CURRENT_DIR=$(dirname "$0")
+readonly CHANGELOG=`${CURRENT_DIR}/generate_changelog.sh`
+echo "$CHANGELOG"
+
+# Parse and preformat the text to handle multi-line output.
+# See https://github.community/t5/GitHub-Actions/set-output-Truncates-Multiline-Strings/td-p/37870
+FILTERED_CHANGELOG=`echo "$CHANGELOG" | grep -v "\\[INFO\\]"`
+FILTERED_CHANGELOG="${FILTERED_CHANGELOG//'%'/'%25'}"
+FILTERED_CHANGELOG="${FILTERED_CHANGELOG//$'\n'/'%0A'}"
+FILTERED_CHANGELOG="${FILTERED_CHANGELOG//$'\r'/'%0D'}"
+echo "::set-output name=changelog::${FILTERED_CHANGELOG}"
+
+
+echo ""
+echo_info "--------------------------------------------"
+echo_info "PREFLIGHT SUCCESSFUL"
+echo_info "--------------------------------------------"
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 10007c5c6..fbb1aad5e 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -1,15 +1,35 @@
+# Copyright 2020 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.
name: Continuous Integration
-on: [push, pull_request]
+on: push
jobs:
build:
runs-on: ubuntu-latest
+
steps:
- uses: actions/checkout@v1
+
- name: Set up JDK 1.7
uses: actions/setup-java@v1
with:
java-version: 1.7
+
+ # Does the following:
+ # 1. Runs the Checkstyle plugin (validate phase)
+ # 2. Compiles the source (compile phase)
+ # 3. Runs the unit tests (test phase)
- name: Build with Maven
- run: mvn -B package --file pom.xml
+ run: mvn -B clean test
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
new file mode 100644
index 000000000..0e1c307bc
--- /dev/null
+++ b/.github/workflows/release.yml
@@ -0,0 +1,129 @@
+# Copyright 2020 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.
+
+name: Release Candidate
+
+on:
+ # Only run the workflow when a PR is updated or when a developer explicitly requests
+ # a build by sending a 'firebase_build' event.
+ pull_request:
+ types: [opened, synchronize, closed]
+
+ repository_dispatch:
+ types:
+ - firebase_build
+
+jobs:
+ stage_release:
+ # To publish a release, merge the release PR with the label 'release:publish'.
+ # To stage a release without publishing it, send a 'firebase_build' event or apply
+ # the 'release:stage' label to a PR.
+ if: github.event.action == 'firebase_build' ||
+ contains(github.event.pull_request.labels.*.name, 'release:stage') ||
+ (github.event.pull_request.merged &&
+ contains(github.event.pull_request.labels.*.name, 'release:publish'))
+
+ runs-on: ubuntu-latest
+
+ # When manually triggering the build, the requester can specify a target branch or a tag
+ # via the 'ref' client parameter.
+ steps:
+ - name: Checkout source for staging
+ uses: actions/checkout@v2
+ with:
+ ref: ${{ github.event.client_payload.ref || github.ref }}
+
+ - name: Set up JDK 1.7
+ uses: actions/setup-java@v1
+ with:
+ java-version: 1.7
+
+ - name: Compile, test and package
+ run: ./.github/scripts/package_artifacts.sh
+ env:
+ FIREBASE_SERVICE_ACCT_KEY: ${{ secrets.FIREBASE_SERVICE_ACCT_KEY }}
+ FIREBASE_API_KEY: ${{ secrets.FIREBASE_API_KEY }}
+
+ # Attach the packaged artifacts to the workflow output. These can be manually
+ # downloaded for later inspection if necessary.
+ - name: Archive artifacts
+ uses: actions/upload-artifact@v1
+ with:
+ name: dist
+ path: dist
+
+ publish_release:
+ needs: stage_release
+
+ # Check whether the release should be published. We publish only when the trigger PR is
+ # 1. merged
+ # 2. to the master branch
+ # 3. with the label 'release:publish', and
+ # 4. the title prefix '[chore] Release '.
+ if: github.event.pull_request.merged &&
+ github.ref == 'master' &&
+ contains(github.event.pull_request.labels.*.name, 'release:publish') &&
+ startsWith(github.event.pull_request.title, '[chore] Release ')
+
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout source for publish
+ uses: actions/checkout@v2
+
+ - name: Set up JDK 1.7
+ uses: actions/setup-java@v1
+ with:
+ java-version: 1.7
+
+ - name: Publish preflight check
+ id: preflight
+ run: ./.github/scripts/publish_preflight_check.sh
+
+ # We pull this action from a custom fork of a contributor until
+ # https://github.com/actions/create-release/pull/32 is merged. Also note that v1 of
+ # this action does not support the "body" parameter.
+ - name: Create release tag
+ uses: fleskesvor/create-release@1a72e235c178bf2ae6c51a8ae36febc24568c5fe
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ with:
+ tag_name: ${{ steps.preflight.outputs.version }}
+ release_name: Firebase Admin Java SDK ${{ steps.preflight.outputs.version }}
+ body: ${{ steps.preflight.outputs.changelog }}
+ draft: false
+ prerelease: false
+
+ - name: Publish to Maven Central
+ run: ./.github/scripts/publish_artifacts.sh
+ env:
+ GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }}
+ GPG_PRIVATE_KEY: ${{ secrets.GPG_PRIVATE_KEY }}
+ NEXUS_OSSRH_USERNAME: ${{ secrets.NEXUS_OSSRH_USERNAME }}
+ NEXUS_OSSRH_PASSWORD: ${{ secrets.NEXUS_OSSRH_PASSWORD }}
+
+ # Post to Twitter if explicitly opted-in by adding the label 'release:tweet'.
+ - name: Post to Twitter
+ if: success() &&
+ contains(github.event.pull_request.labels.*.name, 'release:tweet')
+ uses: firebase/firebase-admin-node/.github/actions/send-tweet@master
+ with:
+ status: >
+ ${{ steps.preflight.outputs.version }} of @Firebase Admin Java SDK is available.
+ https://github.com/firebase/firebase-admin-java/releases/tag/${{ steps.preflight.outputs.version }}
+ consumer-key: ${{ secrets.TWITTER_CONSUMER_KEY }}
+ consumer-secret: ${{ secrets.TWITTER_CONSUMER_SECRET }}
+ access-token: ${{ secrets.TWITTER_ACCESS_TOKEN }}
+ access-token-secret: ${{ secrets.TWITTER_ACCESS_TOKEN_SECRET }}
+ continue-on-error: true
diff --git a/pom.xml b/pom.xml
index e82439e48..2900886ff 100644
--- a/pom.xml
+++ b/pom.xml
@@ -161,56 +161,8 @@
release
-
-
- true
-
-
- maven-javadoc-plugin
-
-
- package
-
- jar
-
-
-
-
-
- com.google.doclava
- doclava
- 1.0.6
-
- com.google.doclava.Doclava
- ${sun.boot.class.path}
-
-
- com.google.j2objc
- j2objc-annotations
- 1.3
-
-
-
- -warning 101
-
- false
- -J-Xmx1024m
-
-
-
- maven-source-plugin
- 2.2.1
-
-
- attach-sources
-
- jar-no-fork
-
-
-
-
maven-gpg-plugin
1.5
@@ -295,6 +247,7 @@
+
maven-checkstyle-plugin
2.17
@@ -315,6 +268,8 @@
+
+
maven-compiler-plugin
3.6.1
@@ -323,6 +278,8 @@
1.7
+
+
maven-surefire-plugin
2.19.1
@@ -330,32 +287,68 @@
${skipUTs}
+
+
- maven-failsafe-plugin
- 2.19.1
+ maven-source-plugin
+ 2.2.1
+ attach-sources
- integration-test
- verify
+ jar-no-fork
-
+
maven-javadoc-plugin
- 2.10.4
-
-
- maven-release-plugin
- 2.5.3
+
+
+ attach-javadocs
+
+ jar
+
+
+
- false
- release
- v@{project.version}
- deploy
+
+ com.google.doclava
+ doclava
+ 1.0.6
+
+ com.google.doclava.Doclava
+ ${sun.boot.class.path}
+
+
+ com.google.j2objc
+ j2objc-annotations
+ 1.3
+
+
+
+ -warning 101
+
+ false
+ -J-Xmx1024m
+
+
+
+ maven-failsafe-plugin
+ 2.19.1
+
+
+
+ integration-test
+ verify
+
+
+
+
+
+
org.sonatype.plugins
nexus-staging-maven-plugin
@@ -364,7 +357,7 @@
ossrh
https://oss.sonatype.org/
- false
+ true