YAML format is used in many config files, and here are a few tips to make your yaml files look nicer.

Multiline text values

YAML since version 1.1 (2005) support block indicators to control how parser should handle multiline text. See interactive demo.

Examples:

>- means “treat single newline symbols ('\n') as spaces (' '), and remove all newlines at the end” (useful to put long description in a yaml key).

# yaml
key: >-
  very
  long
  text
# python
{ "key": "very long text" }

| means “keep newline symbols ('\n') as they are” (useful when writing multiple commands in a workflow for GitHub Actions ).

# yaml
key: |
  command1
  command2
  command3
# python
{ "key": "command1\ncommand2\ncommand3\n" }

Anchors

YAML since version 1.1 (2005) support anchors: a way to annotate a node for future reuse. &anchor at the beginning of a node value declares an anchor, *anchor value is expanded as anchored node. Use YAML online parser for experimenting.

Example:

# original yaml
first-key: &config
  key: value
  list:
    - item1
    - item2
second-key: *config
# parsed yaml
first-key:
  key: value
  list:
    - item1
    - item2
second-key:
  key: value
  list:
    - item1
    - item2

An anchor needs to be defined (&anchor) before it can be referenced (*anchor). Anchors are useful when we need to repeat certain sections without copy-pasting them.

Recently GitHub Actions added support of yaml anchors, but actionlint (a widely used linter for GitHub Actions) doesn’t support them yet.

Anchor limitations

Anchors are expanded as entire node, it’s impossible to add/remove/change keys of a dictionary or items in a list.

# INVALID
first-list: &items
  - item1
  - item2
second-list: *items
  - item3  # can't add items
# INVALID
first-list: &mapping
  key1: value1
  key2: value2
second-list: *mapping
  key3: value3  # can't add key/values

If we need to extend a mapping, we can use “merge key” feature.

Merge key Language-Independent Type

It’s an optional feature proposed for YAML 1.1 to merge multiple mappings defined by anchors into one node (<<: *anchor).

Example:

# original yaml
first-key: &config
  key: value
  foo: bar
second-key: &addon
  abc: xyz
target-1:
  <<: *config
  # add new key
  new-key: new value
  # override existing key
  key: another value
target-2:  # merge multiple mappings
  <<: [*config, *addon]
# parsed yaml
first-key:
  key: value
  foo: bar
second-key:
  abc: xyz
target-1:
  key: another value  # overridden
  foo: bar
  new-key: new value  # addede
target-2:  # combined
  key: value
  foo: bar
  abc: xyz

Check your yaml framework for support. For example PyYaml and ruaml.yaml support merge keys.

Merge key feature does not allow to merge lists.

References