Tooling for Maintaining YAML Files
Table of Contents
YAML is an essential part of modern software development. It has been an established format for configurations for years, and is unlikely to be replaced for a long time to come. Many, many products now use YAML for configuration, from developer tools and continuous integration pipelines to tools for managing systems like Kubernetes and Ansible.
Ideally, we generate YAML files. This ensures that they are valid, correctly formatted and consistent. However, many YAML files are manually edited, even if they were originally generated by systems. This article describes some standard tools that help us maintain YAML documents, regardless of how they are created or changed.
All of these tools become most effective when they work automatically. We can run them in text editors and with pre-commit hooks that call them when we commit changes to version control. We should also run them in continuous integration pipelines. If they run in continuous integration, we ensure that all of the YAML files in a project are always maintained to the same standard.
Formatting, Linting and Validating YAML #
These tools will work on files that use standard YAML:
- Prettier - Formats many types of file, including YAML
- yamllint - Lints YAML files
- check-jsonschema - Checks JSON and YAML files with identified types against their schema
You can run them with both Git hooks and on-demand by using a pre-commit tool. Since they are command-line tools, you can also run them as part of continuous integration pipelines.
All of these tools have useful default configurations, so you only need to add configuration files if you need to customize their behavior.
Prettier and schemas also work in modern text editors. These editors can run Prettier on your code. They usually require a plugin, but Zed has Prettier built-in. Editors use the same schemas as check-jsonschema for error checking and autocompletion.
Formatting with Prettier #
Prettier formats files for a wide range of programming languages and data types, including YAML. It is deliberately opinionated, so that every installation of Prettier formats files in exactly the same way, unless users decide to override it.
If your text editor supports Prettier and is configured to format YAML files on save then it works automatically. The Zed editor has Prettier built-in. For other editors, the documentation for the Prettier plugin should explain how to set it up.
Automated code formatting improves software projects for no cost. When we apply the same formatter on every change, the format of the code becomes consistent and predictable, which enables us to rapidly refactor projects. Automatic code formatting also removes the need for commits that only format files.
Linting with yamllint #
The yamllint tool ensures that files are valid YAML. It applies rules that are designed for standard YAML.
If you have YAML files that are templates, you will need to provide a custom configuration for yamllint, or use a specialized tool for the files that are in that format, such as cfn-lint for CloudFormation. For Ansible, we do both: the ansible-lint tool is intended to be used alongside yamllint.
By design,
yamllintignores files with a double file extension, such as.yaml.jinja. These files are likely to be templates.
Validation with check-jsonschema #
The schemas for YAML formats are JSON Schemas. Each schema is a JSON file that describes JSON or YAML. Vendors publish the schemas for their products to the Schema Store. You can create your own schemas.
Modern text editors like Visual Studio Code, JetBrains IDEs, Neovim and Zed use JSON Schemas for autocompletion and error-checking. These editors download schemas for YAML files from the Schema Store, which means that both editors and tools like check-jsonschema apply the same rules.
Visual Studio Code requires the redhat.vscode-yaml extension to support schemas for YAML.
The check-jsonschema tool checks YAML and JSON files against the relevant schema. It includes copies of schemas for popular tools and can use other schemas, including your own schemas. It also provides hooks.
Running Tools with prek or pre-commit #
The prek tool manages Git hooks and enables you to run the same actions at any time, not just when you commit changes. It can download the other runtimes and tools that the hooks need. This means that it can provide a cross-platform way to install and run a complete set of tools for formatting and checking code.
The prek tool supersedes pre-commit. It can use hooks that are written for
pre-commit, and works with existingpre-commitproject configurations.
Installing prek #
To install prek, use either pipx or uv:
pipx install prek
uv tool install prek
Adding Hooks To a Project #
The configuration must be in a file called .pre-commit-config.yaml file. Save this file in the root directory of your project:
---
repos:
- repo: builtin
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
- id: check-json
- id: check-toml
- id: check-yaml
- id: check-added-large-files
- repo: https://github.com/rbubley/mirrors-prettier
rev: "v3.5.2"
hooks:
- id: prettier
- repo: https://github.com/adrienverge/yamllint.git
rev: "v1.37.1"
hooks:
- id: yamllint
args: ["--strict"]
- repo: https://github.com/python-jsonschema/check-jsonschema
rev: "0.33.3"
hooks:
- id: check-github-workflows
- id: check-taskfile
This configuration enables Prettier, yamllint and check-jsonschema. It also includes check-yaml, one of the standard hooks. This hook is redundant, and you might choose to remove it.
To activate the configuration, run prek install. This adds the hooks to the Git configuration for your copy of the project, so that the tools automatically run on the staged changes each time that you commit.
cd my-project
prek install
Since the
prekconfiguration file is YAML, it will automatically be formatted and checked by the same tools thatprekruns itself.
Using Hooks #
The tools automatically run on the staged changes each time that you commit. To run a tool without commiting a change, use precommit run. If you add the option --all-files it will check the current files in the project, not just staged changes.
For example, to run the check-github-workflows hook on the project, use this command:
prek run check-github-workflows --all-files
To run all of the hooks on the project, use this command:
prek run --all-files
Updating Hooks #
To update all of the hooks to their current version, run this command:
prek auto-update
It automatically edits the .pre-commit-config.yaml file to update the versions of the hooks. You then commit this change to source control, so that other copies of the repository will use the same versions.