From 988f3a768be66dd922877dd058226cdba7180c07 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A1lm=C3=A1n=20=E2=80=9EKAMI=E2=80=9D=20Szalai?= Date: Tue, 18 Aug 2026 12:47:31 +0200 Subject: [PATCH] Add weekly channel health trend report and per-PR link checker Weekly trend workflow: runs the full iptv-checker weekly, keeps a snapshot of failed URLs in .github/checker-history/failed.txt, and reports newly-broken vs newly-recovered channels since the last run in the job summary. PR check workflow: on any PR touching lists/*.md, extracts only the added/changed stream links from the diff and checks just those (not the whole 2000+ channel playlist), reporting online/failed results directly in the PR's Checks summary. --- .github/workflows/pr_check.yml | 90 ++++++++++++++++++++++++++++++ .github/workflows/weekly_trend.yml | 86 ++++++++++++++++++++++++++++ 2 files changed, 176 insertions(+) create mode 100644 .github/workflows/pr_check.yml create mode 100644 .github/workflows/weekly_trend.yml diff --git a/.github/workflows/pr_check.yml b/.github/workflows/pr_check.yml new file mode 100644 index 0000000..62e51bf --- /dev/null +++ b/.github/workflows/pr_check.yml @@ -0,0 +1,90 @@ +name: Check channels changed in PR + +on: + pull_request: + paths: + - 'lists/**.md' + +jobs: + check-pr-channels: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v6 + with: + fetch-depth: 0 + + - name: Setup Node + uses: actions/setup-node@v6 + with: + node-version: "20.10.x" + + - name: Extract added/changed channel links from the PR diff + run: | + git fetch origin "${{ github.event.pull_request.base.sha }}" --depth=1 || true + python3 - "${{ github.event.pull_request.base.sha }}" <<'PYEOF' + import re, subprocess, sys + + base = sys.argv[1] + diff = subprocess.run( + ["git", "diff", "--unified=0", base, "HEAD", "--", "lists/*.md"], + capture_output=True, text=True + ).stdout + + rows = [] + for line in diff.splitlines(): + if not line.startswith('+') or line.startswith('+++'): + continue + content = line[1:] + m = re.search(r'\|\s*([^|]+?)\s*\|\s*\[(?:>|x)\]\(([^)]*)\)', content) + if m: + name = m.group(1).strip() or "Unnamed channel" + url = m.group(2).strip() + if url.startswith('http'): + rows.append((name, url)) + + with open('pr_test.m3u8', 'w') as f: + f.write('#EXTM3U\n') + for name, url in rows: + f.write(f'#EXTINF:-1,{name}\n{url}\n') + + print(f'Found {len(rows)} channel link(s) added or changed in this PR.') + PYEOF + + - name: Check the PR's changed links + if: success() + run: | + if [ ! -s pr_test.m3u8 ] || [ "$(grep -c '^#EXTINF' pr_test.m3u8 || true)" = "0" ]; then + { + echo "## PR channel check" + echo "" + echo "No new or modified stream links (\`[>](...)\` / \`[x](...)\`) were found in this PR's diff — nothing to check." + } >> "$GITHUB_STEP_SUMMARY" + exit 0 + fi + + npm install -g iptv-checker || true + sudo apt-get update && sudo apt-get install -y ffmpeg + mkdir -p pr_output + iptv-checker -o pr_output -p 20 -t 20000 -r 1 ./pr_test.m3u8 || true + + total=$(grep -c '^#EXTINF' pr_test.m3u8 || echo 0) + online=$(grep -c '^#EXTINF' pr_output/online.m3u 2>/dev/null || echo 0) + failed=$(grep -c '^#EXTINF' pr_output/failed.m3u 2>/dev/null || echo 0) + + { + echo "## PR channel check" + echo "" + echo "Checked $total link(s) added or changed by this PR:" + echo "- ✅ Online: $online" + echo "- ❌ Failed: $failed" + if [ "$failed" -gt 0 ]; then + echo "" + echo "### Failed links" + echo '```' + grep '^#EXTINF\|^http' pr_output/failed.m3u + echo '```' + echo "" + echo "_A failed check here doesn't automatically mean the PR is wrong — some channels are geo-blocked and only work from within their own country, which this CI runner isn't. Use your judgment._" + fi + } >> "$GITHUB_STEP_SUMMARY" diff --git a/.github/workflows/weekly_trend.yml b/.github/workflows/weekly_trend.yml new file mode 100644 index 0000000..d8c7847 --- /dev/null +++ b/.github/workflows/weekly_trend.yml @@ -0,0 +1,86 @@ +name: Weekly channel health trend + +on: + schedule: + - cron: '0 6 * * 1' # every Monday 06:00 UTC + workflow_dispatch: + +jobs: + trend: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v6 + + - name: Setup Node + uses: actions/setup-node@v6 + with: + node-version: "20.10.x" + + - name: Install IPTV Checker + run: | + npm install -g iptv-checker || true + sudo apt-get update && sudo apt-get install -y ffmpeg + + - name: Run checker against the full playlist + run: | + mkdir -p output + iptv-checker -o output -p 100 -t 120000 ./playlist.m3u8 || true + + - name: Compare against last week's snapshot and update it + run: | + mkdir -p .github/checker-history + today=$(date -u +%Y-%m-%d) + prev_file=".github/checker-history/failed.txt" + curr_file=".github/checker-history/failed-current.txt" + + grep '^http' output/failed.m3u 2>/dev/null | sort -u > "$curr_file" || touch "$curr_file" + + online=$(grep -c '^#EXTINF' output/online.m3u 2>/dev/null || echo 0) + failed=$(grep -c '^#EXTINF' output/failed.m3u 2>/dev/null || echo 0) + + { + echo "## Weekly channel health trend — $today" + echo "" + echo "- Online: $online" + echo "- Failed: $failed" + echo "" + } >> "$GITHUB_STEP_SUMMARY" + + if [ -s "$prev_file" ]; then + newly_failed=$(comm -13 "$prev_file" "$curr_file") + newly_fixed=$(comm -23 "$prev_file" "$curr_file") + nf_count=$(printf '%s\n' "$newly_failed" | grep -c . || true) + nx_count=$(printf '%s\n' "$newly_fixed" | grep -c . || true) + { + echo "### Changes since last snapshot" + echo "- Newly broken: $nf_count" + echo "- Recovered / fixed since then: $nx_count" + if [ "$nf_count" -gt 0 ]; then + echo "" + echo "**Newly broken URLs:**" + echo '```' + printf '%s\n' "$newly_failed" + echo '```' + fi + if [ "$nx_count" -gt 0 ]; then + echo "" + echo "**Recovered URLs (were failing, now online):**" + echo '```' + printf '%s\n' "$newly_fixed" + echo '```' + fi + } >> "$GITHUB_STEP_SUMMARY" + else + echo "_(no previous snapshot — this is the first run, nothing to compare against yet)_" >> "$GITHUB_STEP_SUMMARY" + fi + + mv "$curr_file" "$prev_file" + + - name: Commit updated snapshot + run: | + git config user.name "PlaylistBot" + git config user.email "playlistbot@users.noreply.github.com" + git add .github/checker-history/failed.txt + git diff --staged --quiet || git commit -m "Weekly checker snapshot ($(date -u +%Y-%m-%d))" + git diff --quiet HEAD @{u} 2>/dev/null || git push