Configuration
Every key in .ghostbranch.yml, with its type, its default and what it changes.
.ghostbranch.yml holds a repo pair’s settings. It lives on the ghostbranch branch of the shadow repo, the overlay branch, and is never published. Every command that needs the settings reads them from there, never from a feature branch.
Change a setting
Section titled “Change a setting”- Check out the
ghostbranchbranch from the shadow repo, and edit.ghostbranch.yml. - Commit, and push the branch to the shadow repo. The next command reads the new settings.
- If you changed
sync.schedule, runghostbranch upgrade --plan, thenghostbranch upgrade, to add or remove the sync workflow.
The file init writes
Section titled “The file init writes”ghostbranch init writes this file, with your repos’ names:
# Ghostbranch configuration. It lives only on this shadow repo's# "ghostbranch" branch and is never promoted.version: 1public: you/projectshadow: you/project-shadow
promote: target: pr # preserve publishes each feature commit; squash publishes one commit; # curated regroups, reorders and rewords commits from a --curate file. default_mode: preserve # noreply publishes every commit as your GitHub noreply identity; keep # publishes the original authors; map uses author_map. author_email: noreply
leak_scan: strip: [".ghostbranch/**"] markers: begin: BEGIN-INTERNAL end: END-INTERNAL block_patterns: [] large_file: 5MB secrets: true
sync: # Scheduled sync is off: run ghostbranch sync yourself (commands warn when # shadow main falls behind public). To opt in, set a cron such as # "23 */6 * * *" (about 120 Actions minutes a month), then run # ghostbranch upgrade. schedule: "off" branches: [main]
ci: rewrite_repo_guards: rewrite
gate: ci_appear_timeout: 10m ci_timeout: 60mA key you leave out takes its default, shown in the tables below. Leave out a whole section rather than leaving it empty: an empty promote:, leak_scan: or gate:, or one with only comments under it, is read as a key Ghostbranch doesn’t know (see below). Only sync: and ci: may be empty.
Top level
Section titled “Top level”| Key | Type | Default | What it does |
|---|---|---|---|
version |
integer | 1 |
The file’s format. It must be 1. |
public |
owner/name |
none, required | The public repo. It must name this pair’s public repo. |
shadow |
owner/name |
none, required | The shadow repo. It must name this pair’s shadow repo. |
promote
Section titled “promote”The keys under promote: decide how promote publishes. See History modes.
| Key | Type | Default | What it does |
|---|---|---|---|
target |
string | pr |
What a publish makes. Only pr, a pull request, is supported. |
default_mode |
squash, preserve or curated |
preserve |
The history mode when promote has no --mode. |
author_email |
noreply, keep or map |
noreply |
Whose name each public commit carries: the publishing account’s GitHub noreply identity, each commit’s own author, or the identity author_map names. |
author_map |
map of email to "Name <email>" |
empty | The identity to publish for each author email, under author_email: map. Emails match ignoring case. With map, it must list at least one email. |
promote: author_email: map author_map: "you@laptop.local": "Your Name <you@example.com>"leak_scan
Section titled “leak_scan”The keys under leak_scan: decide what the leak scan looks for, and what is never published.
| Key | Type | Default | What it does |
|---|---|---|---|
strip |
list of path patterns | .ghostbranch/** |
More overlay paths: they may live on the overlay branch, and they are removed from everything published. |
secrets |
boolean | true |
Secret scanning. It must be true: it can’t be turned off. |
markers.begin |
string | BEGIN-INTERNAL |
The line that opens an internal section. |
markers.end |
string | END-INTERNAL |
The line that closes one. |
block_patterns |
list of regular expressions | [] |
Extra patterns the scan blocks, in Go’s regular expression syntax. |
large_file |
size | 5MB |
New or changed files larger than this give a LARGE_FILE warning. |
The details:
- Overlay paths:
.ghostbranch.yml,.ghostbranch/**and.github/workflows/ghostbranch-*always are, whateverstripsays. - Path patterns:
*and?never match a/;**matches across folders. A leading**/also matches no folder at all, so**/NOTES.mdmatchesNOTES.md, and a trailing/**matches everything under a folder. - Markers are matched ignoring case. Each must be one word (no spaces), not made only of comment characters such as
#,-or*, and the two must differ. A letter or a digit in each keeps them clear. - Sizes are a number of bytes, such as
1048576, or a whole number withKB,MBorGB(powers of 1024), such as512KB.
The keys under sync: decide how the shadow repo keeps up with public. See Sync.
| Key | Type | Default | What it does |
|---|---|---|---|
schedule |
"off" or a cron schedule |
"off" |
Scheduled sync: five cron fields, such as "23 */6 * * *", on one line. GitHub runs schedules at most every 5 minutes, so a minute field of * or */1 to */4 is refused. Run ghostbranch upgrade after changing it. |
branches |
list of branch names | [main] |
The branches sync fast-forwards from public. It must include main, and list each branch once. |
sync must be a section. To turn scheduled sync off, set schedule: "off"; sync: off is an error.
The key under ci: decides how the gate treats your workflows. See Repo guards.
| Key | Type | Default | What it does |
|---|---|---|---|
rewrite_repo_guards |
rewrite, warn or off |
rewrite |
What the gate does with jobs guarded to the public repo, such as if: github.repository == 'you/project'. rewrite rewrites the guard in the gate’s CI candidate only, so the job runs in the shadow repo. warn leaves it, so the job skips, and warns REPO_GUARD. off leaves it and doesn’t warn. |
If any guarded job deploys or publishes, use warn: a rewritten guard would run that job in the shadow repo, on unreleased code.
The keys under gate: decide how long the gate waits for CI. See Long CI.
| Key | Type | Default | What it does |
|---|---|---|---|
ci_appear_timeout |
duration | 10m |
How long to wait for the first check to appear. Past it, the gate fails with NO_CI. |
ci_timeout |
duration | 60m |
How long CI may run, counted from the start of the gate. Past it, the gate fails with CI_TIMEOUT. |
A duration is a number with a unit, such as 90s, 10m or 1h30m, and must be more than zero.
Keys Ghostbranch doesn’t know
Section titled “Keys Ghostbranch doesn’t know”A key Ghostbranch doesn’t know is an error, at any level, sync: and ci: included, so a typo is never silently ignored. Commands stop with UPGRADE_NEEDED and name the key in error.details.unknown_key: the file may have been written by a newer Ghostbranch, so upgrade, or fix the typo.
Two kinds of key only warn, with CONFIG_KEY_IGNORED:
- keys under
agents:; promote.require_human, which agent grants replaced (see Letting agents publish).
A bad value, or a file that names another pair, stops commands with CONFIG_INVALID. So does a file on the overlay branch that isn’t an overlay path.
Errors you may see
Section titled “Errors you may see”CONFIG_INVALIDexit 1.ghostbranch.yml on the overlay branch is missing or invalid, or the overlay branch holds non-overlay paths.
A person fixes .ghostbranch.yml on the shadow repo's ghostbranch branch.
This needs a person.
UPGRADE_NEEDEDexit 1Something this pair uses was written by a newer Ghostbranch: a record (error.details.record: feature, plan, grants or waivers) or the overlay config (error.details.unknown_key, a key this binary doesn't know).
Upgrade ghostbranch on this machine to the version that wrote it, or newer (the other machine is probably newer). Don't edit the record or the overlay config to make an older binary accept it. If the key in error.details.unknown_key is a typo, a person fixes it in .ghostbranch.yml on the overlay branch.
CONFIG_KEY_IGNOREDwarning.ghostbranch.yml has a key this version does not use.
Nothing is required; remove the key to silence the warning.
OVERLAY_OUTDATEDwarningA Ghostbranch-managed file on the overlay branch is missing, out of date, or edited by hand.
Run ghostbranch upgrade --plan to see the change, then ghostbranch upgrade.