168 lines
4.5 KiB
Bash
Executable File
168 lines
4.5 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
require_env() {
|
|
local name="$1"
|
|
if [ -z "${!name:-}" ]; then
|
|
echo "missing required environment variable: ${name}" >&2
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
require_env GITEA_SERVER_URL
|
|
require_env GITEA_REPOSITORY
|
|
require_env GITEA_TOKEN
|
|
require_env RELEASE_TAG
|
|
require_env RELEASE_NAME
|
|
require_env RELEASE_VERSION
|
|
require_env RELEASE_TARGET
|
|
|
|
server="${GITEA_SERVER_URL%/}"
|
|
repo="${GITEA_REPOSITORY}"
|
|
tag="${RELEASE_TAG}"
|
|
name="${RELEASE_NAME}"
|
|
version="${RELEASE_VERSION}"
|
|
target="${RELEASE_TARGET}"
|
|
draft="${RELEASE_DRAFT:-false}"
|
|
prerelease="${RELEASE_PRERELEASE:-false}"
|
|
notes_file="${RELEASE_BODY_FILE:-}"
|
|
|
|
if [ -z "${notes_file}" ]; then
|
|
echo "missing required environment variable: RELEASE_BODY_FILE" >&2
|
|
exit 1
|
|
fi
|
|
if [ ! -f "${notes_file}" ]; then
|
|
echo "release body file does not exist: ${notes_file}" >&2
|
|
exit 1
|
|
fi
|
|
body="$(cat "${notes_file}")"
|
|
|
|
asset_name_for() {
|
|
local family="$1"
|
|
local file="$2"
|
|
local base_name
|
|
base_name="$(basename "${file}")"
|
|
|
|
if [ "${base_name}" = "SHA256SUMS.txt" ]; then
|
|
printf '%s-SHA256SUMS.txt' "${family}"
|
|
else
|
|
printf '%s' "${base_name}"
|
|
fi
|
|
}
|
|
|
|
release_dir="dist/release/v${version}"
|
|
docker_dir="dist/docker/v${version}"
|
|
|
|
declare -a asset_files=()
|
|
declare -a asset_names=()
|
|
|
|
if [ -d "${release_dir}" ]; then
|
|
while IFS= read -r -d '' file; do
|
|
asset_files+=("${file}")
|
|
asset_names+=("$(asset_name_for release "${file}")")
|
|
done < <(find "${release_dir}" -maxdepth 1 -type f -print0 | sort -z)
|
|
fi
|
|
|
|
if [ -d "${docker_dir}" ]; then
|
|
while IFS= read -r -d '' file; do
|
|
asset_files+=("${file}")
|
|
asset_names+=("$(asset_name_for docker "${file}")")
|
|
done < <(find "${docker_dir}" -maxdepth 1 -type f -print0 | sort -z)
|
|
fi
|
|
|
|
if [ "${#asset_files[@]}" -eq 0 ]; then
|
|
echo "no release assets found under ${release_dir} or ${docker_dir}" >&2
|
|
exit 1
|
|
fi
|
|
|
|
api_base="${server}/api/v1/repos/${repo}"
|
|
auth_header="Authorization: token ${GITEA_TOKEN}"
|
|
accept_header="Accept: application/json"
|
|
curl_args=(-sS)
|
|
|
|
if [ "${GITEA_CURL_INSECURE:-false}" = "true" ]; then
|
|
curl_args+=(-k)
|
|
fi
|
|
|
|
release_lookup="$(mktemp)"
|
|
release_payload="$(mktemp)"
|
|
trap 'rm -f "${release_lookup}" "${release_payload}"' EXIT
|
|
|
|
lookup_status="$(
|
|
curl "${curl_args[@]}" -o "${release_lookup}" -w '%{http_code}' \
|
|
-H "${auth_header}" \
|
|
-H "${accept_header}" \
|
|
"${api_base}/releases/tags/${tag}"
|
|
)"
|
|
|
|
printf '%s' "${body}" | jq -Rs \
|
|
--arg tag "${tag}" \
|
|
--arg name "${name}" \
|
|
--arg target "${target}" \
|
|
--argjson draft "${draft}" \
|
|
--argjson prerelease "${prerelease}" \
|
|
'{tag_name:$tag,name:$name,target_commitish:$target,body:.,draft:$draft,prerelease:$prerelease}' \
|
|
> "${release_payload}"
|
|
|
|
if [ "${lookup_status}" = "200" ]; then
|
|
release_id="$(jq -r '.id' "${release_lookup}")"
|
|
curl -f "${curl_args[@]}" \
|
|
-X PATCH \
|
|
-H "${auth_header}" \
|
|
-H "${accept_header}" \
|
|
-H 'Content-Type: application/json' \
|
|
--data @"${release_payload}" \
|
|
"${api_base}/releases/${release_id}" \
|
|
> "${release_lookup}"
|
|
elif [ "${lookup_status}" = "404" ]; then
|
|
curl -f "${curl_args[@]}" \
|
|
-X POST \
|
|
-H "${auth_header}" \
|
|
-H "${accept_header}" \
|
|
-H 'Content-Type: application/json' \
|
|
--data @"${release_payload}" \
|
|
"${api_base}/releases" \
|
|
> "${release_lookup}"
|
|
release_id="$(jq -r '.id' "${release_lookup}")"
|
|
else
|
|
echo "failed to look up release ${tag}: Gitea returned HTTP ${lookup_status}" >&2
|
|
cat "${release_lookup}" >&2
|
|
exit 1
|
|
fi
|
|
|
|
release_id="${release_id:-$(jq -r '.id' "${release_lookup}")}"
|
|
|
|
for index in "${!asset_files[@]}"; do
|
|
file="${asset_files[${index}]}"
|
|
asset_name="${asset_names[${index}]}"
|
|
existing_asset_id="$(
|
|
jq -r --arg name "${asset_name}" '.assets[]? | select(.name == $name) | .id' "${release_lookup}" \
|
|
| head -n 1
|
|
)"
|
|
|
|
if [ -n "${existing_asset_id}" ] && [ "${existing_asset_id}" != "null" ]; then
|
|
curl -f "${curl_args[@]}" \
|
|
-X DELETE \
|
|
-H "${auth_header}" \
|
|
-H "${accept_header}" \
|
|
"${api_base}/releases/${release_id}/assets/${existing_asset_id}" \
|
|
>/dev/null
|
|
fi
|
|
|
|
encoded_name="$(python3 -c 'import sys, urllib.parse; print(urllib.parse.quote(sys.argv[1]))' "${asset_name}")"
|
|
|
|
curl -f "${curl_args[@]}" \
|
|
-X POST \
|
|
-H "${auth_header}" \
|
|
-H "${accept_header}" \
|
|
-F "attachment=@${file}" \
|
|
"${api_base}/releases/${release_id}/assets?name=${encoded_name}" \
|
|
>/dev/null
|
|
done
|
|
|
|
release_url="$(jq -r '.html_url // empty' "${release_lookup}")"
|
|
echo "Published release ${name} (${tag})"
|
|
if [ -n "${release_url}" ]; then
|
|
echo "Release URL: ${release_url}"
|
|
fi
|