Skip to content

Commit 496a353

Browse files
authored
[chore] Release 0.0.1rc0 (#66)
1 parent 842257b commit 496a353

File tree

5 files changed

+395
-2
lines changed

5 files changed

+395
-2
lines changed

.github/scripts/generate_changelog.sh

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
#!/bin/bash
2+
3+
# Copyright 2023 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+
function printChangelog() {
21+
local TITLE=$1
22+
shift
23+
# Skip the sentinel value.
24+
local ENTRIES=("${@:2}")
25+
if [ ${#ENTRIES[@]} -ne 0 ]; then
26+
echo "### ${TITLE}"
27+
echo ""
28+
for ((i = 0; i < ${#ENTRIES[@]}; i++))
29+
do
30+
echo "* ${ENTRIES[$i]}"
31+
done
32+
echo ""
33+
fi
34+
}
35+
36+
if [[ -z "${GITHUB_SHA}" ]]; then
37+
GITHUB_SHA="HEAD"
38+
fi
39+
40+
LAST_TAG=`git describe --tags $(git rev-list --tags --max-count=1) 2> /dev/null` || true
41+
if [[ -z "${LAST_TAG}" ]]; then
42+
echo "[INFO] No tags found. Including all commits up to ${GITHUB_SHA}."
43+
VERSION_RANGE="${GITHUB_SHA}"
44+
else
45+
echo "[INFO] Last release tag: ${LAST_TAG}."
46+
COMMIT_SHA=`git show-ref -s ${LAST_TAG}`
47+
echo "[INFO] Last release commit: ${COMMIT_SHA}."
48+
VERSION_RANGE="${COMMIT_SHA}..${GITHUB_SHA}"
49+
echo "[INFO] Including all commits in the range ${VERSION_RANGE}."
50+
fi
51+
52+
echo ""
53+
54+
# Older versions of Bash (< 4.4) treat empty arrays as unbound variables, which triggers
55+
# errors when referencing them. Therefore we initialize each of these arrays with an empty
56+
# sentinel value, and later skip them.
57+
CHANGES=("")
58+
FIXES=("")
59+
FEATS=("")
60+
MISC=("")
61+
62+
while read -r line
63+
do
64+
COMMIT_MSG=`echo ${line} | cut -d ' ' -f 2-`
65+
if [[ $COMMIT_MSG =~ ^change(\(.*\))?: ]]; then
66+
CHANGES+=("$COMMIT_MSG")
67+
elif [[ $COMMIT_MSG =~ ^fix(\(.*\))?: ]]; then
68+
FIXES+=("$COMMIT_MSG")
69+
elif [[ $COMMIT_MSG =~ ^refactor(\(.*\))?: ]]; then
70+
FIXES+=("$COMMIT_MSG")
71+
elif [[ $COMMIT_MSG =~ ^feat(\(.*\))?: ]]; then
72+
FEATS+=("$COMMIT_MSG")
73+
else
74+
MISC+=("${COMMIT_MSG}")
75+
fi
76+
done < <(git log ${VERSION_RANGE} --oneline)
77+
78+
printChangelog "Breaking Changes" "${CHANGES[@]}"
79+
printChangelog "New Features" "${FEATS[@]}"
80+
printChangelog "Bug Fixes" "${FIXES[@]}"
Lines changed: 179 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,179 @@
1+
#!/bin/bash
2+
3+
# Copyright 2023 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+
18+
###################################### Outputs #####################################
19+
20+
# 1. version: The version of this release including the 'v' prefix (e.g. v1.2.3).
21+
# 2. changelog: Formatted changelog text for this release.
22+
23+
####################################################################################
24+
25+
set -e
26+
set -u
27+
28+
function echo_info() {
29+
local MESSAGE=$1
30+
echo "[INFO] ${MESSAGE}"
31+
}
32+
33+
function echo_warn() {
34+
local MESSAGE=$1
35+
echo "[WARN] ${MESSAGE}"
36+
}
37+
38+
function terminate() {
39+
echo ""
40+
echo_warn "--------------------------------------------"
41+
echo_warn "PREFLIGHT FAILED"
42+
echo_warn "--------------------------------------------"
43+
exit 1
44+
}
45+
46+
47+
echo_info "Starting publish preflight check..."
48+
echo_info "Git revision : ${GITHUB_SHA}"
49+
echo_info "Workflow triggered by : ${GITHUB_ACTOR}"
50+
echo_info "GitHub event : ${GITHUB_EVENT_NAME}"
51+
52+
53+
echo_info ""
54+
echo_info "--------------------------------------------"
55+
echo_info "Extracting release version"
56+
echo_info "--------------------------------------------"
57+
echo_info ""
58+
59+
readonly INIT_FILE="src/firebase_functions/__init__.py"
60+
echo_info "Loading version from: ${INIT_FILE}"
61+
62+
readonly RELEASE_VERSION=`grep "__version__" ${INIT_FILE} | awk '{print $3}' | tr -d \"` || true
63+
if [[ -z "${RELEASE_VERSION}" ]]; then
64+
echo_warn "Failed to extract release version from: ${INIT_FILE}"
65+
terminate
66+
fi
67+
68+
if [[ ! "${RELEASE_VERSION}" =~ ^[0-9]+\.[0-9]+\.[0-9]+([a-zA-Z0-9]+)?$ ]]; then
69+
echo_warn "Malformed release version string: ${RELEASE_VERSION}. Exiting."
70+
terminate
71+
fi
72+
73+
echo_info "Extracted release version: ${RELEASE_VERSION}"
74+
echo "version=${RELEASE_VERSION}" >> "$GITHUB_OUTPUT"
75+
76+
77+
echo_info ""
78+
echo_info "--------------------------------------------"
79+
echo_info "Check release artifacts"
80+
echo_info "--------------------------------------------"
81+
echo_info ""
82+
83+
if [[ ! -d dist ]]; then
84+
echo_warn "dist directory does not exist."
85+
terminate
86+
fi
87+
88+
readonly BIN_DIST="dist/firebase_functions-${RELEASE_VERSION}-py3-none-any.whl"
89+
if [[ -f "${BIN_DIST}" ]]; then
90+
echo_info "Found binary distribution (bdist_wheel): ${BIN_DIST}"
91+
else
92+
echo_warn "Binary distribution ${BIN_DIST} not found."
93+
terminate
94+
fi
95+
96+
readonly SRC_DIST="dist/firebase_functions-${RELEASE_VERSION}.tar.gz"
97+
if [[ -f "${SRC_DIST}" ]]; then
98+
echo_info "Found source distribution (sdist): ${SRC_DIST}"
99+
else
100+
echo_warn "Source distribution ${SRC_DIST} not found."
101+
terminate
102+
fi
103+
104+
readonly ARTIFACT_COUNT=`ls dist/ | wc -l`
105+
if [[ $ARTIFACT_COUNT -ne 2 ]]; then
106+
echo_warn "Unexpected artifacts in the distribution directory."
107+
ls -l dist
108+
terminate
109+
fi
110+
111+
112+
echo_info ""
113+
echo_info "--------------------------------------------"
114+
echo_info "Checking previous releases"
115+
echo_info "--------------------------------------------"
116+
echo_info ""
117+
118+
readonly PYPI_URL="https://pypi.org/pypi/firebase-functions/${RELEASE_VERSION}/json"
119+
readonly PYPI_STATUS=`curl -s -o /dev/null -L -w "%{http_code}" ${PYPI_URL}`
120+
if [[ $PYPI_STATUS -eq 404 ]]; then
121+
echo_info "Release version ${RELEASE_VERSION} not found in Pypi."
122+
elif [[ $PYPI_STATUS -eq 200 ]]; then
123+
echo_warn "Release version ${RELEASE_VERSION} already present in Pypi."
124+
terminate
125+
else
126+
echo_warn "Unexpected ${PYPI_STATUS} response from Pypi. Exiting."
127+
terminate
128+
fi
129+
130+
131+
echo_info ""
132+
echo_info "--------------------------------------------"
133+
echo_info "Checking release tag"
134+
echo_info "--------------------------------------------"
135+
echo_info ""
136+
137+
readonly EXISTING_TAG=`git rev-parse -q --verify "refs/tags/v${RELEASE_VERSION}"` || true
138+
if [[ -n "${EXISTING_TAG}" ]]; then
139+
echo_warn "Tag v${RELEASE_VERSION} already exists. Exiting."
140+
echo_warn "If the tag was created in a previous unsuccessful attempt, delete it and try again."
141+
echo_warn " $ git tag -d v${RELEASE_VERSION}"
142+
echo_warn " $ git push --delete origin v${RELEASE_VERSION}"
143+
144+
readonly RELEASE_URL="https://github.com/firebase/firebase-functions-python/releases/tag/v${RELEASE_VERSION}"
145+
echo_warn "Delete any corresponding releases at ${RELEASE_URL}."
146+
terminate
147+
fi
148+
149+
echo_info "Tag v${RELEASE_VERSION} does not exist."
150+
151+
152+
echo_info ""
153+
echo_info "--------------------------------------------"
154+
echo_info "Generating changelog"
155+
echo_info "--------------------------------------------"
156+
echo_info ""
157+
158+
echo_info "---< git fetch origin main >---"
159+
git fetch origin main
160+
echo ""
161+
162+
echo_info "Generating changelog from history..."
163+
readonly CURRENT_DIR=$(dirname "$0")
164+
readonly CHANGELOG=`${CURRENT_DIR}/generate_changelog.sh`
165+
echo "$CHANGELOG"
166+
167+
# Parse and preformat the text to handle multi-line output.
168+
https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#example-of-a-multiline-string
169+
FILTERED_CHANGELOG=`echo "$CHANGELOG" | grep -v "\\[INFO\\]"`
170+
EOF=$(dd if=/dev/urandom bs=15 count=1 status=none | base64)
171+
echo "changelog=<<$EOF" >> "$GITHUB_OUTPUT"
172+
echo $CHANGELOG >> "$GITHUB_OUTPUT"
173+
echo $EOF >> "$GITHUG_OUTPUT"
174+
175+
176+
echo ""
177+
echo_info "--------------------------------------------"
178+
echo_info "PREFLIGHT SUCCESSFUL"
179+
echo_info "--------------------------------------------"

.github/workflows/release.yaml

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
# Copyright 2023 Google Inc.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
name: Release Candidate
16+
17+
on:
18+
pull_request:
19+
types: [opened, synchronize, closed]
20+
# Allow workflow to be triggered manually.
21+
workflow_dispatch:
22+
23+
jobs:
24+
stage_release:
25+
# To publish a release, merge the release PR with the label 'release:publish'.
26+
# To stage a release without publishing it, manually invoke the workflow.
27+
# . or apply the 'release:stage' label to a PR.
28+
if: (github.event.pull_request.merged && contains(github.event.pull_request.labels.*.name, 'release:publish')) ||
29+
github.event.workflow_dispatch ||
30+
contains(github.event.pull_request.labels.*.name, 'release:stage')
31+
32+
runs-on: ubuntu-latest
33+
34+
steps:
35+
- name: Checkout source for staging
36+
uses: actions/checkout@v3
37+
38+
- name: Set up Python
39+
uses: actions/setup-python@v4
40+
with:
41+
python-version: '3.10'
42+
43+
- name: Install dependencies
44+
run: |
45+
pip install --upgrade pip
46+
python -m pip install -e ".[dev]"
47+
48+
- name: Test with pytest & coverage
49+
run: |
50+
python -m pytest --cov=src --cov-report term --cov-report html --cov-report xml -vv
51+
52+
# Build the Python Wheel and the source distribution.
53+
- name: Package release artifacts
54+
run: |
55+
python -m pip install setuptools wheel
56+
python setup.py bdist_wheel sdist
57+
58+
# Attach the packaged artifacts to the workflow output. These can be manually
59+
# downloaded for later inspection if necessary.
60+
- name: Archive artifacts
61+
uses: actions/upload-artifact@v3
62+
with:
63+
name: dist
64+
path: dist/
65+
66+
publish_release:
67+
needs: stage_release
68+
69+
# Check whether the release should be published. We publish only when the trigger PR is
70+
# 1. merged
71+
# 2. to the master branch
72+
# 3. with the label 'release:publish', and
73+
# 4. the title prefix '[chore] Release '.
74+
if: github.event.pull_request.merged &&
75+
github.ref == 'master' &&
76+
contains(github.event.pull_request.labels.*.name, 'release:publish') &&
77+
startsWith(github.event.pull_request.title, '[chore] Release ')
78+
79+
runs-on: ubuntu-latest
80+
81+
steps:
82+
- name: Checkout source for publish
83+
uses: actions/checkout@v3
84+
85+
# Download the artifacts created by the stage_release job.
86+
- name: Download release candidates
87+
uses: actions/download-artifact@v3
88+
with:
89+
name: dist
90+
path: dist
91+
92+
- name: Publish preflight check
93+
id: preflight
94+
run: ./.github/scripts/publish_preflight_check.sh
95+
96+
- name: Create release tag
97+
# Skip creating a release tag for prereleases
98+
if: (!contains(github.event.pull_request.labels.*.name, 'release:prerelease'))
99+
uses: elgohr/Github-Release-Action@v4
100+
env:
101+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
102+
with:
103+
tag_name: ${{ steps.preflight.outputs.version }}
104+
release_name: Firebase Functions Python SDK ${{ steps.preflight.outputs.version }}
105+
body: ${{ steps.preflight.outputs.changelog }}
106+
draft: false
107+
prerelease: false
108+
109+
- name: Publish to Pypi
110+
uses: pypa/gh-action-pypi-publish@release/v1
111+
with:
112+
user: firebase
113+
password: ${{ secrets.PYPI_PASSWORD }}

0 commit comments

Comments
 (0)