ci(stage): add setup-mirrors action (fixes build error)
CI/CD Stage / stage (push) Failing after 40s
CI/CD Stage / stage (push) Failing after 40s
This commit is contained in:
@@ -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"
|
||||||
Reference in New Issue
Block a user