> ## Documentation Index
> Fetch the complete documentation index at: https://smartcloud.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Labels

> Keep repository labels in line with the config, and apply them by condition.

The labels feature does two jobs:

* **Label sync.** On repository events (push, schedule, manual dispatch, repository dispatch and merge queue), it makes the repository's labels match the `labels` section.
* **Labelling.** On pull request and issue events, it adds and removes labels on the subject as its `labelling` rules pass and fail.
* **Size labels.** A `sizeLabels` section adds built-in `Size: XS` to `Size: XL` labels, applied to pull requests by how many lines they change.

It is enabled when the config has a `labels`, `labelling` or `sizeLabels` section.

```yaml theme={null}
labels:
  bug:
    name: "Type: Bug"
    color: D73A4A
    description: Something is not working
    aliases: [bug, defect]
  docs:
    name: "Type: Documentation"
    color: "#0075CA"
  xs:
    name: "Size: XS"
    color: C2E0C6

labelSync:
  prune: false

labelling:
  docs:
    label: docs
    when:
      condition:
        - type: filesMatch
          condition: "docs/**"
  xs:
    label: xs
    on: [pullRequest]
    when:
      condition:
        - type: changesSize
          min: 0
          max: 10
  bug-issue:
    label: bug
    on: [issue]
    when:
      condition:
        - type: titleMatches
          condition: "/\\bbug\\b/i"
```

## Label sync

Each entry in `labels` is keyed by an id you choose, and has a `name`, a `color` (six hex digits, with or without `#`), and optionally a `description` and `aliases`.

* A configured label is matched to a repository label by name, ignoring case, and updated when its colour or description differs.
* Failing that, a repository label named in `aliases` is renamed, so issues carrying the old name keep the label. Exact names are matched before aliases, so an alias never takes a label another entry names directly.
* Anything else is created.
* A `description` left out of the config is left as it is on GitHub.
* GitHub accepts descriptions of up to 100 characters. A label with a longer one is reported as an error and left as it is, and the rest still sync.
* When two entries name the same label, ignoring case, only the first is synced, with a warning.
* With `labelSync.prune: true`, repository labels the config does not define are deleted. A label named in an entry's `aliases` counts as defined, even when the entry's own name already exists. Pruning is off by default.

Label sync never runs on pull request events: those from forks carry a read-only token.

<Note>
  v1's `skipDelete` input deleted unconfigured labels unless it was set. v2 never deletes a label unless `labelSync.prune` is `true`.
</Note>

## Labelling

Each rule in `labelling` names a `label`, an optional `on` (`pullRequest`, `issue`, or both by default), and a `when` [condition group](/conditions).

* `label` is a key of `labels`, and the label's `name` is what gets applied. A value that is not a key is used as the label's name itself.
* A label is added when any rule for it passes, and removed when every rule for it fails. Several rules may name the same label, for example one per subject kind.
* Names compare ignoring case, as GitHub does.
* If a label has already gone when smartcloud removes it, that is a warning, not a failure.
* If GitHub forbids adding or removing a label, as it does on the read-only token of a pull request from a fork, that is a warning (`labels.add` or `labels.remove`), not a failure, and the rest of the run carries on.

## Size labels

`sizeLabels` adds five labels and a labelling rule for each, so every pull request carries one size label that moves as the pull request grows or shrinks:

```yaml theme={null}
sizeLabels: {}
```

| Key       | Label      | Lines added plus deleted |
| --------- | ---------- | ------------------------ |
| `size-xs` | `Size: XS` | 0 to 9                   |
| `size-s`  | `Size: S`  | 10 to 99                 |
| `size-m`  | `Size: M`  | 100 to 499               |
| `size-l`  | `Size: L`  | 500 to 999               |
| `size-xl` | `Size: XL` | 1000 or more             |

Each size's band starts at its threshold and stops just before the next size's. Change any threshold under `thresholds`. Any size you leave out keeps its default, and the thresholds must rise from `s` to `xl`:

```yaml theme={null}
sizeLabels:
  thresholds:
    s: 20
    xl: 2000
```

* The preset's labels and rules are ordinary `labels` and `labelling` entries, so label sync creates the labels, and `labelSync.prune` counts them as defined.
* A `labels` or `labelling` entry you write with the same key replaces the preset's. For example, define `labels.size-xl` to rename or recolour XL, or `labelling.size-xl` to change when it applies. A renamed size keeps its built-in name among its `aliases`, so label sync renames the existing label instead of leaving the old one on pull requests.
* The rules use the [`changesSize`](/conditions) condition and apply to pull requests only.
