Skip to content

Commit

Permalink
GitHub Actions Support (#77)
Browse files Browse the repository at this point in the history
* Add github actions for verification.
* Added explicit repository license.
* Fixed typo in index file.
* Added to changelog
  • Loading branch information
barticus authored Oct 4, 2023
1 parent 738cf1d commit 2ac7ef0
Show file tree
Hide file tree
Showing 7 changed files with 527 additions and 1 deletion.
34 changes: 34 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Copyright 2019 Google LLC
#
# 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
#
# https://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.

# Copied from https://github.com/firebase/extensions/blob/next/.github/workflows/release.yml

name: Release

on:
push:
branches:
- master

jobs:
release:
name: "Create Releases"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Release Script
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
./.github/workflows/scripts/release.sh
202 changes: 202 additions & 0 deletions .github/workflows/scripts/release.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,202 @@
# Copyright 2019 Google LLC
#
# 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
#
# https://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.

# Copied and modified from https://github.com/firebase/extensions/blob/next/.github/workflows/scripts/release.sh. Changes:
# 1. Read the extension name from the extension.yaml file instead of from the directory name.

#!/bin/bash
set -e
set -o pipefail

# Uncomment for testing purposes:

#GITHUB_TOKEN=YOUR_TOKEN_HERE
#GITHUB_REPOSITORY=invertase/extensions-release-testing

# -------------------
# Functions
# -------------------
json_escape() {
printf '%s' "$1" | python -c 'import json,sys; print(json.dumps(sys.stdin.read()))'
}

# Creates a new GitHub release
# ARGS:
# 1: Name of the release (becomes the release title on GitHub)
# 2: Markdown body of the release
# 3: Release Git tag
create_github_release() {
local response=''
local release_name=$1
local release_body=$2
local release_tag=$3

local body='{
"tag_name": "%s",
"target_commitish": "master",
"name": "%s",
"body": %s,
"draft": false,
"prerelease": false
}'

# shellcheck disable=SC2059
body=$(printf "$body" "$release_tag" "$release_name" "$release_body")
response=$(curl --request POST \
--url https://api.github.com/repos/${GITHUB_REPOSITORY}/releases \
--header "Authorization: Bearer $GITHUB_TOKEN" \
--header 'Content-Type: application/json' \
--data "$body" \
-s)

created=$(echo "$response" | python -c "import sys, json; data = json.load(sys.stdin); print(data.get('id', sys.stdin))")
if [ "$created" != "$response" ]; then
printf "release created successfully!\n"
else
printf "release failed to create; "
printf "\n%s\n" "$body"
printf "\n%s\n" "$response"
exit 1
fi
}

# Updates an existing GitHub release
# ARGS:
# 1: Name of the release (becomes the release title on GitHub)
# 2: Markdown body of the release
# 3: Release Git tag
# 4: ID of the existing release
update_github_release() {
local response=''
local release_name=$1
local release_body=$2
local release_tag=$3
local release_id=$4

local body='{
"tag_name": "%s",
"target_commitish": "master",
"name": "%s",
"body": %s,
"draft": false,
"prerelease": false
}'

# shellcheck disable=SC2059
body=$(printf "$body" "$release_tag" "$release_name" "$release_body")
response=$(curl --request PATCH \
--url "https://api.github.com/repos/$GITHUB_REPOSITORY/releases/$release_id" \
--header "Authorization: Bearer $GITHUB_TOKEN" \
--header 'Content-Type: application/json' \
--data "$body" \
-s)

updated=$(echo "$response" | python -c "import sys, json; data = json.load(sys.stdin); print(data.get('id', sys.stdin))")
if [ "$updated" != "$response" ]; then
printf "release updated successfully!\n"
else
printf "release failed to update; "
printf "\n%s\n" "$body"
printf "\n%s\n" "$response"
exit 1
fi
}

