termux-packages/scripts/updates/api/termux_github_api_get_tag.sh

136 lines
3.5 KiB
Bash

# shellcheck shell=bash
termux_github_api_get_tag() {
if [[ -z "$1" ]]; then
termux_error_exit <<-EndOfUsage
Usage: ${FUNCNAME[0]} PKG_SRCURL [TAG_TYPE]
Returns the latest tag of the given package.
EndOfUsage
fi
if [[ -z "${GITHUB_TOKEN:-}" ]]; then
# Needed to use graphql API.
termux_error_exit "ERROR: GITHUB_TOKEN environment variable not set."
fi
local PKG_SRCURL="$1"
local TAG_TYPE="${2:-}"
local project
project="$(echo "${PKG_SRCURL}" | cut -d'/' -f4-5)"
project="${project%.git}"
if [[ -z "${TAG_TYPE}" ]]; then # If not set, then decide on the basis of url.
if [[ "${PKG_SRCURL: -4}" == ".git" ]]; then
# Get newest tag.
TAG_TYPE="newest-tag"
else
# Get the latest release tag.
TAG_TYPE="latest-release-tag"
fi
fi
local jq_filter
local api_url="https://api.github.com"
local -a curl_opts=(
--silent
--location
--retry 10
--retry-delay 1
-H "Authorization: token ${GITHUB_TOKEN}"
-H "Accept: application/vnd.github.v3+json"
--write-out '|%{http_code}'
)
if [[ "${TAG_TYPE}" == "newest-tag" ]]; then
api_url="${api_url}/graphql"
jq_filter='.data.repository.refs.edges[0].node.name'
curl_opts+=(-X POST)
curl_opts+=(
-d "$(
cat <<-EOF | tr '\n' ' '
{
"query": "query {
repository(owner: \"${project%/*}\", name: \"${project##*/}\") {
refs(refPrefix: \"refs/tags/\", first: 1, orderBy: {
field: TAG_COMMIT_DATE, direction: DESC
})
{
edges {
node {
name
}
}
}
}
}"
}
EOF
)"
)
elif [[ "${TAG_TYPE}" == "latest-release-tag" ]]; then
api_url="${api_url}/repos/${project}/releases/latest"
jq_filter=".tag_name"
else
termux_error_exit <<-EndOfError
ERROR: Invalid TAG_TYPE: '${TAG_TYPE}'.
Allowed values: 'newest-tag', 'latest-release-tag'.
EndOfError
fi
local response
response="$(curl "${curl_opts[@]}" "${api_url}")"
local http_code
http_code="${response##*|}"
# Why printf "%s\n"? Because echo interpolates control characters, which jq does not like.
response="$(printf "%s\n" "${response%|*}")"
local tag_name
if [[ "${http_code}" == "200" ]]; then
if jq --exit-status --raw-output "${jq_filter}" <<<"${response}" >/dev/null; then
tag_name="$(jq --exit-status --raw-output "${jq_filter}" <<<"${response}")"
else
termux_error_exit "ERROR: Failed to parse tag name from: '${response}'"
fi
elif [[ "${http_code}" == "404" ]]; then
if jq --exit-status "has(\"message\") and .message == \"Not Found\"" <<<"${response}"; then
termux_error_exit <<-EndOfError
ERROR: No '${TAG_TYPE}' found (${api_url}).
Try using '$(
if [ ${TAG_TYPE} = "newest-tag" ]; then
echo "latest-release-tag"
else
echo "newest-tag"
fi
)'.
EndOfError
else
termux_error_exit <<-EndOfError
ERROR: Failed to get '${TAG_TYPE}'(${api_url})'.
Response:
${response}
EndOfError
fi
else
termux_error_exit <<-EndOfError
ERROR: Failed to get '${TAG_TYPE}'(${api_url})'.
HTTP code: ${http_code}
Response:
${response}
EndOfError
fi
# If program control reached here and still no tag_name, then something went wrong.
if [[ -z "${tag_name:-}" ]] || [[ "${tag_name}" == "null" ]]; then
termux_error_exit <<-EndOfError
ERROR: JQ could not find '${TAG_TYPE}'(${api_url})'.
Response:
${response}
Please report this as bug.
EndOfError
fi
echo "${tag_name#v}" # Remove leading 'v' which is common in version tag.
}