Skip to main content
A preset is a smartcloud config file that other repositories build on. You write your organisation’s rules once, in one place, and every repository that lists the preset under extends gets them. Change the preset and every repository follows on its next run. Why use one:
  • One source of truth. Labels, title rules, review rules and repository settings stay the same everywhere.
  • Rules that stick. A repository can add to a preset but cannot weaken it. A contributor cannot quietly turn off the DCO check in one repository.
  • Short configs. A repository’s own file holds only what makes it different.

Use a preset

1

Name it under extends

Add an extends list to .github/smartcloud.yml. Each entry is owner/repo/path@ref:
.github/smartcloud.yml
2

Make sure the token can read it

smartcloud reads presets through the GitHub API with the token it acts with. A preset in a public repository, or in the same repository, always works. A preset in another private repository needs a token that can read it, such as a GitHub App installed on both repositories. With only the workflow token, the preset is skipped with a warning; see Reading presets.
3

Check it

“Built from” lists every file, in the order they were merged. The CLI needs a token to read presets; it uses GITHUB_TOKEN or the GitHub CLI’s login.
Pinning a tag or commit (@v1.2.0) means the preset only changes when you move the ref. Tracking a branch (@main) means every repository picks up a change on its next run.

Write a preset

A preset is an ordinary config file with version: 2. Put it in any repository, commonly the organisation’s .github repository. It may extend presets of its own, up to five levels deep.
my-org/.github/smartcloud/typescript.yml
Leave out anything a repository should decide for itself. Whatever the preset sets, repositories cannot change. Recommended setups has a complete preset and a repository file that extends it, and Your organisation’s sync hub walks through hosting presets and shared files in your own .github repository, from creating it to rolling a change out to every repository.

How files are merged

Presets are merged first, in the order listed. Each preset’s own presets come before it. The repository’s config comes last.
Rules are keyed maps, never lists (see Configuration), so two files talking about the same key are talking about the same rule. version, extends and $schema describe a file rather than rules, so they are never merged.

Add, never change

Everything a preset sets is locked. A repository may add to what it inherits, but never change or remove it:
  • Adding is allowed. A new label, a new rule, or a new field on an inherited rule that the preset left unset.
  • Identical restatements are allowed. Repeating an inherited value exactly as it already is changes nothing, so a repository can keep a full copy of a rule without error.
  • Changing is an error. Any other value for something already set, whether a scalar, a list or a different shape, fails the whole run.
Lists are values, not collections to append to: if a preset sets roles.maintainers, a repository cannot add a name to it. Given a preset like this one (an example, not the Resnovas house preset):
your-org/.github/smartcloud/base.yml
This repository config is valid: it restates bug identically, adds a description the preset left unset, and adds a new label.
.github/smartcloud.yml
Changing the colour instead fails with an error naming the path and the preset that set it:
The same rule applies between presets: a later preset cannot change what an earlier one set. A value a preset sets that this version of smartcloud cannot read is dropped from the preset but stays locked: your config cannot set that key either, and a value it sets there is ignored with a warning. A preset that asks for a stricter setting than this version knows can never be turned into a weaker one. See Unknown keys and invalid values.

”I need something different from the preset”

Because locked values cannot change, you have three honest options:
  1. Add a new rule next to it. For example, a second convention rule with its own key, or an extra label. This is what the error message suggests.
  2. Fill in what the preset left open. Presets often leave fields unset on purpose, such as sync.exclude or settings.environments, so each repository adds its own.
  3. Change the preset, or stop extending it and copy what you need. If a rule is wrong for one repository, it is usually wrong in the preset.

Reading presets

The action reads presets through the GitHub API with its own token, so a preset in a private repository needs a token that can read that repository. A restricted run, such as a pull request from a fork or a run with only the workflow token, leaves out a preset from another repository that its token cannot read. It warns that the preset’s rules were not checked (access.config-skipped) rather than failing, and each feature’s check that would pass concludes as neutral with “config left out” in its title. A missing preset in the repository itself still fails the run. See Restricted runs. These problems fail the run, because the config as a whole cannot be trusted:

The Resnovas house preset

Every Resnovas repository extends Resnovas/.github/smartcloud/house.yml@main, the house preset. It lives in the public Resnovas/.github repository, so any token can read it, including the read-only token of a pull request from a fork. The settings and sync sections it sets still need the Resnovas Bot app token, which the house workflow mints; forks and Dependabot run without it, restricted. What it turns on: Left unset on purpose, so each repository adds its own:
  • settings.environments (a projectType such as library, or named environments);
  • settings.ruleset fields requiredDeployments, statusChecks.checks (the repository’s CI job), codeScanning.ESLint and codeCoverage.enabled;
  • sync.exclude, for template files the repository keeps its own copy of;
  • required.expect, the check names the aggregate must wait for;
  • any other labels, labelling rules, stale, lock, backport, freeze, notifications or commands sections.
The feature pages each have an In the house preset section with the details.

house:managed and house:local

In a Resnovas repository you do not write the extends line yourself. The sync feature keeps .github/smartcloud.yml in line with a template, using a managed block:
.github/smartcloud.yml
  • Between house:managed:begin and house:managed:end is the house’s part. Sync rewrites it, and a pull request that edits it fails the sync edit check (rule SYNC).
  • Below house:local is the repository’s part. Sync never touches it. Put your additions here.
“Override” in a Resnovas repository therefore means add below house:local, within the add-never-change rule: new labels and rules, and the keys the house preset leaves unset. A value the house preset already sets cannot be changed there; restating it exactly is allowed, but any other value fails the run. To change a house value, change house.yml in Resnovas/.github.

Troubleshooting

Your file gives a different value for something a preset already set. Remove the line, or restate it exactly as the preset has it, or add a new rule with a new key. See Add, never change.
The run was restricted and could not read a preset in another private repository. This is expected on pull requests from forks and from Dependabot. On your own pull requests, pass a token that can read the preset, such as a GitHub App installed on both repositories.
The path, repository or ref is wrong, or the token cannot see the repository. Check the entry by opening https://github.com/owner/repo/blob/ref/path. Run smartcloud doctor to test the token.
The preset uses a key this version of smartcloud does not know, usually because the preset was written for a newer release. The run carries on without it. Update the action (resnovas/smartcloud@v2 moves with every v2 release) to pick it up.
Follow the chain in the message and remove one extends entry so the chain ends.
Last modified on September 28, 2026