# Creates or updates a GitHub release
# ARGS:
# 1: Extension name
# 2: Extension version
# 3: Markdown body to use for the release
create_or_update_github_release() {
local response=''
local release_id=''
local extension_name=$1
local extension_version=$2
local release_body=$3
local release_tag="$extension_name-v$extension_version"
local release_name="$extension_name v$extension_version"

response=$(curl --request GET \
--url "https://api.github.com/repos/${GITHUB_REPOSITORY}/releases/tags/${release_tag}" \
--header "Authorization: Bearer $GITHUB_TOKEN" \
--header 'Content-Type: application/json' \
--data "$body" \
-s)

release_id=$(echo "$response" | python -c "import sys, json; data = json.load(sys.stdin); print(data.get('id', 'Not Found'))")
if [ "$release_id" != "Not Found" ]; then
existing_release_body=$(echo "$response" | python -c "import sys, json; data = json.load(sys.stdin); print(data.get('body', ''))")
existing_release_body=$(json_escape "$existing_release_body")
# Only update it if the release body is different (this can happen if a change log is manually updated)
printf "Existing release (%s) found for %s - " "$release_id" "$release_tag"
if [ "$existing_release_body" != "$release_body" ]; then
printf "updating it with updated release body ... "
update_github_release "$release_name" "$release_body" "$release_tag" "$release_id"
else
printf "skipping it as release body is already up to date.\n"
fi
else
response_message=$(echo "$response" | python -c "import sys, json; data = json.load(sys.stdin); print(data.get('message'))")
if [ "$response_message" != "Not Found" ]; then
echo "Failed to query release '$release_name' -> GitHub API request failed with response: $response_message"
echo "$response"
exit 1
else
printf "Creating new release '%s' ... " "$release_tag"
create_github_release "$release_name" "$release_body" "$release_tag"
fi
fi
}

# -------------------
# Main Script
# -------------------

# Ensure that the GITHUB_TOKEN env variable is defined
if [[ -z "$GITHUB_TOKEN" ]]; then
echo "Missing required GITHUB_TOKEN env variable. Set this on the workflow action or on your local environment."
exit 1
fi

# Ensure that the GITHUB_REPOSITORY env variable is defined
if [[ -z "$GITHUB_REPOSITORY" ]]; then
echo "Missing required GITHUB_REPOSITORY env variable. Set this on the workflow action or on your local environment."
exit 1
fi

# Find all extensions based on whether a extension.yaml file exists in the directory
for i in $(find . -type f -name 'extension.yaml' -exec dirname {} \; | sort -u); do
# Pluck extension latest name from yaml file
extension_name=$(awk '/^name: /' "$i/extension.yaml" | sed "s/name: //")
# Pluck extension latest version from yaml file
extension_version=$(awk '/^version: /' "$i/extension.yaml" | sed "s/version: //")

changelog_contents="No changelog found for this version."

# Ensure changelog exists
if [ -f "$i/CHANGELOG.md" ]; then
# Pluck out change log contents for the latest extension version
changelog_contents=$(awk -v ver="$extension_version" '/^## Version / { if (p) { exit }; if ($3 == ver) { p=1; next} } p && NF' "$i/CHANGELOG.md")
else
echo "WARNING: A changelog could not be found at $i/CHANGELOG.md - a default entry will be used instead."
fi

# JSON escape the markdown content for the release body
changelog_contents=$(json_escape "$changelog_contents")

# Creates a new release if it does not exist
# OR
# Updates an existing release with updated content (allows updating CHANGELOG.md which will update relevant release body)
create_or_update_github_release "$extension_name" "$extension_version" "$changelog_contents"
done
47 changes: 47 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# Copyright 2019 Google LLC
#
# 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
#
# https://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.

# Copied and modified from https://github.com/firebase/extensions/blob/next/.github/workflows/test.yml. Changes:
# 1. Changed node versions list to only 18.
# 2. Updated paths to use functions directory.

name: Testing

on:
push:
branches:
- "**"
pull_request:
branches:
- "**"

jobs:
nodejs:
runs-on: ubuntu-latest
strategy:
matrix:
node: ["18"]
name: node.js_${{ matrix.node }}_test
steps:
- uses: actions/checkout@v3
- name: Setup node
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node }}
cache: "npm"
cache-dependency-path: "**/package-lock.json"
- name: npm install
run: cd functions && npm i
- name: npm test
run: cd functions && npm run test
40 changes: 40 additions & 0 deletions .github/workflows/validate.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# Copyright 2019 Google LLC
#
# 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
#
# https://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.

# Copied from https://github.com/firebase/extensions/blob/next/.github/workflows/validate.yml
# 1. Changed node versions list to only 18.
# 2. Updated paths to use functions directory.

name: Validate

on:
pull_request:
branches:
- "**"

jobs:
formatting:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup node
uses: actions/setup-node@v3
with:
node-version: 18
cache: "npm"
cache-dependency-path: "**/package-lock.json"
- name: npm install
run: cd functions && npm i
- name: Prettier Lint Check
run: cd functions && npm run lint
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
- Add a configurable retry to allow a higher chance of requests causing transient failures to succeed (PR #69)
- Added linter config and updated packages. (PR #70)
- Node.JS 18 runtime for functions (PR #73)
- GitHub Actions Support to assist with verification and publishing (PR #77)

## Version 0.5.3

Expand Down
Loading

0 comments on commit 2ac7ef0

Please sign in to comment.