#!/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