1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
|
#!/usr/bin/env sh
#
# Author: Hsieh Chin Fan (typebrook) <typebrook@gmail.com>
# License: MIT
# https://gist.github.com/typebrook/4947769e266173303d8848f496e272c9
#
# Originally created by stefanbuck
# fork from: https://gist.github.com/stefanbuck/ce788fee19ab6eb0b4447a85fc99f447
#
# --
# This script manages a release note or its asset with GitHub API v3.
# It accepts the following parameters:
#
# * repo
# * tag
# * type (asset or edit)
# * filename
# * github_api_token
# * action (optional, could be upload, overwrite, rename, delete, default to be upload)
# * extra (optional, new filename for action 'rename')
# * create (optional, create a new release if it doesn't exist)
#
# Example:
#
# # Upload a file as asset. If there is a asset with the same filename, then overwrite it.
# github-release.sh github_api_token=TOKEN repo=stefanbuck/playground tag=v0.1.0 type=asset filename=./build.zip overwrite=true
#
# # Edit a release note with file content
# github-release.sh github_api_token=TOKEN repo=stefanbuck/playground tag=v0.1.0 type=edit filename=note
# Check dependencies.
set -e
# Validate settings.
[ "$TRACE" ] && set -x
# Keep tty
exec 3>&1
CONFIG=$@
for line in $CONFIG; do
eval "$line"
done
# Define variables.
GH_API="https://api.github.com"
GH_REPO="$GH_API/repos/$repo"
GH_TAGS="$GH_REPO/releases/tags/$tag"
AUTH="Authorization: token $github_api_token"
if [ "$tag" = 'LATEST' ]; then
GH_TAGS="$GH_REPO/releases/latest"
fi
if [ "$type" = '' ]; then
sed -E -n -e ' /^$/ q; /# --/,$ s/^# *//p' "$0"
exit 0
fi
# Validate token.
curl -o /dev/null -sH "$AUTH" $GH_REPO || { echo "Error: Invalid repo, token or network issue!"; exit 1; }
# Read asset tags.
response=$(curl -sH "$AUTH" $GH_TAGS)
# Get ID of the release.
release_id=$(echo "$response" | grep -m1 -w \"id\": | sed -E -e 's/[^0-9]//g')
if [ -z "$release_id" ]; then
if [ "$create" = 'true' ]; then
body=$(cat <<EOF
{
"tag_name": "$tag",
"target_commitish": "master",
"name": "$tag",
"body": "",
"draft": false,
"prerelease": false
}
EOF
)
response=$(curl -H "$AUTH" -H "Content-Type: application/json" -d "$body" "$GH_REPO/releases")
release_id=$(echo "$response" | grep -m1 -w \"id\": | sed -E -e 's/[^0-9]//g')
else
echo "Error: Failed to get release id for tag: $tag"; echo "$response" | awk 'length($0)<100' >&2
exit 1
fi
fi
post_asset() {
# Upload asset
echo "Uploading asset... " >&3
# Construct url
GH_ASSET="https://uploads.github.com/repos/$repo/releases/$release_id/assets?name=$1"
curl --data-binary @"$filename" -H "$AUTH" -H "Content-Type: application/octet-stream" $GH_ASSET
}
rename_asset() {
echo "Renaming asset($1) from $2 to $3" >&3
curl -X PATCH -H "$AUTH" -H "Content-Type: application/json" \
--data "{\"name\":\"$3\", \"label\":\"$3\"}" "$GH_REPO/releases/assets/$1"
}
delete_asset() {
echo "Deleting asset($1)... " >&3
curl -X "DELETE" -H "$AUTH" "$GH_REPO/releases/assets/$1"
}
upload_asset() {
# Get ID of the asset based on given filename.
# If exists, delete it.
eval $(echo "$response" | grep -C2 "\"name\": \"$(basename $filename)\"" | grep -m 1 "id.:" | grep -w id | tr : = | tr -cd '[[:alnum:]]=' | sed 's/id/asset_id/')
if [ "$asset_id" = "" ]; then
echo "No need to overwrite asset"
post_asset $(basename $filename)
else
if [ "$action" = "overwrite" ]; then
new_asset_id=$(post_asset "bak_$(basename $filename)" | sed -E 's/^\{[^{]+"id":([0-9]+).+$/\1/')
[ "$new_asset_id" = "" ] && exit 1 || delete_asset "$asset_id"
rename_asset "$new_asset_id" "bak_$(basename $filename)" "$(basename $filename)"
elif [ "$action" = "rename" ]; then
rename_asset "$asset_id" "$filename" "$extra"
elif [ "$action" = "delete" ]; then
delete_asset "$asset_id"
exit 0
else
echo "File already exists on tag $tag"
echo "If you want to overwrite it, set action=overwrite"
exit 1
fi
fi
}
edit_release() {
GH_RELEASE="$GH_REPO/releases/$release_id"
body=$(cat <<EOF
{
"tag_name": "$tag",
"target_commitish": "master",
"name": "$tag",
"body": "$(cat $filename | sed 's/"/\\"/g; $! s/$/\\n/' | tr -d '\n')",
"draft": false,
"prerelease": false
}
EOF
)
curl -X PATCH -H "$AUTH" -H "Content-Type: application/json" -d "$body" $GH_RELEASE
}
case $type in
asset) upload_asset;;
edit) edit_release;;
*) echo "type should be 'asset' or 'edit'";;
esac
|