Files
Skins/.gitea/workflows/test-skins.yml
Arlind 92a640bad8
Some checks failed
Generate Skin previews, OSK files and per skin documentation / Full CI/CD Pipeline (push) Successful in 28s
Test Skins / link-check (push) Has been cancelled
Update .gitea/workflows/test-skins.yml
2025-11-23 13:18:31 +01:00

148 lines
4.9 KiB
YAML

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=()
############################################################
# Safe unicode URL decode (never produces NULL bytes)
############################################################
urldecode() {
local url="$1"
url="${url//+/ }"
printf '%s' "$url" | perl -pe 's/%([A-Fa-f0-9]{2})/chr(hex($1))/eg'
}
############################################################
# Detect Gitea "soft 404" even when HTTP=200 OK
############################################################
check_http() {
local url="$1"
echo " → Checking external: $url"
local status body
status=$(curl -Is --max-time 10 "$url" | head -n1 | awk '{print $2}')
if [[ "$status" =~ ^2|3 ]]; then
body=$(curl -Ls --max-time 10 "$url")
if echo "$body" | grep -qiE "404 Not Found|doesn't exist|File not found|Not Found"; then
return 1
fi
return 0
fi
status=$(curl -Is --max-time 10 -X GET "$url" | head -n1 | awk '{print $2}')
if [[ "$status" =~ ^2|3 ]]; then
body=$(curl -Ls --max-time 10 "$url")
if echo "$body" | grep -qiE "404 Not Found|doesn't exist|File not found|Not Found"; then
return 1
fi
return 0
fi
return 1
}
############################################################
# Local file check
############################################################
check_local() {
local path="$1"
path="${path#/}" # strip leading slash
local decoded
decoded=$(urldecode "$path")
echo " → Checking local: $decoded"
[[ -e "$decoded" ]]
}
############################################################
# Extract links from markdown + HTML
############################################################
extract_links() {
local f="$1"
grep -oE '\[[^]]*\]\([^)]*\)' "$f" \
| sed -E 's/.*\((.*)\).*/\1/'
grep -oE '!\[[^]]*\]\([^)]*\)' "$f" \
| sed -E 's/.*\((.*)\).*/\1/'
grep -oE 'https?://[^ )"]+' "$f"
grep -oE '<img[^>]*src="[^"]+"' "$f" \
| sed -E 's/.*src="([^"]*)".*/\1/'
grep -oE '<video[^>]*src="[^"]+"' "$f" \
| sed -E 's/.*src="([^"]*)".*/\1/'
}
echo "🔍 Scanning Markdown files..."
echo
############################################################
# Process all markdown files
############################################################
find . -type f -name '*.md' | while IFS= read -r mdfile; do
echo "📄 Checking: $mdfile"
while IFS= read -r url; do
[[ -z "$url" ]] && continue
[[ "$url" == mailto:* ]] && continue
# Skip versioned docs tag links
if [[ "$mdfile" == ./docs/* ]] && [[ "$url" == *"/src/tag/"* ]]; then
continue
fi
# External links
if [[ "$url" == http* ]]; then
if ! check_http "$url"; then
ERRORS+=("❌ Broken external link: $url (in $mdfile)")
fi
else
# Local links
if ! check_local "$url"; then
ERRORS+=("❌ Missing local file: $url (in $mdfile)")
fi
fi
# 🌟 FULL FIX: sanitize extract_links output BEFORE loop
done < <(extract_links "$mdfile" | tr -d '\000' | tr -d '\r' | sed 's/[[:cntrl:]]//g')
echo
done
############################################################
# Final report
############################################################
echo
if (( ${#ERRORS[@]} > 0 )); then
echo -e "${RED}✖ Errors found:${RESET}"
printf "%s\n" "${ERRORS[@]}"
echo
echo -e "${RED}❌ Failing job because broken links were found.${RESET}"
exit 1
else
echo -e "${GREEN}✔ All links OK!${RESET}"
fi