Skip to content

Commit 9e5a8e0

Browse files
authored
chore: Implementing the publish workflow (#147)
* chore: Implementing the publish workflow * Fixed send-tweet action path
1 parent c615e61 commit 9e5a8e0

File tree

4 files changed

+330
-0
lines changed

4 files changed

+330
-0
lines changed
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
#!/bin/bash
2+
3+
set -e
4+
set -u
5+
6+
function printChangelog() {
7+
local TITLE=$1
8+
shift
9+
# Skip the sentinel value.
10+
local ENTRIES=("${@:2}")
11+
if [ ${#ENTRIES[@]} -ne 0 ]; then
12+
echo "### ${TITLE}"
13+
echo ""
14+
for ((i = 0; i < ${#ENTRIES[@]}; i++))
15+
do
16+
echo "* ${ENTRIES[$i]}"
17+
done
18+
echo ""
19+
fi
20+
}
21+
22+
if [[ -z "${GITHUB_SHA}" ]]; then
23+
GITHUB_SHA="HEAD"
24+
fi
25+
26+
LAST_TAG=`git describe --tags $(git rev-list --tags --max-count=1) 2> /dev/null` || true
27+
if [[ -z "${LAST_TAG}" ]]; then
28+
echo "[INFO] No tags found. Including all commits up to ${GITHUB_SHA}."
29+
VERSION_RANGE="${GITHUB_SHA}"
30+
else
31+
echo "[INFO] Last release tag: ${LAST_TAG}."
32+
COMMIT_SHA=`git show-ref -s ${LAST_TAG}`
33+
echo "[INFO] Last release commit: ${COMMIT_SHA}."
34+
VERSION_RANGE="${COMMIT_SHA}..${GITHUB_SHA}"
35+
echo "[INFO] Including all commits in the range ${VERSION_RANGE}."
36+
fi
37+
38+
echo ""
39+
40+
# Older versions of Bash (< 4.4) treat empty arrays as unbound variables, which triggers
41+
# errors when referencing them. Therefore we initialize each of these arrays with an empty
42+
# sentinel value, and later skip them.
43+
CHANGES=("")
44+
FIXES=("")
45+
FEATS=("")
46+
MISC=("")
47+
48+
while read -r line
49+
do
50+
COMMIT_MSG=`echo ${line} | cut -d ' ' -f 2-`
51+
if [[ $COMMIT_MSG =~ ^change(\(.*\))?: ]]; then
52+
CHANGES+=("$COMMIT_MSG")
53+
elif [[ $COMMIT_MSG =~ ^fix(\(.*\))?: ]]; then
54+
FIXES+=("$COMMIT_MSG")
55+
elif [[ $COMMIT_MSG =~ ^feat(\(.*\))?: ]]; then
56+
FEATS+=("$COMMIT_MSG")
57+
else
58+
MISC+=("${COMMIT_MSG}")
59+
fi
60+
done < <(git log ${VERSION_RANGE} --oneline)
61+
62+
printChangelog "Breaking Changes" "${CHANGES[@]}"
63+
printChangelog "New Features" "${FEATS[@]}"
64+
printChangelog "Bug Fixes" "${FIXES[@]}"
65+
printChangelog "Miscellaneous" "${MISC[@]}"

.github/scripts/publish_package.sh

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
#!/bin/bash
2+
3+
# Copyright 2020 Google Inc.
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+
set -e
18+
set -u
19+
20+
readonly UNPREFIXED_VERSION=`echo ${VERSION} | cut -c 2-`
21+
dotnet nuget push Release/FirebaseAdmin.${UNPREFIXED_VERSION}.nupkg \
22+
-k ${NUGET_KEY} \
23+
-s https://api.nuget.org/v3/index.json
Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
#!/bin/bash
2+
3+
# Copyright 2020 Google Inc.
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+
###################################### Outputs #####################################
18+
19+
# 1. version: The version of this release including the 'v' prefix (e.g. v1.2.3).
20+
# 2. changelog: Formatted changelog text for this release.
21+
22+
####################################################################################
23+
24+
set -e
25+
set -u
26+
27+
function echo_info() {
28+
local MESSAGE=$1
29+
echo "[INFO] ${MESSAGE}"
30+
}
31+
32+
function echo_warn() {
33+
local MESSAGE=$1
34+
echo "[WARN] ${MESSAGE}"
35+
}
36+
37+
function terminate() {
38+
echo ""
39+
echo_warn "--------------------------------------------"
40+
echo_warn "PREFLIGHT FAILED"
41+
echo_warn "--------------------------------------------"
42+
exit 1
43+
}
44+
45+
46+
echo_info "Starting publish preflight check..."
47+
echo_info "Git revision : ${GITHUB_SHA}"
48+
echo_info "Workflow triggered by : ${GITHUB_ACTOR}"
49+
echo_info "GitHub event : ${GITHUB_EVENT_NAME}"
50+
51+
52+
echo_info ""
53+
echo_info "--------------------------------------------"
54+
echo_info "Extracting release version"
55+
echo_info "--------------------------------------------"
56+
echo_info ""
57+
58+
readonly PROJECT_FILE="FirebaseAdmin/FirebaseAdmin/FirebaseAdmin.csproj"
59+
echo_info "Loading version from: ${PROJECT_FILE}"
60+
61+
readonly RELEASE_VERSION=`grep -oPm1 "(?<=<Version>)[^<]+" ${PROJECT_FILE}` || true
62+
if [[ -z "${RELEASE_VERSION}" ]]; then
63+
echo_warn "Failed to extract release version from: ${PROJECT_FILE}"
64+
terminate
65+
fi
66+
67+
if [[ ! "${RELEASE_VERSION}" =~ ^([0-9]*)\.([0-9]*)\.([0-9]*)$ ]]; then
68+
echo_warn "Malformed release version string: ${RELEASE_VERSION}. Exiting."
69+
terminate
70+
fi
71+
72+
echo_info "Extracted release version: ${RELEASE_VERSION}"
73+
echo "::set-output name=version::v${RELEASE_VERSION}"
74+
75+
76+
echo_info ""
77+
echo_info "--------------------------------------------"
78+
echo_info "Check release artifacts"
79+
echo_info "--------------------------------------------"
80+
echo_info ""
81+
82+
if [[ ! -d Release ]]; then
83+
echo_warn "Release directory does not exist."
84+
terminate
85+
fi
86+
87+
readonly RELEASE_ARTIFACT="Release/FirebaseAdmin.${RELEASE_VERSION}.nupkg"
88+
if [[ -f "${RELEASE_ARTIFACT}" ]]; then
89+
echo_info "Found release artifact: ${RELEASE_ARTIFACT}"
90+
else
91+
echo_warn "Release artifact ${RELEASE_ARTIFACT} not found."
92+
terminate
93+
fi
94+
95+
96+
echo_info ""
97+
echo_info "--------------------------------------------"
98+
echo_info "Checking previous releases"
99+
echo_info "--------------------------------------------"
100+
echo_info ""
101+
102+
103+
mkdir -p VersionCheck
104+
pushd VersionCheck
105+
dotnet new console
106+
dotnet add package FirebaseAdmin --version ${RELEASE_VERSION} || true
107+
readonly PACKAGE_REFERENCE=`grep "PackageReference Include=\"FirebaseAdmin\"" VersionCheck.csproj` || true
108+
if [[ -n ${PACKAGE_REFERENCE} ]]; then
109+
echo_warn "Release version ${RELEASE_VERSION} already present in Nuget."
110+
terminate
111+
fi
112+
113+
echo_info "Release version ${RELEASE_VERSION} not found in Nuget."
114+
popd
115+
116+
117+
echo_info ""
118+
echo_info "--------------------------------------------"
119+
echo_info "Checking release tag"
120+
echo_info "--------------------------------------------"
121+
echo_info ""
122+
123+
echo_info "---< git fetch --depth=1 origin +refs/tags/*:refs/tags/* >---"
124+
git fetch --depth=1 origin +refs/tags/*:refs/tags/*
125+
echo ""
126+
127+
readonly EXISTING_TAG=`git rev-parse -q --verify "refs/tags/v${RELEASE_VERSION}"` || true
128+
if [[ -n "${EXISTING_TAG}" ]]; then
129+
echo_warn "Tag v${RELEASE_VERSION} already exists. Exiting."
130+
echo_warn "If the tag was created in a previous unsuccessful attempt, delete it and try again."
131+
echo_warn " $ git tag -d v${RELEASE_VERSION}"
132+
echo_warn " $ git push --delete origin v${RELEASE_VERSION}"
133+
134+
readonly RELEASE_URL="https://github.com/firebase/firebase-admin-dotnet/releases/tag/v${RELEASE_VERSION}"
135+
echo_warn "Delete any corresponding releases at ${RELEASE_URL}."
136+
terminate
137+
fi
138+
139+
echo_info "Tag v${RELEASE_VERSION} does not exist."
140+
141+
142+
echo_info ""
143+
echo_info "--------------------------------------------"
144+
echo_info "Generating changelog"
145+
echo_info "--------------------------------------------"
146+
echo_info ""
147+
148+
echo_info "---< git fetch origin master --prune --unshallow >---"
149+
git fetch origin master --prune --unshallow
150+
echo ""
151+
152+
echo_info "Generating changelog from history..."
153+
readonly CURRENT_DIR=$(dirname "$0")
154+
readonly CHANGELOG=`${CURRENT_DIR}/generate_changelog.sh`
155+
echo "$CHANGELOG"
156+
157+
# Parse and preformat the text to handle multi-line output.
158+
# See https://github.saobby.my.eu.orgmunity/t5/GitHub-Actions/set-output-Truncates-Multiline-Strings/td-p/37870
159+
FILTERED_CHANGELOG=`echo "$CHANGELOG" | grep -v "\\[INFO\\]"` || true
160+
FILTERED_CHANGELOG="${FILTERED_CHANGELOG//'%'/'%25'}"
161+
FILTERED_CHANGELOG="${FILTERED_CHANGELOG//$'\n'/'%0A'}"
162+
FILTERED_CHANGELOG="${FILTERED_CHANGELOG//$'\r'/'%0D'}"
163+
echo "::set-output name=changelog::${FILTERED_CHANGELOG}"
164+
165+
166+
echo ""
167+
echo_info "--------------------------------------------"
168+
echo_info "PREFLIGHT SUCCESSFUL"
169+
echo_info "--------------------------------------------"

.github/workflows/release.yml

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ jobs:
3434
(github.event.pull_request.merged &&
3535
contains(github.event.pull_request.labels.*.name, 'release:publish'))
3636

37+
# Build and package artifacts on Windows.
3738
runs-on: windows-latest
3839

3940
env:
@@ -70,3 +71,75 @@ jobs:
7071
with:
7172
name: Release
7273
path: FirebaseAdmin/FirebaseAdmin/bin/Release
74+
75+
publish_release:
76+
needs: stage_release
77+
78+
# Check whether the release should be published. We publish only when the trigger PR is
79+
# 1. merged
80+
# 2. to the master branch
81+
# 3. with the label 'release:publish', and
82+
# 4. the title prefix '[chore] Release '.
83+
if: github.event.pull_request.merged &&
84+
github.ref == 'master' &&
85+
contains(github.event.pull_request.labels.*.name, 'release:publish') &&
86+
startsWith(github.event.pull_request.title, '[chore] Release ')
87+
88+
# Use Linux for this phase, so we can reuse the same helper scripts as other Admin SDK
89+
# repositories.
90+
runs-on: ubuntu-latest
91+
92+
steps:
93+
- name: Checkout source for publish
94+
uses: actions/checkout@v2
95+
96+
# Download the artifacts created by the stage_release job.
97+
- name: Download release candidates
98+
uses: actions/download-artifact@v1
99+
with:
100+
name: Release
101+
102+
- name: Setup .NET Core
103+
if: matrix.os == 'ubuntu-latest'
104+
uses: actions/setup-dotnet@v1
105+
with:
106+
dotnet-version: 2.2.108
107+
108+
- name: Publish preflight check
109+
id: preflight
110+
run: ./.github/scripts/publish_preflight_check.sh
111+
112+
# We pull this action from a custom fork of a contributor until
113+
# https://github.com/actions/create-release/pull/32 is merged. Also note that v1 of
114+
# this action does not support the "body" parameter.
115+
- name: Create release tag
116+
uses: fleskesvor/create-release@1a72e235c178bf2ae6c51a8ae36febc24568c5fe
117+
env:
118+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
119+
with:
120+
tag_name: ${{ steps.preflight.outputs.version }}
121+
release_name: Firebase Admin .NET SDK ${{ steps.preflight.outputs.version }}
122+
body: ${{ steps.preflight.outputs.changelog }}
123+
draft: false
124+
prerelease: false
125+
126+
- name: Publish to Nuget
127+
run: ./.github/scripts/publish_package.sh
128+
env:
129+
NUGET_KEY: ${{ secrets.NUGET_KEY }}
130+
VERSION: ${{ steps.preflight.outputs.version }}
131+
132+
# Post to Twitter if explicitly opted-in by adding the label 'release:tweet'.
133+
- name: Post to Twitter
134+
if: success() &&
135+
contains(github.event.pull_request.labels.*.name, 'release:tweet')
136+
uses: firebase/firebase-admin-node/.github/actions/send-tweet@master
137+
with:
138+
status: >
139+
${{ steps.preflight.outputs.version }} of @Firebase Admin .NET SDK is avaialble.
140+
https://github.com/firebase/firebase-admin-dotnet/releases/tag/${{ steps.preflight.outputs.version }}
141+
consumer-key: ${{ secrets.TWITTER_CONSUMER_KEY }}
142+
consumer-secret: ${{ secrets.TWITTER_CONSUMER_SECRET }}
143+
access-token: ${{ secrets.TWITTER_ACCESS_TOKEN }}
144+
access-token-secret: ${{ secrets.TWITTER_ACCESS_TOKEN_SECRET }}
145+
continue-on-error: true

0 commit comments

Comments
 (0)