225 lines
6.6 KiB
Bash
Executable File
225 lines
6.6 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
# Usage: scripts/release_gitea.sh <version> [--draft] [--prerelease]
|
|
# Env: liest automatisch $ROOT_DIR/.env (GITEA_TOKEN, GITEA_BASE, OWNER, REPO)
|
|
# Falls nicht gesetzt, werden GITEA_BASE/OWNER/REPO aus der Git-Remote-URL abgeleitet.
|
|
|
|
if [[ $# -lt 1 ]]; then
|
|
echo "Usage: $0 <version> [--draft] [--prerelease]" >&2
|
|
exit 1
|
|
fi
|
|
|
|
VERSION="$1"
|
|
shift || true
|
|
DRAFT=false
|
|
PRERELEASE=false
|
|
for arg in "$@"; do
|
|
case "$arg" in
|
|
--draft) DRAFT=true ;;
|
|
--prerelease) PRERELEASE=true ;;
|
|
esac
|
|
done
|
|
|
|
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")"/.. && pwd)"
|
|
|
|
# Load .env if present
|
|
if [[ -f "$ROOT_DIR/.env" ]]; then
|
|
set -a
|
|
# shellcheck disable=SC1090
|
|
. "$ROOT_DIR/.env"
|
|
set +a
|
|
fi
|
|
|
|
# Map alternative token variable name
|
|
if [[ -z "${GITEA_TOKEN:-}" && -n "${GITEA_API_TOKEN:-}" ]]; then
|
|
GITEA_TOKEN="$GITEA_API_TOKEN"
|
|
fi
|
|
|
|
# Map API URL to base if provided
|
|
if [[ -z "${GITEA_BASE:-}" && -n "${GITEA_API_URL:-}" ]]; then
|
|
# strip trailing /api/... from URL
|
|
GITEA_BASE="${GITEA_API_URL%%/api/*}"
|
|
fi
|
|
|
|
# Map owner/repo alternative names
|
|
if [[ -z "${OWNER:-}" && -n "${GITEA_OWNER:-}" ]]; then
|
|
OWNER="$GITEA_OWNER"
|
|
fi
|
|
if [[ -z "${REPO:-}" && -n "${GITEA_REPO:-}" ]]; then
|
|
REPO="$GITEA_REPO"
|
|
fi
|
|
|
|
# Derive defaults from git remote if not provided
|
|
if [[ -z "${GITEA_BASE:-}" || -z "${OWNER:-}" || -z "${REPO:-}" ]]; then
|
|
ORIGIN_URL=$(git -C "$ROOT_DIR" remote get-url origin 2>/dev/null || true)
|
|
if [[ "$ORIGIN_URL" =~ ^https?://([^/]+)/([^/]+)/([^/]+?)(\.git)?$ ]]; then
|
|
: "${GITEA_BASE:="https://${BASH_REMATCH[1]}"}"
|
|
: "${OWNER:=${BASH_REMATCH[2]}}"
|
|
: "${REPO:=${BASH_REMATCH[3]}}"
|
|
fi
|
|
fi
|
|
|
|
: "${GITEA_TOKEN:?Set GITEA_TOKEN (in .env oder Umgebung)}"
|
|
: "${GITEA_BASE:?Set GITEA_BASE (z. B. https://gitea.elpatron.me)}"
|
|
: "${OWNER:?Set OWNER (z. B. elpatron)}"
|
|
: "${REPO:?Set REPO (z. B. octo-funnel)}"
|
|
DIST_DIR="$ROOT_DIR/octoprint_tailscale_funnel/dist"
|
|
|
|
TAG="v${VERSION}"
|
|
|
|
echo "Creating git tag ${TAG} and pushing..."
|
|
git tag -f "${TAG}"
|
|
git push -f origin "${TAG}"
|
|
|
|
echo "Creating Gitea release ${TAG}..."
|
|
BODY=$(cat <<EOF
|
|
Release ${TAG}
|
|
|
|
Changes:
|
|
- Navbar: Statusanzeige, Toggle, Farbkennung
|
|
- Build-Skript & Quick-Build Docs
|
|
- Version ${VERSION}
|
|
EOF
|
|
)
|
|
|
|
CREATE_PAYLOAD=$(jq -n \
|
|
--arg tag_name "${TAG}" \
|
|
--arg name "${TAG}" \
|
|
--arg body "${BODY}" \
|
|
--argjson draft ${DRAFT} \
|
|
--argjson prerelease ${PRERELEASE} \
|
|
'{tag_name:$tag_name, name:$name, body:$body, draft:$draft, prerelease:$prerelease}')
|
|
|
|
RELEASE_JSON=$(curl -sS -X POST "${GITEA_BASE}/api/v1/repos/${OWNER}/${REPO}/releases" \
|
|
-H "Authorization: token ${GITEA_TOKEN}" \
|
|
-H 'Content-Type: application/json' \
|
|
-d "${CREATE_PAYLOAD}")
|
|
|
|
UPLOAD_URL=$(echo "$RELEASE_JSON" | jq -r .upload_url)
|
|
ID=$(echo "$RELEASE_JSON" | jq -r .id)
|
|
|
|
if [[ -z "$ID" || "$ID" == "null" ]]; then
|
|
echo "Failed to create release: $RELEASE_JSON" >&2
|
|
exit 1
|
|
fi
|
|
|
|
echo "Release created: ID=$ID"
|
|
echo "Using: GITEA_BASE=$GITEA_BASE OWNER=$OWNER REPO=$REPO"
|
|
|
|
function upload_asset() {
|
|
local file="$1"
|
|
local name
|
|
name=$(basename "$file")
|
|
echo "Uploading asset: $name"
|
|
curl -sS -X POST "${GITEA_BASE}/api/v1/repos/${OWNER}/${REPO}/releases/${ID}/assets?name=${name}" \
|
|
-H "Authorization: token ${GITEA_TOKEN}" \
|
|
-H 'Content-Type: application/octet-stream' \
|
|
--data-binary @"$file" > /dev/null
|
|
}
|
|
|
|
upload_asset "$DIST_DIR/octoprint_tailscale_funnel-${VERSION}-py3-none-any.whl"
|
|
upload_asset "$DIST_DIR/octoprint_tailscale_funnel-${VERSION}.tar.gz"
|
|
upload_asset "$DIST_DIR/octoprint_tailscale_funnel-${VERSION}.zip"
|
|
|
|
echo "Release ${TAG} created and assets uploaded."
|
|
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
# Load .env if present
|
|
if [ -f "$(dirname "$0")/../.env" ]; then
|
|
set -a
|
|
# shellcheck disable=SC1091
|
|
. "$(dirname "$0")/../.env"
|
|
set +a
|
|
fi
|
|
|
|
API_URL=${GITEA_API_URL:-"https://gitea.elpatron.me/api/v1"}
|
|
OWNER=${GITEA_OWNER:-"elpatron"}
|
|
REPO=${GITEA_REPO:-"octo-funnel"}
|
|
TOKEN=${GITEA_API_TOKEN:-""}
|
|
|
|
TAG=""
|
|
NAME=""
|
|
ASSET_PATH=""
|
|
BODY_FILE=""
|
|
|
|
usage() {
|
|
echo "Usage: $0 -t <tag> -a <asset-zip> [-n <name>] [-b <body-file>]" >&2
|
|
}
|
|
|
|
while getopts ":t:a:n:b:" opt; do
|
|
case $opt in
|
|
t) TAG="$OPTARG" ;;
|
|
a) ASSET_PATH="$OPTARG" ;;
|
|
n) NAME="$OPTARG" ;;
|
|
b) BODY_FILE="$OPTARG" ;;
|
|
*) usage; exit 2 ;;
|
|
esac
|
|
done
|
|
|
|
if [ -z "$TAG" ] || [ -z "$ASSET_PATH" ]; then
|
|
usage; exit 2
|
|
fi
|
|
if [ -z "$NAME" ]; then NAME="$TAG"; fi
|
|
if [ ! -f "$ASSET_PATH" ]; then
|
|
echo "Asset not found: $ASSET_PATH" >&2; exit 1
|
|
fi
|
|
if [ -z "$TOKEN" ]; then
|
|
echo "GITEA_API_TOKEN not set (in .env)." >&2; exit 1
|
|
fi
|
|
|
|
# Derive asset name early for later use
|
|
ASSET_NAME="$(basename "$ASSET_PATH")"
|
|
|
|
BODY="Tailscale Funnel Plugin ${TAG}\n\nAutomated release."
|
|
if [ -n "$BODY_FILE" ] && [ -f "$BODY_FILE" ]; then
|
|
BODY=$(cat "$BODY_FILE")
|
|
fi
|
|
|
|
# Try to fetch existing release by tag first
|
|
get_resp=$(curl -sS -H "Authorization: token ${TOKEN}" "${API_URL}/repos/${OWNER}/${REPO}/releases/tags/${TAG}" || true)
|
|
rel_id=$(echo "$get_resp" | jq -r '.id // empty')
|
|
|
|
if [ -z "$rel_id" ]; then
|
|
# Build minimal JSON payload (use existing tag)
|
|
create_payload=$(jq -n --arg tag "$TAG" --arg name "$NAME" --arg body "$BODY" '{tag_name:$tag, name:$name, body:$body, draft:false, prerelease:false}')
|
|
|
|
create_resp=$(curl -sS -X POST \
|
|
-H 'Content-Type: application/json' \
|
|
-H "Authorization: token ${TOKEN}" \
|
|
-d "$create_payload" \
|
|
"${API_URL}/repos/${OWNER}/${REPO}/releases" || true)
|
|
|
|
# Extract id from create response
|
|
rel_id=$(echo "$create_resp" | jq -r '.id // empty')
|
|
fi
|
|
|
|
# Fallback: search releases list for matching tag if still empty
|
|
if [ -z "$rel_id" ]; then
|
|
list_resp=$(curl -sS -H "Authorization: token ${TOKEN}" "${API_URL}/repos/${OWNER}/${REPO}/releases?limit=100")
|
|
rel_id=$(echo "$list_resp" | jq -r --arg tag "$TAG" '[.[] | select(.tag_name==$tag)][0].id // empty')
|
|
fi
|
|
|
|
if [ -z "$rel_id" ]; then
|
|
echo "Failed to get create/fetch release id" >&2
|
|
echo "$create_resp" | head -c 400 >&2
|
|
exit 1
|
|
fi
|
|
|
|
# Check if asset exists (skip upload if present)
|
|
assets_json=$(curl -sS -H "Authorization: token ${TOKEN}" "${API_URL}/repos/${OWNER}/${REPO}/releases/${rel_id}/assets")
|
|
asset_exists=$(echo "$assets_json" | jq -r --arg name "$ASSET_NAME" 'any(.[]; .name==$name)')
|
|
|
|
if [ "$asset_exists" = "true" ]; then
|
|
echo "Asset already exists, skipping upload: ${ASSET_NAME}"
|
|
else
|
|
echo "Uploading asset: ${ASSET_NAME}"
|
|
upload_resp=$(curl -sS -H "Authorization: token ${TOKEN}" -F attachment=@"${ASSET_PATH}" "${API_URL}/repos/${OWNER}/${REPO}/releases/${rel_id}/assets?name=${ASSET_NAME}")
|
|
html_url=$(echo "$upload_resp" | jq -r '.browser_download_url // empty')
|
|
echo "Asset uploaded: ${html_url}"
|
|
fi
|
|
|
|
echo "Release ${TAG} ready (id=${rel_id})."
|
|
|