#!/usr/bin/env bash # Download myoffice-publish.tar.gz from a Gitea release into API_DIR. # Env: # GITEA_URL, GITEA_OWNER, GITEA_REPO, RELEASE_TAG (latest|v1.2.3) # API_DIR (default /opt/myoffice/api) # RELEASE_ASSET_URL — optional direct override (skips API resolve) # GITEA_TOKEN — optional for private release downloads set -euo pipefail API_DIR="${API_DIR:-/opt/myoffice/api}" GITEA_URL="${GITEA_URL:-}" GITEA_OWNER="${GITEA_OWNER:-}" GITEA_REPO="${GITEA_REPO:-myoffice_public}" RELEASE_TAG="${RELEASE_TAG:-latest}" RELEASE_ASSET_URL="${RELEASE_ASSET_URL:-}" ASSET_NAME="${ASSET_NAME:-myoffice-publish.tar.gz}" GITEA_TOKEN="${GITEA_TOKEN:-}" msg() { echo -e " ==> $*"; } curl_auth() { if [[ -n "$GITEA_TOKEN" ]]; then curl -fsSL -H "Authorization: token ${GITEA_TOKEN}" "$@" else curl -fsSL "$@" fi } json_first_string() { # Extract first "key":"value" for key=$1 from JSON on stdin (no jq/python required). local key="$1" tr -d '\n' | sed -n "s/.*\"${key}\"[[:space:]]*:[[:space:]]*\"\([^\"]*\)\".*/\1/p" | head -1 } resolve_asset_url() { if [[ -n "$RELEASE_ASSET_URL" ]]; then echo "$RELEASE_ASSET_URL" return 0 fi if [[ -z "$GITEA_URL" || -z "$GITEA_OWNER" ]]; then echo "Set GITEA_URL + GITEA_OWNER (and GITEA_REPO), or RELEASE_ASSET_URL." >&2 exit 1 fi local base api_json tag browser_url base="${GITEA_URL%/}" if [[ "$RELEASE_TAG" == "latest" ]]; then api_json=$(curl_auth "${base}/api/v1/repos/${GITEA_OWNER}/${GITEA_REPO}/releases/latest") tag=$(printf '%s' "$api_json" | json_first_string tag_name) if [[ -z "$tag" ]]; then echo "Could not resolve latest release tag from Gitea API." >&2 exit 1 fi else tag="$RELEASE_TAG" api_json=$(curl_auth "${base}/api/v1/repos/${GITEA_OWNER}/${GITEA_REPO}/releases/tags/${tag}" || true) fi # Prefer browser_download_url that ends with the asset name browser_url=$(printf '%s' "${api_json:-}" | tr '"' '\n' | grep -F "/${ASSET_NAME}" | grep -E '^https?://' | head -1 || true) if [[ -z "$browser_url" ]]; then browser_url="${base}/${GITEA_OWNER}/${GITEA_REPO}/releases/download/${tag}/${ASSET_NAME}" fi echo "$browser_url" } download_and_extract() { local url tar_path staging url=$(resolve_asset_url) msg "Downloading release asset: $url" mkdir -p "$API_DIR" tar_path="/tmp/${ASSET_NAME}" curl_auth -o "$tar_path" "$url" staging=$(mktemp -d /tmp/myoffice-extract.XXXXXX) tar -xzf "$tar_path" -C "$staging" rm -f "$tar_path" local prod="${API_DIR}/appsettings.Production.json" local shared_prod="${API_DIR}/appsettings.shared.Production.json" local prod_bak="" shared_bak="" if [[ -f "$prod" ]]; then prod_bak=$(mktemp) cp -a "$prod" "$prod_bak" fi if [[ -f "$shared_prod" ]]; then shared_bak=$(mktemp) cp -a "$shared_prod" "$shared_bak" fi local top_count top_dir top_count=$(find "$staging" -mindepth 1 -maxdepth 1 | wc -l) top_dir="" if [[ "$top_count" -eq 1 ]]; then local only only=$(find "$staging" -mindepth 1 -maxdepth 1 | head -1) if [[ -d "$only" ]]; then top_dir="$only" fi fi find "$API_DIR" -mindepth 1 -maxdepth 1 \ ! -name 'appsettings.Production.json' \ ! -name 'appsettings.shared.Production.json' \ -exec rm -rf {} + if [[ -n "$top_dir" ]]; then cp -a "$top_dir"/. "$API_DIR"/ else cp -a "$staging"/. "$API_DIR"/ fi rm -rf "$staging" rm -f "$API_DIR/appsettings.Production.json" "$API_DIR/appsettings.shared.Production.json" 2>/dev/null || true if [[ -n "$prod_bak" ]]; then mv "$prod_bak" "$prod" fi if [[ -n "$shared_bak" ]]; then mv "$shared_bak" "$shared_prod" fi if [[ ! -f "${API_DIR}/MyOffice.Web.dll" ]]; then echo "Extracted archive but MyOffice.Web.dll is missing in ${API_DIR}" >&2 exit 1 fi msg "App extracted to ${API_DIR}" } if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then download_and_extract fi