name: Test Skins on: push: pull_request: jobs: link-check: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Validate links and assets shell: bash run: | set -uo pipefail RED="\033[31m" GREEN="\033[32m" RESET="\033[0m" ERRORS=() ############################################################ # FIXED: SAFE URL DECODER (no null bytes!) ############################################################ urldecode() { local url="$1" url="${url//+/ }" # Perl decoding avoids raw NUL bytes and handles unicode correctly printf '%s' "$url" | perl -pe 's/%([A-Fa-f0-9]{2})/chr(hex($1))/eg' } ############################################################ # FIXED: Gitea "soft 404" detection (HTML body says 404) ############################################################ check_http() { local url="$1" echo " → Checking external: $url" # HEAD local status status=$(curl -Is --max-time 10 "$url" | head -n1 | awk '{print $2}') if [[ "$status" =~ ^2|3 ]]; then local body body=$(curl -Ls --max-time 10 "$url") if echo "$body" | grep -qiE "404 Not Found|Path .* doesn't exist|File not found|does not exist|Not Found"; then return 1 fi return 0 fi # GET fallback status=$(curl -Is --max-time 10 -X GET "$url" | head -n1 | awk '{print $2}') if [[ "$status" =~ ^2|3 ]]; then local body body=$(curl -Ls --max-time 10 "$url") if echo "$body" | grep -qiE "404 Not Found|Path .* doesn't exist|File not found|does not exist|Not Found"; then return 1 fi return 0 fi return 1 } ############################################################ # Local file existence check ############################################################ check_local() { local path="$1" path="${path#/}" local decoded decoded=$(urldecode "$path") echo " → Checking local: $decoded" if [[ ! -e "$decoded" ]]; then return 1 fi return 0 } ############################################################ # Extract *all* link types from a Markdown file ############################################################ extract_links() { local f="$1" # Markdown links grep -oE '\[[^]]*\]\([^)]*\)' "$f" \ | sed -E 's/.*\((.*)\).*/\1/' # Markdown images grep -oE '!\[[^]]*\]\([^)]*\)' "$f" \ | sed -E 's/.*\((.*)\).*/\1/' # Raw URLs grep -oE 'https?://[^ )"]+' "$f" # grep -oE ']*src="[^"]+"' "$f" \ | sed -E 's/.*src="([^"]*)".*/\1/' #