@@ -14,20 +14,23 @@ const { deprecated } = require('../lib/enterprise-server-releases')
1414const 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
2729program
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