TutorialVS Code

YAML Formatting and yamllint Checks

Separate Oxfmt, yamllint, and schema validation, then connect task diagnostics to Problems.

Updated Verified SourceEdit this page

Sources checked on 2026-09-06. Apply the examples sequentially in a separate format-lab project. Commands run from its root on macOS, Linux, or WSL. Merge the relevant keys into existing configuration files.

YAML needs three distinct checks

Pretty YAML can still contain replicas: many. Oxfmt owns layout, yamllint checks duplicate keys and notation, and the Red Hat YAML extension provides schema diagnostics. The YAML extension does not execute .yamllint.yaml. YAML schema support

Prepare configuration

Reuse Oxfmt from Oxfmt and Oxlint and install uv for Python tools. Run uv init --bare only if the lab has no pyproject.toml. Commit the dependency declarations and uv.lock generated by uv add.

uv init --bare
uv add --dev --bounds exact yamllint
code --install-extension redhat.vscode-yaml

Create .yamllint.yaml:

extends: default
rules:
    document-start: disable
    line-length: disable
    braces:
        min-spaces-inside: 0
        max-spaces-inside: 1
    truthy:
        allowed-values: ["true", "false"]
        check-keys: false
ignore: |
    node_modules/
    .venv/
    dist/

This lab makes the document marker optional and disables line-length enforcement to avoid fighting the formatter. Flow mapping spaces allow Oxfmt output. Exempting keys from truthy checks accommodates keys such as GitHub Actions on; values such as yes still trigger diagnostics. Tighten these choices when appropriate. yamllint configuration

Merge the following editor settings. Disable the YAML extension's formatting provider so Oxfmt owns layout.

{
    "[yaml]": {
        "editor.defaultFormatter": "oxc.oxc-vscode"
    },
    "yaml.format.enable": false,
    "yaml.validate": true,
    "yaml.schemas": {
        "./config/app.schema.json": "config/app.yaml"
    }
}

Create config/app.schema.json to experiment without downloading a schema:

{
    "$schema": "https://json-schema.org/draft-07/schema#",
    "type": "object",
    "additionalProperties": false,
    "required": ["name", "enabled", "replicas"],
    "properties": {
        "name": { "type": "string" },
        "enabled": { "type": "boolean" },
        "replicas": { "type": "integer", "minimum": 1 }
    }
}

Reproduce a failure and decide the meaning

Start with this invalid policy example in config/app.yaml:

name: api
enabled: yes
replicas: 2
replicas: 3

yamllint flags the duplicate key and truthy value. Choose which replica count to keep yourself, then write the boolean explicitly:

name: api
enabled: true
replicas: 3

Run the first command on the bad file, then apply the correction before continuing. Strict mode -s treats warnings as failures. There is no yamllint automatic fix step here.

uv run --locked yamllint -c .yamllint.yaml config/app.yaml
npm exec -- oxfmt config/app.yaml
uv run --locked yamllint -c .yamllint.yaml -s config/app.yaml
npm exec -- oxfmt --check config/app.yaml

Now try replicas: many. It is valid YAML, so yamllint cannot enforce the application's integer contract. The editor's schema diagnostic should catch it. Add an actual schema validator or the consuming application's validation command if CI needs the same guarantee.

Send yamllint diagnostics to Problems

Create .vscode/tasks.json. Invoke Tasks: Run Task → lint:yaml; this task does not run automatically on save.

{
    "version": "2.0.0",
    "tasks": [
        {
            "label": "lint:yaml",
            "type": "process",
            "command": "uv",
            "args": [
                "run",
                "--locked",
                "yamllint",
                "-c",
                ".yamllint.yaml",
                "-f",
                "parsable",
                "-s",
                "config"
            ],
            "options": { "cwd": "${workspaceFolder}" },
            "problemMatcher": {
                "owner": "yamllint",
                "fileLocation": ["relative", "${workspaceFolder}"],
                "pattern": {
                    "regexp": "^(.+):(\\d+):(\\d+): \\[(warning|error)\\] (.+)$",
                    "file": 1,
                    "line": 2,
                    "column": 3,
                    "severity": 4,
                    "message": 5
                }
            }
        }
    ]
}

The matcher maps parsable output to file, line, column, and severity. Reintroduce yes, run the task, and verify that the Problems entry navigates to it. VS Code problem matchers

Encrypted inventories, Helm/Jinja templates, and pinned upstream manifests may need exclusions. Align the formatter and linter scopes, document why each exclusion exists, and name its replacement check.

Previous · Next