Skip to content

Commit 60ceb65

Browse files
docs: validate relative links (#28690)
Co-authored-by: HonkingGoose <[email protected]>
1 parent 02eaf8c commit 60ceb65

File tree

11 files changed

+101
-9
lines changed

11 files changed

+101
-9
lines changed

.eslintrc.js

+9
Original file line numberDiff line numberDiff line change
@@ -224,5 +224,14 @@ module.exports = {
224224
'import/extensions': 0,
225225
},
226226
},
227+
{
228+
files: ['tools/docs/test/**/*.mjs'],
229+
env: {
230+
jest: false,
231+
},
232+
rules: {
233+
'@typescript-eslint/no-floating-promises': 0,
234+
},
235+
},
227236
],
228237
};

.github/workflows/build.yml

+3
Original file line numberDiff line numberDiff line change
@@ -558,6 +558,9 @@ jobs:
558558
- name: Build
559559
run: pnpm build:docs
560560

561+
- name: Test docs
562+
run: pnpm test:docs
563+
561564
- name: Upload
562565
uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3
563566
with:

docs/usage/configuration-options.md

+3-3
Original file line numberDiff line numberDiff line change
@@ -1272,7 +1272,7 @@ It is valid only as a top-level configuration option and not, for example, withi
12721272

12731273
<!-- prettier-ignore -->
12741274
!!! warning
1275-
The bot administrator must configure a list of allowed environment names in the [`allowedEnv`](./self-hosted-configuration.md#allowedEnv) config option, before users can use those allowed names in the `env` option.
1275+
The bot administrator must configure a list of allowed environment names in the [`allowedEnv`](./self-hosted-configuration.md#allowedenv) config option, before users can use those allowed names in the `env` option.
12761276

12771277
Behavior:
12781278

@@ -1376,7 +1376,7 @@ Renovate can fetch changelogs when they are hosted on one of these platforms:
13761376
- GitHub (.com and Enterprise Server)
13771377
- GitLab (.com and CE/EE)
13781378

1379-
If you are running on any platform except `github.com`, you need to [configure a Personal Access Token](./getting-started/running.md#githubcom-token-for-release-notes) to allow Renovate to fetch changelogs notes from `github.com`.
1379+
If you are running on any platform except `github.com`, you need to [configure a Personal Access Token](./getting-started/running.md#githubcom-token-for-changelogs) to allow Renovate to fetch changelogs notes from `github.com`.
13801380

13811381
<!-- prettier-ignore -->
13821382
!!! note
@@ -1869,7 +1869,7 @@ Enable got [http2](https://github.com/sindresorhus/got/blob/v11.5.2/readme.md#ht
18691869
You can provide a `headers` object that includes fields to be forwarded to the HTTP request headers.
18701870
By default, all headers starting with "X-" are allowed.
18711871

1872-
A bot administrator may configure an override for [`allowedHeaders`](./self-hosted-configuration.md#allowedHeaders) to configure more permitted headers.
1872+
A bot administrator may configure an override for [`allowedHeaders`](./self-hosted-configuration.md#allowedheaders) to configure more permitted headers.
18731873

18741874
`headers` value(s) configured in the bot admin `hostRules` (for example in a `config.js` file) are _not_ validated, so it may contain any header regardless of `allowedHeaders`.
18751875

docs/usage/getting-started/private-packages.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -616,4 +616,4 @@ For instructions on this, see the above section on encrypting secrets for the Me
616616

617617
### hostRules configuration using environment variables
618618

619-
Self-hosted users can enable the option [`detectHostRulesFromEnv`](../self-hosted-configuration.md#detectHostRulesFromEnv) to configure the most common types of `hostRules` via environment variables.
619+
Self-hosted users can enable the option [`detectHostRulesFromEnv`](../self-hosted-configuration.md#detecthostrulesfromenv) to configure the most common types of `hostRules` via environment variables.

docs/usage/key-concepts/changelogs.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -98,11 +98,11 @@ If your repository uses the monorepo pattern make sure _each_ `package.json` fil
9898

9999
### maven package maintainers
100100

101-
Read [`maven` datasource, making your changelogs fetchable](https://docs.renovatebot.com/modules/datasource/maven/#making-your-changelogs-fetchable).
101+
Read [`maven` datasource, making your changelogs fetchable](../modules/datasource/maven/index.md#making-your-changelogs-fetchable).
102102

103103
### Docker image maintainers
104104

105-
Read the [Docker datasource](https://docs.renovatebot.com/modules/datasource/docker/) docs.
105+
Read the [Docker datasource](../modules/datasource/docker/index.md) docs.
106106

107107
### Nuget package maintainers
108108

docs/usage/self-hosted-configuration.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -997,7 +997,7 @@ Defines how the report is exposed:
997997
- `<unset>` If unset, no report will be provided, though the debug logs will still have partial information of the report
998998
- `logging` The report will be printed as part of the log messages on `INFO` level
999999
- `file` The report will be written to a path provided by [`reportPath`](#reportpath)
1000-
- `s3` The report is pushed to an S3 bucket defined by [`reportPath`](#reportpath). This option reuses [`RENOVATE_X_S3_ENDPOINT`](./self-hosted-experimental.md#renovatexs3endpoint) and [`RENOVATE_X_S3_PATH_STYLE`](./self-hosted-experimental.md#renovatexs3pathstyle)
1000+
- `s3` The report is pushed to an S3 bucket defined by [`reportPath`](#reportpath). This option reuses [`RENOVATE_X_S3_ENDPOINT`](./self-hosted-experimental.md#renovate_x_s3_endpoint) and [`RENOVATE_X_S3_PATH_STYLE`](./self-hosted-experimental.md#renovate_x_s3_path_style)
10011001

10021002
## repositories
10031003

docs/usage/self-hosted-experimental.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ If you use the Mend Renovate Enterprise Edition (Renovate EE) and:
138138

139139
Then you must set this variable at the _server_ and the _workers_.
140140

141-
But if you have specified the token as a [`matchConfidence`](https://docs.renovatebot.com/configuration-options/#matchconfidence) `hostRule`, you only need to set this variable at the _workers_.
141+
But if you have specified the token as a [`matchConfidence`](configuration-options.md#matchconfidence) `hostRule`, you only need to set this variable at the _workers_.
142142

143143
This feature is in private beta.
144144

lib/modules/platform/gerrit/readme.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ It works similar to the default option `"pr"`.
4242

4343
You can use the `statusCheckNames` configuration to map any of the available branch checks (like `minimumReleaseAge`, `mergeConfidence`, and so on) to a Gerrit label.
4444

45-
For example, if you want to use the [Merge Confidence](https://docs.renovatebot.com/merge-confidence/) feature and map the result of the Merge Confidence check to your Gerrit label "Renovate-Merge-Confidence" you can configure:
45+
For example, if you want to use the [Merge Confidence](../../../merge-confidence.md) feature and map the result of the Merge Confidence check to your Gerrit label "Renovate-Merge-Confidence" you can configure:
4646

4747
```json
4848
{

package.json

+2
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
"test-e2e:install": "cd test/e2e && npm install --no-package-lock --prod",
5252
"test-e2e:run": "cd test/e2e && npm test",
5353
"test-schema": "run-s create-json-schema",
54+
"test:docs": "node --test tools/docs/test/",
5455
"schedule-test-shards": "SCHEDULE_TEST_SHARDS=true ts-node jest.config.ts",
5556
"tsc": "tsc",
5657
"type-check": "run-s 'generate:*' 'tsc --noEmit {@}' --",
@@ -300,6 +301,7 @@
300301
"@types/semver-utils": "1.1.3",
301302
"@types/tar": "6.1.13",
302303
"@types/traverse": "0.6.36",
304+
"@types/unist": "2.0.10",
303305
"@types/url-join": "4.0.3",
304306
"@types/validate-npm-package-name": "4.0.2",
305307
"@types/xmldoc": "1.1.9",

pnpm-lock.yaml

+3
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

tools/docs/test/index.test.mjs

+75
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
import assert from 'node:assert';
2+
import path from 'node:path';
3+
import { describe, it } from 'node:test';
4+
import fs from 'fs-extra';
5+
import { glob } from 'glob';
6+
import remark from 'remark';
7+
import github from 'remark-github';
8+
9+
const root = path.resolve('tmp/docs');
10+
11+
/**
12+
* @param {any} node
13+
* @param {Set<string>} files
14+
* @param {string} file
15+
*/
16+
function checkNode(node, files, file) {
17+
if (node.type === 'link') {
18+
/** @type {import('mdast').Link} */
19+
const link = node;
20+
assert.ok(
21+
!link.url.startsWith('/'),
22+
`Link should be external or relative: ${link.url}`,
23+
);
24+
25+
if (link.url.startsWith('.') && !/^https?:\/\//.test(link.url)) {
26+
// absolute path
27+
const absPath = path.resolve(
28+
'tmp/docs',
29+
path.dirname(file),
30+
link.url.replace(/#.*/, ''),
31+
);
32+
// relative path
33+
const relPath = absPath.substring(root.length + 1);
34+
35+
assert.ok(
36+
files.has(relPath),
37+
`File not found: ${link.url} in ${file} -> ${relPath}`,
38+
);
39+
} else {
40+
assert.ok(
41+
!link.url.startsWith('https://docs.renovatebot.com/'),
42+
`Docs links should be relative: ${link.url}`,
43+
);
44+
}
45+
} else if ('children' in node) {
46+
for (const child of node.children) {
47+
checkNode(child, files, file);
48+
}
49+
}
50+
}
51+
52+
describe('index', async () => {
53+
await describe('validate links', async () => {
54+
const todo = await glob('**/*.md', { cwd: 'tmp/docs' });
55+
const files = new Set(todo);
56+
57+
// Files from https://github.com/renovatebot/renovatebot.github.io/tree/main/src
58+
files.add('index.md');
59+
60+
let c = 0;
61+
62+
for (const file of todo) {
63+
c++;
64+
65+
await it(`${file}`, async () => {
66+
const node = remark()
67+
.use(github)
68+
.parse(await fs.readFile(`tmp/docs/${file}`, 'utf8'));
69+
checkNode(node, files, file);
70+
});
71+
}
72+
73+
assert.ok(c > 0, 'Should find at least one file');
74+
});
75+
});

0 commit comments

Comments
 (0)