mirror of
https://github.com/renovatebot/renovate.git
synced 2025-01-10 22:16:28 +00:00
test: enforce valid JSON in fenced markdown code blocks (#12196)
This commit is contained in:
parent
f885e3e437
commit
34f13fee3e
12 changed files with 166 additions and 67 deletions
1
.github/workflows/build.yml
vendored
1
.github/workflows/build.yml
vendored
|
@ -154,6 +154,7 @@ jobs:
|
|||
yarn prettier
|
||||
yarn markdown-lint
|
||||
yarn git-check
|
||||
yarn doc-fence-check
|
||||
|
||||
- name: Test schema
|
||||
run: yarn test-schema
|
||||
|
|
|
@ -53,11 +53,10 @@ If you add a `renovate.json` file to the root of your repository, you can use th
|
|||
If you add configuration options to your `package.json` then these will override any other settings above.
|
||||
|
||||
```json
|
||||
"renovate": {
|
||||
"labels": [
|
||||
"upgrade",
|
||||
"bot"
|
||||
]
|
||||
{
|
||||
"renovate": {
|
||||
"labels": ["upgrade", "bot"]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
|
|
@ -128,28 +128,24 @@ You can find the Renovate team's preset configs at the "Config Presets" section
|
|||
If you browse the "default" presets, you will see some that contain parameters, e.g.:
|
||||
|
||||
```json
|
||||
"labels": {
|
||||
"description": "Apply labels <code>{{arg0}}</code> and <code>{{arg1}}</code> to PRs",
|
||||
"labels": [
|
||||
"{{arg0}}",
|
||||
"{{arg1}}"
|
||||
]
|
||||
},
|
||||
"assignee": {
|
||||
"description": "Assign PRs to <code>{{arg0}}</code>",
|
||||
"assignees": [
|
||||
"{{arg0}}"
|
||||
]
|
||||
},
|
||||
{
|
||||
"labels": {
|
||||
"description": "Apply labels <code>{{arg0}}</code> and <code>{{arg1}}</code> to PRs",
|
||||
"labels": ["{{arg0}}", "{{arg1}}"]
|
||||
},
|
||||
"assignee": {
|
||||
"description": "Assign PRs to <code>{{arg0}}</code>",
|
||||
"assignees": ["{{arg0}}"]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Here is how you would use these in your Renovate config:
|
||||
|
||||
```json
|
||||
"extends": [
|
||||
":labels(dependencies,devops)",
|
||||
":assignee(rarkins)"
|
||||
]
|
||||
{
|
||||
"extends": [":labels(dependencies,devops)", ":assignee(rarkins)"]
|
||||
}
|
||||
```
|
||||
|
||||
In short, the number of `{{argx}}` parameters in the definition is how many parameters you need to provide.
|
||||
|
@ -170,7 +166,9 @@ To host your preset config on GitHub:
|
|||
- In other repos, reference it in an extends array like "github>owner/name", for example:
|
||||
|
||||
```json
|
||||
{
|
||||
"extends": ["github>rarkins/renovate-config"]
|
||||
}
|
||||
```
|
||||
|
||||
From then on Renovate will use the Renovate config from the preset repo's default branch.
|
||||
|
@ -259,7 +257,6 @@ For example:
|
|||
{
|
||||
"name": "renovate-config-fastcore",
|
||||
"version": "0.0.1",
|
||||
...
|
||||
"renovate-config": {
|
||||
"default": {
|
||||
"extends": ["config:base", "schedule:nonOfficeHours"]
|
||||
|
@ -271,7 +268,9 @@ For example:
|
|||
Then in each of your repositories you can add your Renovate config like:
|
||||
|
||||
```json
|
||||
{
|
||||
"extends": ["fastcore"]
|
||||
}
|
||||
```
|
||||
|
||||
Any repository including this config will then adopt the rules of the default `library` preset but schedule it on weeknights or weekends.
|
||||
|
@ -279,5 +278,7 @@ Any repository including this config will then adopt the rules of the default `l
|
|||
Note: if you prefer to publish using the namespace `@fastcore/renovate-config` then you would use the `@` prefix instead:
|
||||
|
||||
```json
|
||||
{
|
||||
"extends": ["@fastcore"]
|
||||
}
|
||||
```
|
||||
|
|
|
@ -126,11 +126,13 @@ If you wish to override Docker settings for one particular type of manager, use
|
|||
For example, to disable digest updates for Docker Compose only but leave them for other managers like `Dockerfile`, you would use this:
|
||||
|
||||
```json
|
||||
{
|
||||
"docker-compose": {
|
||||
"digest": {
|
||||
"enabled": false
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The following configuration options are applicable to Docker:
|
||||
|
|
|
@ -180,12 +180,14 @@ Set the configuration option `labels` to an array of labels to use.
|
|||
e.g.
|
||||
|
||||
```json
|
||||
"packageRules": [
|
||||
{
|
||||
"matchPackageNames": ["abc"],
|
||||
"assignees": ["importantreviewer"]
|
||||
}
|
||||
]
|
||||
{
|
||||
"packageRules": [
|
||||
{
|
||||
"matchPackageNames": ["abc"],
|
||||
"assignees": ["importantreviewer"]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### Apply a rule, but only for packages starting with `abc`
|
||||
|
@ -193,12 +195,14 @@ e.g.
|
|||
Do the same as above, but instead of using `matchPackageNames`, use `matchPackagePatterns` and a regex:
|
||||
|
||||
```json
|
||||
"packageRules": [
|
||||
{
|
||||
"matchPackagePatterns": "^abc",
|
||||
"assignees": ["importantreviewer"]
|
||||
}
|
||||
]
|
||||
{
|
||||
"packageRules": [
|
||||
{
|
||||
"matchPackagePatterns": "^abc",
|
||||
"assignees": ["importantreviewer"]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### Group all packages starting with `abc` together in one PR
|
||||
|
@ -206,12 +210,14 @@ Do the same as above, but instead of using `matchPackageNames`, use `matchPackag
|
|||
As above, but apply a `groupName`:
|
||||
|
||||
```json
|
||||
"packageRules": [
|
||||
{
|
||||
"matchPackagePatterns": "^abc",
|
||||
"groupName": ["abc packages"]
|
||||
}
|
||||
]
|
||||
{
|
||||
"packageRules": [
|
||||
{
|
||||
"matchPackagePatterns": "^abc",
|
||||
"groupName": ["abc packages"]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### Change the default values for branch name, commit message, PR title or PR description
|
||||
|
|
|
@ -46,9 +46,11 @@ You can force Renovate to use a specific version of Go by setting a constraint.
|
|||
As an example, say you want Renovate to use the latest patch version of the `1.16` Go binary, you'd put this in your Renovate config:
|
||||
|
||||
```json
|
||||
{
|
||||
"constraints": {
|
||||
"go": "1.16"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
We do not support patch level versions for the minimum `go` version.
|
||||
|
|
|
@ -28,12 +28,14 @@ You may wish to take this further, for example you might want to group together
|
|||
In that case you might create a config like this:
|
||||
|
||||
```json
|
||||
{
|
||||
"packageRules": [
|
||||
{
|
||||
"matchPackagePatterns": [ "eslint" ],
|
||||
"matchPackagePatterns": ["eslint"],
|
||||
"groupName": "eslint"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
By setting `matchPackagePatterns` to "eslint", it means that any package with ESLint anywhere in its name will be grouped into a `renovate/eslint` branch and related PR.
|
||||
|
@ -79,25 +81,29 @@ If you think about it, updates to `eslint` rules don't exactly need to be applie
|
|||
You don't want to get too far behind, so how about we update `eslint` packages only once a month?
|
||||
|
||||
```json
|
||||
{
|
||||
"packageRules": [
|
||||
{
|
||||
"matchPackagePatterns": [ "eslint" ],
|
||||
"matchPackagePatterns": ["eslint"],
|
||||
"groupName": "eslint",
|
||||
"schedule": ["on the first day of the month"]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
Or perhaps at least weekly:
|
||||
|
||||
```json
|
||||
{
|
||||
"packageRules": [
|
||||
{
|
||||
"matchPackagePatterns": [ "eslint" ],
|
||||
"matchPackagePatterns": ["eslint"],
|
||||
"groupName": "eslint",
|
||||
"schedule": ["before 2am on monday"]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
If you're wondering what is supported and not, under the hood, the schedule is parsed using [@breejs/later](https://github.com/breejs/later) using the `later.parse.text(scheduleString)` API.
|
||||
|
@ -149,15 +155,17 @@ Remember our running `eslint` example?
|
|||
Let's automerge it if all the linting updates pass:
|
||||
|
||||
```json
|
||||
{
|
||||
"packageRules": [
|
||||
{
|
||||
"matchPackagePatterns": [ "eslint" ],
|
||||
"matchPackagePatterns": ["eslint"],
|
||||
"groupName": "eslint",
|
||||
"schedule": ["before 2am on monday"],
|
||||
"automerge": true,
|
||||
"automergeType": "branch"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
Have you come up with a rule that you think others would benefit from?
|
||||
|
|
|
@ -30,12 +30,14 @@ Renovate by default performs all lookups on `https://api.nuget.org/v3/index.json
|
|||
Alternative feeds can be specified either [in a `NuGet.config` file](https://docs.microsoft.com/en-us/nuget/reference/nuget-config-file#package-source-sections) within your repository (Renovate will not search outside the repository) or in Renovate configuration options:
|
||||
|
||||
```json
|
||||
"nuget": {
|
||||
"registryUrls": [
|
||||
"https://api.nuget.org/v3/index.json",
|
||||
"https://example1.com/nuget/",
|
||||
"https://example2.com/nuget/v3/index.json"
|
||||
]
|
||||
{
|
||||
"nuget": {
|
||||
"registryUrls": [
|
||||
"https://api.nuget.org/v3/index.json",
|
||||
"https://example1.com/nuget/",
|
||||
"https://example2.com/nuget/v3/index.json"
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -50,10 +52,10 @@ Renovate as a NuGet client supports both versions and will use `v2` unless the c
|
|||
If you have a `v3` feed that does not match this pattern (e.g. JFrog Artifactory) you need to help Renovate by appending `#protocolVersion=3` to the registry URL:
|
||||
|
||||
```json
|
||||
"nuget": {
|
||||
"registryUrls": [
|
||||
"http://myV3feed#protocolVersion=3"
|
||||
]
|
||||
{
|
||||
"nuget": {
|
||||
"registryUrls": ["http://myV3feed#protocolVersion=3"]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -62,14 +64,16 @@ If you have a `v3` feed that does not match this pattern (e.g. JFrog Artifactory
|
|||
Credentials for authenticated/private feeds can be provided via host rules in the configuration options (file or command line parameter).
|
||||
|
||||
```json
|
||||
"hostRules": [
|
||||
{
|
||||
"hostType": "nuget",
|
||||
"matchHost": "http://example1.com/nuget",
|
||||
"username": "root",
|
||||
"password": "p4$$w0rd"
|
||||
}
|
||||
]
|
||||
{
|
||||
"hostRules": [
|
||||
{
|
||||
"hostType": "nuget",
|
||||
"matchHost": "http://example1.com/nuget",
|
||||
"username": "root",
|
||||
"password": "p4$$w0rd"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
Please note that at the moment only Basic HTTP authentication (via username and password) is supported.
|
||||
|
|
|
@ -32,9 +32,11 @@ If you have a specific file or file pattern you want the Renovate bot to find, u
|
|||
e.g.:
|
||||
|
||||
```json
|
||||
{
|
||||
"pip_requirements": {
|
||||
"fileMatch": ["my/specifically-named.file", "\.requirements$"]
|
||||
"fileMatch": ["my/specifically-named.file", "\\.requirements$"]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Alternate registries
|
||||
|
@ -63,9 +65,11 @@ You can use the `registryUrls` array to configure alternate index URL(s).
|
|||
e.g.:
|
||||
|
||||
```json
|
||||
{
|
||||
"python": {
|
||||
"registryUrls": ["http://example.com/private-pypi/"]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Note: the index-url found in the `requirements.txt` file takes precedence over a `registryUrl` configured like the above.
|
||||
|
@ -76,14 +80,18 @@ To override the URL found in `requirements.txt`, you need to configure it in `pa
|
|||
The most direct way to disable all Python support in Renovate is like this:
|
||||
|
||||
```json
|
||||
{
|
||||
"python": {
|
||||
"enabled": false
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Alternatively, maybe you only want one package manager, such as `npm`.
|
||||
In that case this would enable _only_ `npm`:
|
||||
|
||||
```json
|
||||
{
|
||||
"enabledManagers": ["npm"]
|
||||
}
|
||||
```
|
||||
|
|
|
@ -4,8 +4,10 @@ You can create a custom [versioning config](/configuration-options/#versioning)
|
|||
For example, if you want to reference a tag like `module-v1.2.5`, a block like this would work:
|
||||
|
||||
```json
|
||||
"terraform": {
|
||||
"versioning": "regex:^((?<compatibility>.*)-v|v*)(?<major>\\d+)\\.(?<minor>\\d+)\\.(?<patch>\\d+)$"
|
||||
{
|
||||
"terraform": {
|
||||
"versioning": "regex:^((?<compatibility>.*)-v|v*)(?<major>\\d+)\\.(?<minor>\\d+)\\.(?<patch>\\d+)$"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
"create-json-schema": "node -r ts-node/register/transpile-only -- bin/create-json-schema.js && prettier --write \"renovate-schema.json\"",
|
||||
"debug": "node --inspect-brk -r ts-node/register/transpile-only -- lib/renovate.ts",
|
||||
"doc-fix": "run-s markdown-lint-fix prettier-fix",
|
||||
"doc-fence-check": "node tools/check-fenced-code.mjs",
|
||||
"eslint": "eslint --ext .js,.mjs,.ts lib/ test/ tools/ --report-unused-disable-directives",
|
||||
"eslint-fix": "eslint --ext .js,.mjs,.ts --fix lib/ test/ tools/ --report-unused-disable-directives",
|
||||
"generate": "run-s generate:*",
|
||||
|
@ -23,7 +24,7 @@
|
|||
"jest": "cross-env NODE_ENV=test LOG_LEVEL=fatal TZ=UTC node --expose-gc node_modules/jest/bin/jest.js --logHeapUsage",
|
||||
"jest-debug": "cross-env NODE_OPTIONS=--inspect-brk yarn jest --testTimeout=100000000",
|
||||
"jest-silent": "cross-env yarn jest --reporters jest-silent-reporter",
|
||||
"lint": "run-s ls-lint eslint prettier markdown-lint git-check",
|
||||
"lint": "run-s ls-lint eslint prettier markdown-lint git-check doc-fence-check",
|
||||
"lint-fix": "run-s eslint-fix prettier-fix markdown-lint-fix",
|
||||
"ls-lint": "ls-lint",
|
||||
"markdown-lint": "markdownlint-cli2",
|
||||
|
|
65
tools/check-fenced-code.mjs
Normal file
65
tools/check-fenced-code.mjs
Normal file
|
@ -0,0 +1,65 @@
|
|||
import { promisify } from 'util';
|
||||
import fs from 'fs-extra';
|
||||
import g from 'glob';
|
||||
import MarkdownIt from 'markdown-it';
|
||||
import shell from 'shelljs';
|
||||
|
||||
const glob = promisify(g);
|
||||
|
||||
const errorTitle = 'Invalid JSON in fenced code block';
|
||||
const errorBody =
|
||||
'Fix this manually by ensuring each block is a valid, complete JSON document.';
|
||||
const markdownGlob = '{docs,lib}/**/*.md';
|
||||
const markdown = new MarkdownIt('zero');
|
||||
|
||||
let issues = 0;
|
||||
|
||||
markdown.enable(['fence']);
|
||||
|
||||
function checkValidJson(file, token) {
|
||||
const start = parseInt(token.map[0], 10) + 1;
|
||||
const end = parseInt(token.map[1], 10) + 1;
|
||||
|
||||
try {
|
||||
JSON.parse(token.content);
|
||||
} catch (err) {
|
||||
issues += 1;
|
||||
if (process.env.CI) {
|
||||
shell.echo(
|
||||
`::error file=${file},line=${start},endLine=${end},title=${errorTitle}::${err.message}. ${errorBody}`
|
||||
);
|
||||
} else {
|
||||
shell.echo(
|
||||
`${errorTitle} (${file} lines ${start}-${end}): ${err.message}`
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function processFile(file) {
|
||||
const text = await fs.readFile(file, 'utf8');
|
||||
const tokens = markdown.parse(text, undefined);
|
||||
shell.echo(`Linting ${file}...`);
|
||||
|
||||
tokens.forEach((token) => {
|
||||
if (token.type === 'fence' && token.info === 'json') {
|
||||
checkValidJson(file, token);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
||||
(async () => {
|
||||
const files = await glob(markdownGlob);
|
||||
|
||||
for (const file of files) {
|
||||
await processFile(file);
|
||||
}
|
||||
|
||||
if (issues) {
|
||||
shell.echo(
|
||||
`${issues} issues found. ${errorBody} See above for lines affected.`
|
||||
);
|
||||
shell.exit(1);
|
||||
}
|
||||
})();
|
Loading…
Reference in a new issue