151 lines
4.6 KiB
Bash
Executable File
151 lines
4.6 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
|
|
usage() {
|
|
cat <<EOF
|
|
$0 --repo=<owner/repo> --tag=<release tag | @> --file=<artifact path> --token=<github api token>
|
|
|
|
Usage:
|
|
|
|
This script uploads the given artifact to a GitHub release.
|
|
|
|
It takes 4 required options:
|
|
|
|
--repo | The <org>/<repo> combo to upload the artifact to env:\$GITHUB_REPO =${repo:-<unset>}
|
|
--tag | The tag / release name to upload the artifact to env:\$GITHUB_RELEASE =${tag:-<unset>}
|
|
--file | The file path to the artifact to upload env:\$GITHUB_ARTIFACT =${artifact:-<unset>}
|
|
--token | The API token to use when authenticating with GitHub env:\$GITHUB_TOKEN =$([[-n "$token" ]] && printf '<*****>' || printf '<unset>')
|
|
--dry-run | Don't actually upload the artifact env:\$GITHUB_DRYRUN =$([[-n "$dry" ]] && printf 'true' || printf 'false')
|
|
--help | Print this help
|
|
|
|
Each option may also be set via the associated environment variable, with the command line taking precedence.
|
|
|
|
You may optionally force the uploaded artifact to have a different name from the given file, by suffixing --file
|
|
with a ':<name-override>'. For example, '/path/to/artifact_with.dirty+name.tar.gz:artifact.tar.gz' will resolve
|
|
the uploaded artifact's filename to 'artifact.tar.gz'.
|
|
|
|
To select the most recent tag on the remote, you can use the special value '@' when setting --tag.
|
|
|
|
Examples:
|
|
|
|
1. $(basename $0) --tag=v1.0.0 --repo github/octocat --file ./cute-kat.jpg --token=dae3re34...
|
|
|
|
2. GITHUB_TOKEN=4wf4dec... GITHUB_ARTIFACT=/assets/cats.json $(basename $0) --repo=github/octocat --tag=v2.0.0
|
|
|
|
3. $(basename $0) --tag=@ --repo github/octocat --file ./dirty_m3sszy.kitty.tar.xz:kitty.tar.xz --token f43rffe...
|
|
|
|
EOF
|
|
}
|
|
|
|
requires() {
|
|
local t v efails xfails emsg
|
|
for t in "$@"; do
|
|
v=${t#*:}
|
|
|
|
case $t in
|
|
e:*)
|
|
[[ -n "${!v}" ]] || efails+=("$v")
|
|
;;
|
|
x:*|*)
|
|
command -v "${v}" &>/dev/null || xfails+=("$v")
|
|
;;
|
|
esac
|
|
done
|
|
|
|
[[ -n "${efails}" ]] && emsg=$(printf 'Missing required variable(s): %s' "${efails[*]}")
|
|
[[ -n "${xfails}" ]] && emsg=$(printf '%s\nMissing required executable(s): %s' "$emsg" "${xfails[*]}")
|
|
[[ -n "$emsg" ]] && die 3 "$(printf '%s\n[INFO]: Use --help for more information' "$emsg")"
|
|
}
|
|
|
|
cli() {
|
|
local GOPTS=$(getopt -o hd --long help,dry-run,repo:,tag:,file:,token: -n "gh-upload-artifact" -- "$@")
|
|
eval set -- "$GOPTS"
|
|
|
|
while (( $# > 0 )); do
|
|
case "$1" in
|
|
--repo) repo="$2"; shift 2 ;;
|
|
--tag) tag="$2"; shift 2 ;;
|
|
--file) artifact="$2"; shift 2 ;;
|
|
--token) token="$2"; shift 2 ;;
|
|
-h|--help) help=1; shift ;;
|
|
-d|--dry-run) dry=1; shift ;;
|
|
--) shift; break ;;
|
|
*) die 1 "Unknown option: $1" 1 ;;
|
|
esac
|
|
done
|
|
}
|
|
|
|
set_filename() {
|
|
artifact=${1%:*}
|
|
filename=${1##*:}
|
|
[[ -n "$filename" ]] || filename=$(basename $artifact)
|
|
}
|
|
|
|
die() {
|
|
echo "[ERROR]: $2" >&2
|
|
[ -n "$3" ] && usage >&2
|
|
exit $1
|
|
}
|
|
|
|
setup() {
|
|
requires x:getopt x:curl x:jq
|
|
|
|
# Script inputs
|
|
repo=${GITHUB_REPO}
|
|
tag=${GITHUB_RELEASE}
|
|
artifact=${GITHUB_ARTIFACT}
|
|
token=${GITHUB_TOKEN}
|
|
dry=${GITHUB_DRYRUN:+1}
|
|
filename=""
|
|
help=-1
|
|
|
|
cli "$@"
|
|
(( help > 0 )) && usage && exit 0
|
|
|
|
requires e:repo e:tag e:artifact e:token
|
|
|
|
set_filename "$artifact"
|
|
|
|
# Constants
|
|
GH_RESPONSE=$(mktemp)
|
|
GH_AUTH="Authorization: token $token"
|
|
CURL_ARGS="-sSL"
|
|
[[ "$tag" == '@' ]] \
|
|
&& GH_TAG="latest" \
|
|
|| GH_TAG="tags/$tag"
|
|
}
|
|
|
|
main() {
|
|
setup "$@"
|
|
trap 'rm -f $GH_RESPONSE' EXIT
|
|
|
|
# Fetch release JSON blob
|
|
curl "$CURL_ARGS" -o "$GH_RESPONSE" -H "$GH_AUTH" "https://api.github.com/repos/$repo/releases/$GH_TAG"
|
|
(( $? > 0 )) && die 1 "$(cat <(printf "Invalid repo, token or network issue!\n") $GH_RESPONSE)"
|
|
|
|
# Get ID of the asset based on given filename.
|
|
id=$(jq -r '.id' "$GH_RESPONSE")
|
|
(( $? > 0 )) && die 1 "$(cat <(printf "Failed to get release id for tag '%s' from response:\n" "$tag") $GH_RESPONSE)"
|
|
|
|
# Construct url
|
|
upload_uri="https://uploads.github.com/repos/$repo/releases/$id/assets?name=$filename"
|
|
|
|
# Upload artifact
|
|
if [[ -n "$dry" ]]; then
|
|
echo "[INFO]: Would upload $artifact to $upload_uri" >&2
|
|
else
|
|
curl "$CURL_ARGS" \
|
|
-H "$GH_AUTH" \
|
|
-H "Content-Type: $(file -b --mime-type $artifact)" \
|
|
--data-binary @"$artifact" \
|
|
-o "$GH_RESPONSE" \
|
|
$upload_uri
|
|
|
|
(( $? > 0 )) \
|
|
&& die 1 "$(cat <(printf "Failed to upload $filename to $repo:\n") $GH_RESPONSE)" \
|
|
|| jq '.' "$GH_RESPONSE"
|
|
fi
|
|
}
|
|
|
|
[[ -n "$Debug" ]] && set -x
|
|
main "$@"
|