Skip to content

Commit 3543597

Browse files
authored
Merge pull request #17885 from github/if-it-aint-broke
No broken links = no broken link report
2 parents 219db8d + b36513f commit 3543597

1 file changed

Lines changed: 27 additions & 19 deletions

File tree

script/check-english-links.js

Lines changed: 27 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -14,20 +14,23 @@ const { deprecated } = require('../lib/enterprise-server-releases')
1414
const got = require('got')
1515

1616
// Links with these codes may or may not really be broken.
17-
const retryStatusCodes = [429, 503]
17+
const retryStatusCodes = [429, 503, 'Invalid']
1818

1919
// [start-readme]
2020
//
2121
// This script runs once per day via a scheduled GitHub Action to check all links in
2222
// English content, not including deprecated Enterprise Server content. It opens an issue
2323
// if it finds broken links. To exclude a link path, add it to `lib/excluded-links.js`.
24+
// Note that linkinator somtimes returns 429 and 503 errors for links that are not actually
25+
// broken, so this script double-checks those using `got`.
2426
//
2527
// [end-readme]
2628

2729
program
2830
.description('Check all links in the English docs.')
2931
.option('-d, --dry-run', 'Turn off recursion to get a fast minimal report (useful for previewing output).')
30-
.option('-p, --path <PATH>', 'Provide an optional path to check. Best used with --dry-run. If not provided, defaults to the homepage.')
32+
.option('-r, --do-not-retry', `Do not retry broken links with status codes ${retryStatusCodes.join(', ')}.`)
33+
.option('-p, --path <PATH>', `Provide an optional path to check. Best used with --dry-run. Default: ${englishRoot}`)
3134
.parse(process.argv)
3235

3336
// Skip excluded links defined in separate file.
@@ -79,23 +82,28 @@ async function main () {
7982
// Scan is complete! Filter the results for broken links.
8083
const brokenLinks = result
8184
.filter(link => link.state === 'BROKEN')
82-
83-
// Links to retry individually.
84-
const linksToRetry = brokenLinks
85-
.filter(link => !link.status || retryStatusCodes.includes(link.status))
86-
87-
await Promise.all(linksToRetry
88-
.map(async (link) => {
89-
try {
90-
// got throws an HTTPError if response code is not 2xx or 3xx.
91-
// If got succeeds, we can remove the link from the list.
92-
await got(link.url)
93-
pull(brokenLinks, link)
94-
// If got fails, do nothing. The link is already in the broken list.
95-
} catch (err) {
96-
// noop
97-
}
98-
}))
85+
// Coerce undefined status codes into `Invalid` strings so we can display them.
86+
// Without this, undefined codes get JSON.stringified as `0`, which is not useful output.
87+
.map(link => { link.status = link.status || 'Invalid'; return link })
88+
89+
if (!program.doNotRetry) {
90+
// Links to retry individually.
91+
const linksToRetry = brokenLinks
92+
.filter(link => retryStatusCodes.includes(link.status))
93+
94+
await Promise.all(linksToRetry
95+
.map(async (link) => {
96+
try {
97+
// got throws an HTTPError if response code is not 2xx or 3xx.
98+
// If got succeeds, we can remove the link from the list.
99+
await got(link.url)
100+
pull(brokenLinks, link)
101+
// If got fails, do nothing. The link is already in the broken list.
102+
} catch (err) {
103+
// noop
104+
}
105+
}))
106+
}
99107

100108
// Exit successfully if no broken links!
101109
if (!brokenLinks.length) {

0 commit comments

Comments
 (0)