settings section, and on every scheduled run smartcloud brings the repository back in line. That gives you:
- The same baseline everywhere. Put the settings in a preset and every repository that extends it gets them.
- A record of every change. Settings live in a file, so a change is a reviewed pull request, not a click nobody remembers.
- Self-healing settings. If someone changes a setting by hand, the next run puts it back.
Turn it on
Create a GitHub App (recommended) or a token
- In your organisation, open Settings > Developer settings > GitHub Apps > New GitHub App. Give it a name, set any homepage URL, and untick Webhook > Active: smartcloud runs from Actions and needs no webhook.
- Under Repository permissions, grant what the sections you use need. For every smartcloud feature together that is: Administration (read and write), Contents (read and write), Issues (read and write), Pull requests (read and write), Checks (read and write), Commit statuses (read), Workflows (read and write, for sync), Webhooks (read and write, for
settings.webhooks), Pages (read and write, forsettings.pages), Environments (read and write, forsettings.environments) and Variables (read, forsettings.variables). Forsettings.teams, also grant the organisation permission Members (read). - Create the app, note its App ID, and generate a private key.
- Install the app on the repositories it should manage (and on the repository that holds your presets, if it is private).
- In the repository or organisation, add the App ID as an Actions variable (for example
SMARTCLOUD_APP_ID) and the private key as an Actions secret (for exampleSMARTCLOUD_APP_PRIVATE_KEY).
repo scope (and workflow for sync) can change settings too, but GitHub never lets a personal token create check runs, so every smartcloud check fails to publish. Use a GitHub App. Run smartcloud doctor to check a token’s scopes and access.Pass the token to smartcloud
actions/create-github-app-token and give it to smartcloud as GITHUB_TOKEN. Keep the fallback to github.token, so a run where no token can be minted, such as a pull request from a fork, runs restricted instead of failing.schedule, workflow_dispatch and push events only.Add a settings section
Preview, then run
smartcloud plan settings, the MCP server’s plan_settings tool, or a run with the dryRun: true input. Then run the workflow from the Actions tab (Run workflow), or wait for the schedule.Options
Every key is optional. A key left out is left as GitHub has it.merging
features
security
ruleset
ruleset manages one ruleset on the default branch. A ruleset is GitHub’s modern branch protection: rules such as “no force pushes” or “these checks must pass” that apply to a branch. smartcloud finds its ruleset by name and updates it in place on every run.
codeScanning if it uploads results for every pull request, or nothing can merge. Every workflow behind a required check must also run on the merge_group event when you use a merge queue. On a private repository, rulesets need a paid plan, so a ruleset failure there is a warning.
The merge queue method must fit the ruleset
A merge queue lines pull requests up and merges them one group at a time, usingmergeQueue.method. Two other rules limit which methods can work, and a queue whose method breaks either of them can never merge anything:
linearHistory: truerules outmerge. Linear history means the branch has no merge commits, and themergemethod makes one for every pull request. GitHub would refuse every merge the queue tries.pullRequest.mergeMethodsmust include the queue’s method. That list says which ways a pull request may be merged. A queue told torebasewhile pull requests may only be squashed is asking for something the same ruleset forbids.
merge.
What you will see:
smartcloud validate(and the MCPvalidate_configtool) fails and names the key, for example["mergeQueue"]["method"]: the merge queue cannot use merge while linearHistory is on, because a merge commit breaks linear history; use squash or rebase, orthe merge queue method rebase is not one of pullRequest.mergeMethods (squash); add it there or use one of them.- A run never breaks for it. It ignores the method, uses one that fits instead (squash, or the first of rebase and merge that the ruleset allows), and reports a
config.ignoredwarning on thesmartcloud / configcheck, naming the file andsettings.ruleset.mergeQueue.method. smartcloud plan settings(and the MCPplan_settingstool) shows the ruleset with the method it will really use, and lists the ignored method under “Ignored, so not applied”.
method out and let smartcloud pick one:
environments
v*. smartcloud sets them to use custom deployment branch policies and creates a branch policy for the default branch and a tag policy for v* when they are missing; policies you added yourself are kept. It does not rely on GitHub’s “protected branches” option, because that counts only classic branch protection, and with none (this feature writes a ruleset instead) every branch could deploy. Staging, development, dev, preview and any name ending in “Beta” accept any branch.
actions
enabled whenever allowedActions or shaPinningRequired is sent, so setting either alone keeps Actions on. selectedActions is ignored unless allowedActions is selected, because GitHub rejects it otherwise.
The access level only exists for private and internal repositories: any repository can already use the actions of a public one. On a public repository it is left alone and a notice says so. Keep it at organization on a private repository whose reusable workflows the others call, such as a private .github repository; at none, every workflow that calls them fails before it starts.
Set workflowPermissions: read only when every workflow declares the permissions it needs. A workflow that relies on the default write access breaks.
collaborators and teams
webhooks
webhooks maps a name of your choosing to a webhook. smartcloud finds the webhook on GitHub by its url.
pages
legacy build type is set), then updated with the custom domain and HTTPS setting. An existing site is updated with what the config sets.
variables
variables maps each Actions variable the repository must have to a sentence saying what it is for. smartcloud only checks that the names exist. Values are never read, written or kept in the config. A missing variable is a warning that names it and its purpose, so a maintainer can add it by hand under Settings > Secrets and variables > Actions > Variables. Names compare ignoring case, since GitHub stores them in upper case, and names starting with GITHUB_ are reserved by GitHub and rejected by the schema.
Complete example
How it works
- The feature runs on
schedule,workflow_dispatchandpushevents. Other events never change settings. - smartcloud reads the repository, then plans one step per configured part, in a fixed order: merging, features, security, the ruleset, environments (each followed by its deployment policies), Actions, collaborators, teams, webhooks, Pages, then the variables check.
- Each step is applied on its own. A failed step is reported and the others still run.
- Some steps are expected to fail on some repositories, so their failure is a warning rather than an error: code scanning (no supported language), secret scanning, the ruleset on a private repository (rulesets need a paid plan there), and missing Actions variables.
What you will see on GitHub
- A
smartcloud / settingscheck run on the commit. It fails when a required step failed (for example a token without administration access), is neutral when only optional steps failed, and passes otherwise. Every run carries thesettings.push-limitnotice. - In the job summary, one change per step that was applied, such as
Ruleset "house: default branch"orCollaborator @hubot as write (invited if not yet a collaborator), and each failure with GitHub’s message, under a rule id likesettings.rulesetorsettings.collaborator:octocat. - On GitHub itself: the ruleset under Settings > Rules > Rulesets, named
house: default branchunless you setruleset.name, environments under Settings > Environments, and invitations for new collaborators.
Forks and restricted runs
Settings only ever runs with a token that can administer the repository. In a restricted run, which is any run with only the workflow token, a pull request from a fork, or Dependabot’s runs and pull requests, the feature is skipped and the job summary says “repository settings need an admin token”. Scheduled and manually dispatched runs never come from a fork, so they get your app token whenever it can be minted.In the house preset
The Resnovas house preset sets a full baseline: squash and rebase merges only, auto-merge, branch deletion and web sign-off on, squash commits titled from the pull request with every commit message kept; wiki off, discussions and sponsorships on; immutable releases, private vulnerability reporting, Dependabot alerts and security updates and secret scanning on, and CodeQL default setup off (the house runs CodeQL as advanced setup); ahouse: default branch ruleset with deletion and force-push blocked, linear history, a squash merge queue with allGreen, signed commits, one approval with stale reviews dismissed and conversations resolved, the smartcloud check required with strict, CodeQL at high_or_higher/errors, code quality at errors, coverage limits of 80 and 5 (off until enabled), provider secret alerts, Copilot review and admin bypass; and read-only workflow tokens that may open pull requests, with organisation access.
A repository extending it may still add what the preset leaves unset: settings.environments, ruleset.requiredDeployments, extra ruleset.statusChecks.checks, ruleset.codeScanning.ESLint, ruleset.codeCoverage.enabled, collaborators, teams, webhooks, pages and variables. It cannot change a value the preset sets; see Add, never change.
Troubleshooting
The job summary says settings was skipped: restricted access
The job summary says settings was skipped: restricted access
GITHUB_TOKEN, as in Turn it on, and run the workflow on a schedule or by hand. smartcloud doctor shows whether your token can administer the repository.Every step fails with Resource not accessible by integration or 403
Every step fails with Resource not accessible by integration or 403
repo scope. For a fine-grained token, add Administration (write).Code scanning or secret scanning fails with a warning
Code scanning or secret scanning fails with a warning
A required approval is not enforced
A required approval is not enforced
ruleset.pullRequest.requiredApprovals and ruleset.requiredChecks only bind once two or more distinct logins are in roles.maintainers, so a sole maintainer is never locked out. Add a second maintainer.Nothing can merge after adding code scanning or coverage rules
Nothing can merge after adding code scanning or coverage rules
codeScanning tool or codeCoverage.enabled: true blocks merging until results are uploaded for every pull request. Upload them (CodeQL workflow, actions/upload-code-coverage) or remove the rule. With a merge queue, every workflow behind a required check must also run on merge_group.ignored settings.ruleset.mergeQueue.method
ignored settings.ruleset.mergeQueue.method
merge while linearHistory is on, or it is not in pullRequest.mergeMethods. The run used a method that fits instead. Change mergeQueue.method to one that fits, or leave it out; see The merge queue method must fit the ruleset. If a preset sets both values, fix the preset.A missing variable warning
A missing variable warning
settings.variables lists a name that is not set. Add it by hand under Settings > Secrets and variables > Actions > Variables; smartcloud never writes values.cannot change settings.... it is set by a preset
cannot change settings.... it is set by a preset