# actions/labeler: path and branch rules for pull request labels

> GitHub's official labeler action applies labels from a .github/labeler.yml file using glob and regexp rules. Version 7 only changes the internals to ESM; the configuration format is the part that will actually cost you time.

**actions/labeler** — An action for automatically labelling pull requests. What's changed in V7 Migrated to ESM internally to support the latest @actions/* package versions.

- Repository: https://github.com/actions/labeler
- Stars: 2,499 · Forks: 491
- Language: TypeScript
- License: MIT
- Published: 2026-08-08 · Updated: 2026-08-18 · Language: en
- Canonical page: https://hysenlabs.com/projects/actions-labeler

## What actions/labeler does that GitHub's label settings do not

GitHub repositories can define labels, but nothing in the repository settings decides which label a given pull request deserves. Someone reads the diff and clicks. actions/labeler replaces that click with a rule file: the README describes it as an action that automatically labels new pull requests based on the paths of files being changed or the branch name. The audience is maintainers of repositories where the same paths keep arriving: a docs/ tree that should be flagged for a technical writer, a migrations/ directory that should never merge without a database reviewer, a release/* branch that should carry the release label. The action matters most when the mapping from path to label is stable and boring. If the mapping changes every sprint, a rule file becomes another artifact to maintain. The README does not discuss label removal beyond the sync-labels input mentioned in the v5 notes, so treat it as an additive tool first.

## How the match object turns globs and regexps into one boolean decision

The configuration is a map from label name to a list of match objects. Each match object can carry three things: changed-files with globs, base-branch with regexps, and head-branch with regexps. The README states the boolean logic plainly: top-level match objects and options inside all are AND-ed, while individual rules inside any are OR-ed. A base option written without a top-level key defaults to any, so a single changed-files entry behaves the same whether or not you wrap it in any. Inside changed-files there are four combinations, and they are the part people get wrong. any-glob-to-any-file asks whether any glob matches any changed file. any-glob-to-all-files asks whether one glob matches every changed file. all-globs-to-any-file asks whether every glob matches at least one file. all-globs-to-all-files asks for every glob to match every file. The globs come from minimatch, and the README notes that combining globs with ! negation lets you write complex rules. Two configuration keys cap the work: changed-files-labels-limit sets how many new labels may be applied from changed files, and max-files-changed skips all file-based labeling when a pull request is too large. Both must be non-negative integers. The second one is the honest admission that a tree-wide refactor will otherwise match half your label set.

## Setting up .github/labeler.yml and labelling your first pull request

The action is consumed from the GitHub Actions marketplace, so there is no package to install locally. You add a configuration file and a workflow file to your repository. The README's usage section starts with creating .github/labeler.yml, where the key is the label name and the value is a match object. A minimal file that labels any change under docs/ looks like this:

```yaml
Documentation:
- changed-files:
  - any-glob-to-any-file: docs/**
```

A second rule can key off the branch name instead of the files, using the base-branch and head-branch regexps the v5 release added:

```yaml
Documentation:
- changed-files:
  - any-glob-to-any-file: docs/**
- head-branch: ['^release']
```

After pushing a branch that edits a file under docs/, open a pull request and the Documentation label should appear without anyone clicking. If it does not, check the workflow run log first, then confirm the glob actually matches the changed path: docs/** covers nested files, docs/* does not. The README also warns that the pull_request_target event trigger deserves attention before upgrading to v5, so read that section before choosing between the two triggers.

## The v5 configuration break and what v7 actually changes

The version history here is unusually load-bearing. Version 5 redesigned the configuration file structure and the README says it is not compatible with the previous structure, so any labeler.yml written for v4 has to be rewritten, not tweaked. The same release added base-branch and head-branch matching, fixed the sync-labels input so its value is read correctly, and changed the dot input default to true, which means paths beginning with a dot such as .github are now matched by default. Version 6 moved the runtime from node20 to node24 and the README tells you to make sure your runner is on v2.327.1 or later. Version 7, released on 2026-07-21, migrated the action to ESM internally to support the latest @actions/* package versions, and the README states there are no changes to inputs, outputs, or behavior. That last claim is the one to hold onto: if you are on v6, the v7 upgrade is a version bump in your workflow file, not a configuration migration. The last push to the repository was on 2026-07-21, the same day v7.0.0 was released.

## Where the rule engine stops being the right tool

Two limits are visible in the documentation. First, file-based labeling is all-or-nothing once max-files-changed is exceeded: the README says that when the limit is passed, all file-based labeling is skipped for that run. A pull request that regenerates a lockfile and touches forty directories therefore arrives unlabelled, which is exactly the kind of pull request where a human most wants a hint. Second, the same all-or-nothing applies per run to changed-files-labels-limit: if the number of new labels would exceed it, no changed-files labels are applied at all. Neither key degrades gracefully, and the README does not describe a partial mode. The action also cannot judge code. It sees paths and branch names, so a one-line change to a payment module and a whitespace fix in the same file look identical. Teams that need review routing based on ownership rather than path should look at CODEOWNERS, which this repository itself uses at the top level. And because the action only reads what the event payload exposes about changed files, a rule written against a path outside the diff will simply never fire.

## How actions/labeler compares with a scripted gh CLI step

The obvious alternative is a shell step in your own workflow that calls the GitHub CLI or the REST API directly. The difference is where the rule logic lives. With actions/labeler, globs and regexps live in a declarative YAML file that the action parses with js-yaml and evaluates with minimatch, and the boolean combination of any and all is defined by the action rather than by your code. With a scripted step, you write the matching yourself, which means you also own the edge cases: negation, dotfile defaults, and the four glob-to-file combinations. The action also retries API calls through @octokit/plugin-retry, which a naive curl loop will not do. The trade-off runs the other way for anything the action does not model, such as labelling based on commit message content or on the size of the diff in lines, because those need code the action does not have. A third option is to skip automation entirely and let reviewers apply labels, which costs nothing to maintain and fails as soon as the repository gets busy.

## Licence, maintenance and the cost of staying current

The repository is MIT licensed, which permits commercial use and modification; this is a statement about the licence text, not legal advice, and the LICENSE file at the repository root is the authority. The action is not archived and the last push was on 2026-07-21. Maintenance cost here is mostly configuration drift. Every new top-level directory in your repository is a candidate for a new rule, and every rule you add interacts with the any and all logic in ways that are easy to misread. The upgrade path has been disruptive once, at v5, when the configuration structure changed; v6 and v7 are runtime and packaging changes. Pinning the major version, actions/labeler@v7, means you receive patch and minor updates without editing your workflow, and the README's v7 note about unchanged behavior is what makes that pinning reasonable. If you pin v6 or v7, the runner version requirement of v2.327.1 or later applies.

## Conclusion

Adopt actions/labeler if your repository already depends on labels for triage, review routing, or release automation and you are willing to maintain a .github/labeler.yml file. Do not adopt it if you only want a handful of static labels, since GitHub's own label settings cover that without a workflow. Before rolling it out, decide between the pull_request and pull_request_target triggers, because the README treats that choice as important enough to flag before the v5 upgrade, and verify that your runners are on v2.327.1 or later if you pin v6 or v7. Then run one pull request that touches a glob you expect to match and confirm the label actually appears.

## FAQ

### What is actions/labeler?

It is a GitHub Action that automatically labels new pull requests based on the paths of files being changed or the branch name. Labels and their matching rules are defined in a .github/labeler.yml file.

### What changed in actions/labeler v7?

The README states that v7 migrated the action to ESM internally to support the latest @actions/* package versions, with no changes to action inputs, outputs, or behavior. The v7.0.0 release is dated 2026-07-21.

### What is the difference between any-glob-to-any-file and all-globs-to-all-files in actions/labeler?

any-glob-to-any-file applies the label when any glob matches any changed file. all-globs-to-all-files requires every glob to match every changed file, which is the strictest of the four changed-files combinations the README documents.

### Does actions/labeler still work with an older labeler.yml file?

Not if the file was written for v4. The README says the v5 configuration structure was significantly redesigned and is not compatible with the previous structure, so those files must be adapted.

### What happens in actions/labeler when a pull request changes too many files?

The max-files-changed option sets a maximum number of total changed files. If it is exceeded, the README states that all file-based labeling is skipped for that run.

## Sources

- [Official README](https://github.com/actions/labeler#readme)
- [Project repository](https://github.com/actions/labeler)
- [Release notes](https://github.com/actions/labeler/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/actions-labeler
