/* eslint-disable no-console */ import { exec } from 'child_process' import { promisify } from 'util' import * as core from '@actions/core' import dotenv from 'dotenv' dotenv.config() // Extrait la liste des liens référencés dans la base de code const { stdout, stderr } = await promisify(exec)( "rg -oNI -e 'https?://([\\w/_\\-?=%+@]|\\.\\w)+' -g '*.{yaml,ts,tsx,js,jsx}' -g '!*-en.yaml' -g '!api' ./ | sort | uniq" ) if (stderr) { throw new Error(stderr) } const links = stdout .split('\n') .filter(Boolean) .filter((link) => !link.startsWith('http://localhost')) // Certains sites référencés ont des problèmes de certificats, mais ce n'est pas // ce que nous cherchons à détecter ici. process.env.NODE_TLS_REJECT_UNAUTHORIZED = 0 // Création d'une queue permettant de paralléliser la vérification des liens const queue = [...links] const detectedErrors = [] const simultaneousItems = 5 async function processNextQueueItem() { if (queue.length !== 0) { await fetchAndReport(queue.shift()) await processNextQueueItem() } } async function fetchAndReport(link) { let status = await getHTTPStatus(link) // Retries in case of timeout let remainingRetries = 3 while (status === 499 && remainingRetries > 0) { remainingRetries-- await sleep(15_000) status = await getHTTPStatus(link) } report({ status, link }) } async function getHTTPStatus(link) { const maxTime = 15_000 const controller = new AbortController() setTimeout(() => controller.abort(), maxTime) try { const res = await fetch(link, { signal: controller.signal }) return res.status } catch (err) { return 499 } } function report({ status, link }) { console.log(status >= 404 ? '❌' : status >= 400 ? '⬛' : '✅', status, link) if (status >= 404 && status !== 499) { detectedErrors.push({ status, link }) } } function sleep(ms) { return new Promise((resolve) => setTimeout(resolve, ms)) } await Promise.allSettled( Array.from({ length: simultaneousItems }).map(processNextQueueItem) ) console.log('Terminé') if (detectedErrors.length > 0) { // Formattage spécifique pour récupérer le résultat avec l'action Github if (process.argv.slice(2).includes('--ci')) { const message = ` Certains liens référencés ne semblent plus fonctionner : | Status HTTP | Lien | |---|---| ${detectedErrors .map(({ status, link }) => `| ${status} | ${link} |`) .join('\n')}` const format = (msg) => msg .trim() .split('\n') .map((line) => line.trim()) .join('
') core.setOutput('comment', format(message)) } else if (detectedErrors) { core.setFailed( 'Liens invalides :' + detectedErrors .map(({ status, link }) => `\n- [${status}] ${link}`) .join('') ) } } process.exit(0)