diff --git a/.github/scripts/check-markdown.mjs b/.github/scripts/check-markdown.mjs index a21c09d1b..89f88c9e5 100644 --- a/.github/scripts/check-markdown.mjs +++ b/.github/scripts/check-markdown.mjs @@ -4,6 +4,10 @@ * Current checks: * - H1 headings (# ...): the H1 is already generated from the `title` field * in the frontmatter, so adding a `#` heading manually creates a duplicate. + * - Absolute URLs to the published site: links beginning with + * https://design-history.prevention-services.nhs.uk/ should use + * relative URLs instead, so that they work in previews and in case the URL + * changes in future. * * When run directly, scans all markdown files under app/: * npm run check:markdown @@ -24,6 +28,13 @@ const H1_MESSAGE = 'If this heading duplicates the title, remove it. ' + 'If it is a different heading, change it to an H2 using `##`.' +const SITE_URL = 'https://design-history.prevention-services.nhs.uk/' + +const ABSOLUTE_URL_MESSAGE = + 'Use a relative URL instead of a full URL for links to other posts on the site.\n\n' + + 'This means that the links will work in previews, and in case the site domain name changes in future.\n\n' + + 'For example, replace `https://design-history.prevention-services.nhs.uk/some/path/` with `/some/path/`.' + /** * Recursively finds all .md files under the given directory. * @@ -56,6 +67,9 @@ export function scanAllFiles() { if (/^# /.test(lines[i])) { mistakes.push({ path: filePath, line: i + 1, message: H1_MESSAGE }) } + if (lines[i].includes('](' + SITE_URL)) { + mistakes.push({ path: filePath, line: i + 1, message: ABSOLUTE_URL_MESSAGE }) + } } } @@ -106,6 +120,16 @@ export function getMistakes(baseRef) { message: H1_MESSAGE }) } + // Added line containing an absolute URL to the published site + const lineContent = rawLine.slice(1) + if (lineContent.includes('](' + SITE_URL)) { + mistakes.push({ + path: currentFile, + line: lineNumber, + message: ABSOLUTE_URL_MESSAGE, + suggestion: lineContent.replaceAll(SITE_URL, '/') + }) + } } else if (!rawLine.startsWith('-')) { // Context line -- still advances the new-file line number lineNumber++ diff --git a/.github/scripts/pr-review.mjs b/.github/scripts/pr-review.mjs index 8a2f67b87..221e1b63c 100644 --- a/.github/scripts/pr-review.mjs +++ b/.github/scripts/pr-review.mjs @@ -18,6 +18,18 @@ const { GITHUB_TOKEN, REPO, BASE_REF, PR_NUMBER, HEAD_SHA } = process.env const BOT_USER = 'github-actions[bot]' +/** + * Builds the comment body for a mistake. If the mistake includes a suggestion, + * appends a GitHub suggestion block so the author can apply the fix in one click. + * + * @param {{ message: string, suggestion?: string }} mistake + * @returns {string} + */ +function commentBody({ message, suggestion }) { + if (!suggestion) return message + return `${message}\n\n\`\`\`suggestion\n${suggestion}\n\`\`\`` +} + async function githubFetch(path, options = {}) { const response = await fetch(`https://api.github.com${path}`, { ...options, @@ -56,7 +68,7 @@ const botComments = existingComments const staleComments = botComments.filter( (c) => !mistakes.some( - (m) => m.path === c.path && m.line === c.line && m.message === c.body + (m) => m.path === c.path && m.line === c.line && commentBody(m) === c.body ) ) @@ -107,16 +119,16 @@ if (mistakes.length === 0) { // Post new comments for mistakes that don't already have a comment const newComments = mistakes .filter( - ({ path, line, message }) => + (m) => !botComments.some( - (c) => c.path === path && c.line === line && c.body === message + (c) => c.path === m.path && c.line === m.line && c.body === commentBody(m) ) ) - .map(({ path, line, message }) => ({ - path, - line, + .map((m) => ({ + path: m.path, + line: m.line, side: 'RIGHT', - body: message + body: commentBody(m) })) if (newComments.length === 0) {