Skip to content

Commit c07279f

Browse files
authored
chore(*): initial GitHub releases action (#272)
* chore: initial GitHub release script * chore: prettier * fix: add GH token env
1 parent ae37b73 commit c07279f

File tree

2 files changed

+190
-0
lines changed

2 files changed

+190
-0
lines changed

.github/workflows/release.yml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
name: Release
2+
3+
on:
4+
push:
5+
branches:
6+
- master
7+
8+
jobs:
9+
release:
10+
name: "Create Releases"
11+
runs-on: ubuntu-latest
12+
steps:
13+
- uses: actions/checkout@v1
14+
- name: Release Script
15+
env:
16+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
17+
run: |
18+
./.github/workflows/scripts/release.sh
Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
#!/bin/bash
2+
set -e
3+
set -o pipefail
4+
5+
# Uncomment for testing purposes:
6+
7+
#GITHUB_TOKEN=YOUR_TOKEN_HERE
8+
#GITHUB_REPOSITORY=invertase/extensions-release-testing
9+
10+
# -------------------
11+
# Functions
12+
# -------------------
13+
json_escape () {
14+
printf '%s' "$1" | python -c 'import json,sys; print(json.dumps(sys.stdin.read()))'
15+
}
16+
17+
# Creates a new GitHub release
18+
# ARGS:
19+
# 1: Name of the release (becomes the release title on GitHub)
20+
# 2: Markdown body of the release
21+
# 3: Release Git tag
22+
create_github_release(){
23+
local response=''
24+
local release_name=$1
25+
local release_body=$2
26+
local release_tag=$3
27+
28+
local body='{
29+
"tag_name": "%s",
30+
"target_commitish": "master",
31+
"name": "%s",
32+
"body": %s,
33+
"draft": false,
34+
"prerelease": false
35+
}'
36+
37+
# shellcheck disable=SC2059
38+
body=$(printf "$body" "$release_tag" "$release_name" "$release_body")
39+
response=$(curl --request POST \
40+
--url https://api.github.com/repos/${GITHUB_REPOSITORY}/releases \
41+
--header "Authorization: Bearer $GITHUB_TOKEN" \
42+
--header 'Content-Type: application/json' \
43+
--data "$body" \
44+
-s)
45+
46+
created=$(echo "$response" | python -c "import sys, json; data = json.load(sys.stdin); print(data.get('id', sys.stdin))")
47+
if [ "$created" != "$response" ]; then
48+
echo "release created successfully"
49+
else
50+
echo "release failed to create; "
51+
printf "\n%s\n" "$body"
52+
printf "\n%s\n" "$response"
53+
exit 1;
54+
fi
55+
}
56+
57+
# Updates an existing GitHub release
58+
# ARGS:
59+
# 1: Name of the release (becomes the release title on GitHub)
60+
# 2: Markdown body of the release
61+
# 3: Release Git tag
62+
# 4: ID of the existing release
63+
update_github_release(){
64+
local response=''
65+
local release_name=$1
66+
local release_body=$2
67+
local release_tag=$3
68+
local release_id=$4
69+
70+
local body='{
71+
"tag_name": "%s",
72+
"target_commitish": "master",
73+
"name": "%s",
74+
"body": %s,
75+
"draft": false,
76+
"prerelease": false
77+
}'
78+
79+
# shellcheck disable=SC2059
80+
body=$(printf "$body" "$release_tag" "$release_name" "$release_body")
81+
response=$(curl --request PATCH \
82+
--url "https://api.github.com/repos/$GITHUB_REPOSITORY/releases/$release_id" \
83+
--header "Authorization: Bearer $GITHUB_TOKEN" \
84+
--header 'Content-Type: application/json' \
85+
--data "$body" \
86+
-s)
87+
88+
updated=$(echo "$response" | python -c "import sys, json; data = json.load(sys.stdin); print(data.get('id', sys.stdin))")
89+
if [ "$updated" != "$response" ]; then
90+
echo "release updated successfully"
91+
else
92+
echo "release failed to update; "
93+
printf "\n%s\n" "$body"
94+
printf "\n%s\n" "$response"
95+
exit 1;
96+
fi
97+
}
98+
99+
# Creates or updates a GitHub release
100+
# ARGS:
101+
# 1: Extension name
102+
# 2: Extension version
103+
# 3: Markdown body to use for the release
104+
create_or_update_github_release() {
105+
local response=''
106+
local release_id=''
107+
local extension_name=$1
108+
local extension_version=$2
109+
local release_body=$3
110+
local release_tag="$extension_name-$extension_version"
111+
local release_name="$extension_name $extension_version"
112+
113+
response=$(curl --request GET \
114+
--url "https://api.github.com/repos/${GITHUB_REPOSITORY}/releases/tags/${release_tag}" \
115+
--header "Authorization: Bearer $GITHUB_TOKEN" \
116+
--header 'Content-Type: application/json' \
117+
--data "$body" \
118+
-s)
119+
120+
release_id=$(echo "$response" | python -c "import sys, json; data = json.load(sys.stdin); print(data.get('id', 'Not Found'))")
121+
if [ "$release_id" != "Not Found" ]; then
122+
echo "Existing release (${release_id}) found for $release_tag - updating it ... "
123+
update_github_release "$release_name" "$release_body" "$release_tag" "$release_id"
124+
else
125+
response_message=$(echo "$response" | python -c "import sys, json; data = json.load(sys.stdin); print(data.get('message', 'OK'))")
126+
if [ "$response_message" != "OK" ]; then
127+
echo "Failed to create/update release '$release_name' -> GitHub API request failed with response: $response_message"
128+
echo "$response"
129+
exit 1;
130+
else
131+
echo "Creating new release '$release_tag' ... "
132+
create_github_release "$release_name" "$release_body" "$release_tag"
133+
fi
134+
fi
135+
}
136+
137+
# -------------------
138+
# Main Script
139+
# -------------------
140+
141+
# Ensure that the GITHUB_TOKEN env variable is defined
142+
if [[ -z "$GITHUB_TOKEN" ]]; then
143+
echo "Missing required GITHUB_TOKEN env variable. Set this on the workflow action or on your local environment."
144+
exit 1
145+
fi
146+
147+
# Ensure that the GITHUB_REPOSITORY env variable is defined
148+
if [[ -z "$GITHUB_REPOSITORY" ]]; then
149+
echo "Missing required GITHUB_REPOSITORY env variable. Set this on the workflow action or on your local environment."
150+
exit 1
151+
fi
152+
153+
if [[ $(git branch | grep "^*" | awk '{print $2}') != "master" ]]; then
154+
# Find all extensions based on whether a extension.yaml file exists in the directory
155+
for i in $(find . -type f -name 'extension.yaml' -exec dirname {} \; | sort -u); do
156+
# Pluck extension name from directory name
157+
extension_name=$(echo "$i" | sed "s/\.\///")
158+
# Pluck extension latest version from yaml file
159+
extension_version=$(awk '/^version: /' "$i/extension.yaml" | sed "s/version: //")
160+
# Pluck out change log contents for the latest extension version
161+
changelog_contents=$(awk -v ver="$extension_version" '/^## Version / { if (p) { exit }; if ($3 == ver) { p=1; next} } p && NF' "$i/CHANGELOG.md")
162+
# JSON escape the markdown content for the release body
163+
changelog_contents=$(json_escape "$changelog_contents")
164+
# Creates a new release if it does not exist
165+
# OR
166+
# Updates an existing release with updated content (allows updating CHANGELOG.md which will update relevant release body)
167+
create_or_update_github_release "$extension_name" "$extension_version" "$changelog_contents"
168+
done
169+
else
170+
echo "This action can only run on 'master' branch."
171+
exit 0
172+
fi

0 commit comments

Comments
 (0)