-
Notifications
You must be signed in to change notification settings - Fork 0
132 lines (121 loc) · 4.97 KB
/
Copy pathbroken-links.yml
File metadata and controls
132 lines (121 loc) · 4.97 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
name: broken-links
on:
schedule:
# Nightly at 09:00 UTC (around 03:00 MT / 04:00 CT).
- cron: '0 9 * * *'
workflow_dispatch: {}
permissions:
issues: write
contents: read
jobs:
crawl:
name: Crawl site for broken links
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Pick target URL
id: target
# We feed Lychee the sitemap rather than the homepage. Lychee's
# CLI doesn't support recursive crawling — it checks every link
# on every input. Pointing it at /sitemap.xml gives it the full
# URL list (33 static pages + 162 blog posts) and it then checks
# every link on every one of those pages. That's the "test all
# internal pages too" coverage the homepage-only run lacked.
run: |
if [ -n "${{ secrets.STAGING_URL }}" ]; then
base="${{ secrets.STAGING_URL }}"
else
base="https://beta.ontargetaba.com/"
fi
# Trim trailing slash, append sitemap.xml
base="${base%/}"
echo "url=${base}/sitemap.xml" >> "$GITHUB_OUTPUT"
- name: Run Lychee
id: lychee
uses: lycheeverse/lychee-action@v2
with:
args: >-
--verbose
--no-progress
--max-retries 2
--retry-wait-time 5
--timeout 20
--accept 200,206,429
--include-verbatim
--exclude '^https://ontargetaba\.com/'
--exclude '^https://static\.hotjar\.com/c/hotjar-$'
--exclude 'search_term_string'
--exclude '^https://(www\.)?linkedin\.com/'
--exclude '^https://(www\.)?instagram\.com/'
--exclude '^https://(www\.)?facebook\.com/'
${{ steps.target.outputs.url }}
fail: false
output: ./lychee-report.md
- name: Verify Lychee actually ran
# `fail: false` above lets the step continue when broken links
# are found, but it also masks the case where Lychee itself
# blew up (bad CLI args, sitemap unreachable, etc.) — in which
# case no report is produced and we'd silently open a misleading
# tracking issue. Treat "no report or empty report" as a hard
# workflow failure so red CI flags the real problem.
run: |
if [ ! -s ./lychee-report.md ]; then
echo "::error::Lychee produced no report — it likely failed to run. Check the 'Run Lychee' step logs above for CLI arg errors or network failures."
exit 1
fi
- name: Find existing tracking issue
id: existing
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
num=$(gh issue list --state open --label broken-links \
--search "Broken links found" \
--json number --jq '.[0].number // empty')
echo "number=$num" >> "$GITHUB_OUTPUT"
- name: Open or update tracking issue
if: steps.lychee.outputs.exit_code != '0'
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
TARGET_URL: ${{ steps.target.outputs.url }}
RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
run: |
date_str=$(date -u +%Y-%m-%d)
title="Broken links found ${date_str}"
# Build the body in a file. We previously stitched it with
# bash $(...) + +=, but command substitution strips trailing
# newlines, so when lychee-report.md didn't end with one the
# closing ``` ended up smushed against the last content line.
# Writing through printf to a real file gives us deterministic
# line endings — closing fence is always on its own line.
{
printf '## Broken links\n\n'
printf 'Target: %s\n' "$TARGET_URL"
printf 'Run: %s\n\n' "$RUN_URL"
printf '```\n'
if [ -s ./lychee-report.md ]; then
cat ./lychee-report.md
else
printf 'See run logs for details.\n'
fi
# Force a final newline before the closing fence regardless
# of whether the report ended with one.
printf '\n```\n'
} > /tmp/issue-body.md
if [ -n "${{ steps.existing.outputs.number }}" ]; then
gh issue edit "${{ steps.existing.outputs.number }}" \
--title "$title" \
--body-file /tmp/issue-body.md
else
gh issue create \
--title "$title" \
--body-file /tmp/issue-body.md \
--label broken-links
fi
- name: Close tracking issue when clean
if: steps.lychee.outputs.exit_code == '0' && steps.existing.outputs.number != ''
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
gh issue close "${{ steps.existing.outputs.number }}" \
--comment "All previously broken links are now resolving. Closing."