From ef69aa469d17f92a6a2cd6e4a7aeaccc5b8c238e Mon Sep 17 00:00:00 2001 From: nfel Date: Thu, 6 Aug 2026 17:03:37 +0330 Subject: [PATCH] ci(stage): add setup-mirrors action (fixes build error) --- .gitea/actions/setup-mirrors/action.yml | 151 ++++++++++++++++++++++++ 1 file changed, 151 insertions(+) create mode 100644 .gitea/actions/setup-mirrors/action.yml diff --git a/.gitea/actions/setup-mirrors/action.yml b/.gitea/actions/setup-mirrors/action.yml new file mode 100644 index 0000000..7d2d0bd --- /dev/null +++ b/.gitea/actions/setup-mirrors/action.yml @@ -0,0 +1,151 @@ +name: Setup package mirrors +description: Benchmark package mirrors and export the fastest reachable registry for each ecosystem +inputs: + npm_mirrors: + description: Newline-separated npm-compatible registries + required: false + default: | + https://npm.reg.darano.ir/ + pypi_mirrors: + required: false + default: | + https://package-mirror.liara.ir/repository/pypi/simple + https://pypi.reg.darano.ir + https://pypi-iran.ir/simple/ + https://pypi.org/simple/ + go_mirrors: + description: Newline-separated Go module proxies + required: false + default: | + https://go.devneeds.ir/ + https://package-mirror.liara.ir/repository/go/ + https://go.reg.darano.ir/ + https://proxy.golang.org/ + debian_mirrors: + description: Newline-separated Debian package repository base URLs + required: false + default: | + http://repo.iut.ac.ir/debian/ + http://deb.debian.org/debian/ + connect_timeout: + description: curl connection timeout in seconds + required: false + default: "3" + max_time: + description: curl request timeout in seconds + required: false + default: "10" +outputs: + npm_registry: + description: Fastest reachable npm registry + value: ${{ steps.select.outputs.npm_registry }} + pypi_index: + description: Fastest reachable Python package index + value: ${{ steps.select.outputs.pypi_index }} + go_proxy: + description: Fastest reachable Go module proxy + value: ${{ steps.select.outputs.go_proxy }} + debian_mirror: + description: Fastest reachable Debian package repository + value: ${{ steps.select.outputs.debian_mirror }} +runs: + using: composite + steps: + - name: Rate mirrors and export package environments + id: select + shell: bash + env: + NPM_MIRRORS: ${{ inputs.npm_mirrors }} + PYPI_MIRRORS: ${{ inputs.pypi_mirrors }} + GO_MIRRORS: ${{ inputs.go_mirrors }} + DEBIAN_MIRRORS: ${{ inputs.debian_mirrors }} + CONNECT_TIMEOUT: ${{ inputs.connect_timeout }} + MAX_TIME: ${{ inputs.max_time }} + run: | + set -euo pipefail + + if [[ ! "$CONNECT_TIMEOUT" =~ ^[0-9]+([.][0-9]+)?$ ]] || + [[ ! "$MAX_TIME" =~ ^[0-9]+([.][0-9]+)?$ ]]; then + echo "Mirror timeouts must be positive numbers" >&2 + exit 1 + fi + + select_fastest() { + local ecosystem="$1" + local mirrors="$2" + local scores mirror result status duration fallback + scores="$(mktemp)" + fallback="" + + while IFS= read -r mirror; do + mirror="$(printf '%s' "$mirror" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')" + [[ -z "$mirror" || "$mirror" == \#* ]] && continue + + if [[ ! "$mirror" =~ ^https?:// ]]; then + echo "[$ecosystem] skipped invalid URL: $mirror" >&2 + continue + fi + [[ -z "$fallback" ]] && fallback="$mirror" + + if result="$(curl \ + --location \ + --silent \ + --show-error \ + --output /dev/null \ + --connect-timeout "$CONNECT_TIMEOUT" \ + --max-time "$MAX_TIME" \ + --write-out '%{http_code} %{time_total}' \ + "$mirror" 2>/dev/null)"; then + read -r status duration <<< "$result" + if [[ "$status" =~ ^[0-9]{3}$ ]] && + (((10#$status >= 200 && 10#$status < 400) || 10#$status == 404)) && + [[ "$duration" =~ ^[0-9]+([.][0-9]+)?$ ]]; then + printf '%s\t%s\t%s\n' "$duration" "$status" "$mirror" >> "$scores" + continue + fi + fi + + echo "[$ecosystem] unavailable: $mirror" >&2 + done <<< "$mirrors" + + if [[ ! -s "$scores" ]]; then + rm -f "$scores" + if [[ -z "$fallback" ]]; then + echo "No valid $ecosystem mirror was configured" >&2 + return 1 + fi + echo "[$ecosystem] no mirror responded; falling back to $fallback" >&2 + printf '%s\n' "$fallback" + return 0 + fi + + echo "[$ecosystem] mirror ranking (seconds, HTTP status, URL):" >&2 + sort -n -k1,1 "$scores" >&2 + sort -n -k1,1 "$scores" | head -n 1 | cut -f3- + rm -f "$scores" + } + + npm_registry="$(select_fastest npm "$NPM_MIRRORS")" + pypi_index="$(select_fastest pypi "$PYPI_MIRRORS")" + go_proxy="$(select_fastest go "$GO_MIRRORS")" + debian_mirror="$(select_fastest debian "$DEBIAN_MIRRORS")" + + { + echo "NPM_CONFIG_REGISTRY=$npm_registry" + echo "npm_config_registry=$npm_registry" + echo "COREPACK_NPM_REGISTRY=$npm_registry" + echo "YARN_REGISTRY=$npm_registry" + echo "PNPM_CONFIG_REGISTRY=$npm_registry" + echo "BUN_CONFIG_REGISTRY=$npm_registry" + echo "PIP_INDEX_URL=$pypi_index" + echo "UV_DEFAULT_INDEX=$pypi_index" + echo "GOPROXY=$go_proxy" + echo "DEBIAN_MIRROR=$debian_mirror" + } >> "$GITHUB_ENV" + + { + echo "npm_registry=$npm_registry" + echo "pypi_index=$pypi_index" + echo "go_proxy=$go_proxy" + echo "debian_mirror=$debian_mirror" + } >> "$GITHUB_OUTPUT"