CLI
The ermite binary also drives a running server over its API. Run ermite <command> --help for the details of each command.
Connect to a server
| Setting |
Environment |
Config file key |
| server address |
ERMITE_URL |
url |
| token (optional for public reads) |
ERMITE_TOKEN |
token.cmd, a command that prints it |
The environment wins over the config file.
ermite config set url https://git.example.com
ermite config set token.cmd 'pass show ermite/token'
ermite config show [--json] # path and values
ermite config unset <key>
The file holds no secret, only the command that fetches the token (pass, gopass show -o, op read, secret-tool lookup, …):
# ~/.config/ermite/config
url = https://git.example.com
token.cmd = pass show ermite/token
Location: $XDG_CONFIG_HOME/ermite/config, ~/Library/Application Support/ermite/config on macOS, %AppData%\ermite\config on Windows. ERMITE_CONFIG names another file.
A token sent over plain http:// to a non-loopback host prints a warning.
How token.cmd runs
- Through
sh -c (cmd /C on Windows), at most once per run, only when a command needs the token.
- It gets your terminal when stdin is one, so pinentry or biometric prompts work.
- It must print the token alone on one line, under 4 KiB, within 60 seconds. On timeout or interrupt it is killed.
- A failure is reported in one line, without the command's output.
It does not run:
- when
ERMITE_TOKEN is set;
- for
ermite version, ermite config or shell completion;
- when
ERMITE_URL points to another server than the file's url (the call is anonymous; set ERMITE_TOKEN);
- when the file or its directory is writable by other users, or owned by another user (not checked on Windows).
Commands
ermite repo list | show <name> | create <name> [--description …] [--visibility public]
ermite repo edit <name> [--description …] [--visibility …] [--default-branch …] [--merge-modes …] [--allow-auto-merge] [--issues off|owner|public]
ermite repo delete <name> [--yes]
ermite token create <label> [--preset cli|agent|ci|runner] [--scope …] [--repo …] [--branch-prefix …] [--expires 30d]
ermite token list | revoke <id>
ermite mr create <repo> --source <branch> --title … | list <repo> | show <repo> <n> [--diff] # show prints the mergeability: up to date, behind, conflict
ermite mr comment <repo> <n> -m … [--path … --line N|A-B --side old|new] [--reply <id>] [--approve|--request-changes]
ermite mr resolve <repo> <n> <comment> | edit-comment <repo> <n> <comment> -m … | delete-comment <repo> <n> <comment>
ermite mr ready <repo> <n> # removes WIP:/[WIP], needs mr:write
ermite mr merge <repo> <n> --head <id> [--mode fast-forward|squash|merge] [--delete-branch] [--ignore-checks] | merge <repo> <n> --head <id> --auto [--mode …] | merge <repo> <n> --cancel-auto | close <repo> <n>
ermite issue create <repo> --title … [--body … | --body-file …] | list <repo> [--state open|closed|all]
ermite issue show <repo> <n> | comment <repo> <n> -m … | close <repo> <n> | reopen <repo> <n>
# issue show prints `closed by !N` when a merge closed it, and a `merge requests (K)` block (`!5 open <title> · closes`); --json adds closed_by_merge_request and references
ermite run list <repo> [--workflow …] [--branch …] [--status …]
ermite run view <repo> <id> [--attempt n] [--log [--job …]] [--summary]
ermite run watch <repo> <id> [--log] | cancel <repo> <id> | rerun <repo> <id> [--failed]
ermite run artifacts <repo> <id> | download <repo> <id> [--name N]… [--dir D]
ermite workflow run <file> --repo <repo> [--ref …] [-f name=value …]
ermite workflow list <repo> [--json]
ermite workflow disable <repo> <file> # no event starts a run of it; the file need not exist yet
ermite workflow enable <repo> <file>
ermite runner list | remove <id>
ermite secret set|list|delete … # CI secrets (needs ERMITE_SECRETS_KEY)
ermite variable set|get|list|delete …
ermite environment create|list|delete … --repo <repo>
ermite mirror key show | rotate # SSH key to add to the remote (rotate: owner only)
ermite mirror config [--enabled] [--url …{repo}…] [--cron …] [--all-branches] | config show # global policy, owner only
ermite mirror add <repo> <url> [--cron …] [--all-branches] | remove <repo> | exclude <repo> | include <repo>
ermite mirror status [repo] | sync <repo>|--all [--force] # sync --all: one row per repository, exit 1 if any failed
ermite web login # one-time sign-in link (60 s)
ermite web logout --all # sign every browser out
ermite web passkey list | remove <id>
ermite signing-key show # public key of squash and merge commits (server-signed)
ermite oidc rotate-key
ermite watch [repo] [--json] # follow live events
ermite version # client and server versions
ermite completion bash|zsh|fish
Issues need a server with the issues feature and ermite repo edit <repo> --issues owner (or --issues public, which also opens a moderated form to visitors of a public repository); they are written with the issue:write scope. See Issues.
Mirrors push repositories to a remote over SSH, never forcing. See Push mirror.
Output
--json prints stable field names (listed in each --help) on repo list|show|create|edit, issue create|list|show|comment|close|reopen, token create|list, run list|view|cancel|rerun, runner list, mirror key|config|status and version.
watch --json prints one object per line. merge_request_mergeability events carry mergeability (state, behind, conflict_paths…) and print as repo!n mergeability: behind by 2.
- A merge needs passing checks on the head (no failed, queued or running checks); a head with no checks can merge.
mr merge --ignore-checks bypasses this, needs mr:force-merge, and cannot be combined with --auto or --cancel-auto. The cli preset includes mr:force-merge; agent does not. Adding --scope mr:merge lets an agent merge only with passing checks.
mr merge --mode squash|merge creates a commit signed by the server's own key (generated on first start); the output names its fingerprint, ermite signing-key show prints the key. Every mode is allowed by default; repo edit --merge-modes fast-forward,squash disables merge.
mr merge --auto makes the server merge once CI passed on the head (repo edit --allow-auto-merge first); --cancel-auto cancels it; both are exclusive with each other and --auto with --delete-branch. watch --json adds merge_request_auto_merge_enabled, merge_request_auto_merge_cancelled (with reason), and auto (true) on merge_request_merged after an auto-merge. See Merge requests.
- Errors are one line on stderr (
ermite: …) with exit status 1.
- Shell completion completes repository names from the server.
ermite mr create and ermite mr close print a confirmation followed by the full
merge request web URL on its own line. With --json, merge request objects
(create, show, list, close and merge) include url alongside the other fields.
source
1# CLI
2
3The `ermite` binary also drives a running server over its API. Run `ermite <command> --help` for the details of each command.
4
5## Connect to a server
6
7| Setting | Environment | Config file key |
8|---|---|---|
9| server address | `ERMITE_URL` | `url` |
10| token (optional for public reads) | `ERMITE_TOKEN` | `token.cmd`, a command that prints it |
11
12The environment wins over the config file.
13
14```sh
15ermite config set url https://git.example.com
16ermite config set token.cmd 'pass show ermite/token'
17ermite config show [--json] # path and values
18ermite config unset <key>
19```
20
21The file holds no secret, only the command that fetches the token (`pass`, `gopass show -o`, `op read`, `secret-tool lookup`, …):
22
23```ini
24# ~/.config/ermite/config
25url = https://git.example.com
26token.cmd = pass show ermite/token
27```
28
29Location: `$XDG_CONFIG_HOME/ermite/config`, `~/Library/Application Support/ermite/config` on macOS, `%AppData%\ermite\config` on Windows. `ERMITE_CONFIG` names another file.
30
31A token sent over plain `http://` to a non-loopback host prints a warning.
32
33### How `token.cmd` runs
34
35- Through `sh -c` (`cmd /C` on Windows), at most once per run, only when a command needs the token.
36- It gets your terminal when stdin is one, so pinentry or biometric prompts work.
37- It must print the token alone on one line, under 4 KiB, within 60 seconds. On timeout or interrupt it is killed.
38- A failure is reported in one line, without the command's output.
39
40It does not run:
41
42- when `ERMITE_TOKEN` is set;
43- for `ermite version`, `ermite config` or shell completion;
44- when `ERMITE_URL` points to another server than the file's `url` (the call is anonymous; set `ERMITE_TOKEN`);
45- when the file or its directory is writable by other users, or owned by another user (not checked on Windows).
46
47## Commands
48
49```sh
50ermite repo list | show <name> | create <name> [--description …] [--visibility public]
51ermite repo edit <name> [--description …] [--visibility …] [--default-branch …] [--merge-modes …] [--allow-auto-merge] [--issues off|owner|public]
52ermite repo delete <name> [--yes]
53
54ermite token create <label> [--preset cli|agent|ci|runner] [--scope …] [--repo …] [--branch-prefix …] [--expires 30d]
55ermite token list | revoke <id>
56
57ermite mr create <repo> --source <branch> --title … | list <repo> | show <repo> <n> [--diff] # show prints the mergeability: up to date, behind, conflict
58ermite mr comment <repo> <n> -m … [--path … --line N|A-B --side old|new] [--reply <id>] [--approve|--request-changes]
59ermite mr resolve <repo> <n> <comment> | edit-comment <repo> <n> <comment> -m … | delete-comment <repo> <n> <comment>
60ermite mr ready <repo> <n> # removes WIP:/[WIP], needs mr:write
61ermite mr merge <repo> <n> --head <id> [--mode fast-forward|squash|merge] [--delete-branch] [--ignore-checks] | merge <repo> <n> --head <id> --auto [--mode …] | merge <repo> <n> --cancel-auto | close <repo> <n>
62
63ermite issue create <repo> --title … [--body … | --body-file …] | list <repo> [--state open|closed|all]
64ermite issue show <repo> <n> | comment <repo> <n> -m … | close <repo> <n> | reopen <repo> <n>
65# issue show prints `closed by !N` when a merge closed it, and a `merge requests (K)` block (`!5 open <title> · closes`); --json adds closed_by_merge_request and references
66
67ermite run list <repo> [--workflow …] [--branch …] [--status …]
68ermite run view <repo> <id> [--attempt n] [--log [--job …]] [--summary]
69ermite run watch <repo> <id> [--log] | cancel <repo> <id> | rerun <repo> <id> [--failed]
70ermite run artifacts <repo> <id> | download <repo> <id> [--name N]… [--dir D]
71ermite workflow run <file> --repo <repo> [--ref …] [-f name=value …]
72ermite workflow list <repo> [--json]
73ermite workflow disable <repo> <file> # no event starts a run of it; the file need not exist yet
74ermite workflow enable <repo> <file>
75ermite runner list | remove <id>
76ermite secret set|list|delete … # CI secrets (needs ERMITE_SECRETS_KEY)
77ermite variable set|get|list|delete …
78ermite environment create|list|delete … --repo <repo>
79
80ermite mirror key show | rotate # SSH key to add to the remote (rotate: owner only)
81ermite mirror config [--enabled] [--url …{repo}…] [--cron …] [--all-branches] | config show # global policy, owner only
82ermite mirror add <repo> <url> [--cron …] [--all-branches] | remove <repo> | exclude <repo> | include <repo>
83ermite mirror status [repo] | sync <repo>|--all [--force] # sync --all: one row per repository, exit 1 if any failed
84
85ermite web login # one-time sign-in link (60 s)
86ermite web logout --all # sign every browser out
87ermite web passkey list | remove <id>
88ermite signing-key show # public key of squash and merge commits (server-signed)
89ermite oidc rotate-key
90ermite watch [repo] [--json] # follow live events
91ermite version # client and server versions
92ermite completion bash|zsh|fish
93```
94
95Issues need a server with the `issues` feature and `ermite repo edit <repo> --issues owner` (or `--issues public`, which also opens a moderated form to visitors of a public repository); they are written with the `issue:write` scope. See [Issues](issues.md).
96
97Mirrors push repositories to a remote over SSH, never forcing. See [Push mirror](mirror.md).
98
99## Output
100
101- `--json` prints stable field names (listed in each `--help`) on `repo list|show|create|edit`, `issue create|list|show|comment|close|reopen`, `token create|list`, `run list|view|cancel|rerun`, `runner list`, `mirror key|config|status` and `version`.
102- `watch --json` prints one object per line. `merge_request_mergeability` events carry `mergeability` (`state`, `behind`, `conflict_paths`…) and print as `repo!n mergeability: behind by 2`.
103- A merge needs passing checks on the head (no failed, queued or running checks); a head with no checks can merge. `mr merge --ignore-checks` bypasses this, needs `mr:force-merge`, and cannot be combined with `--auto` or `--cancel-auto`. The `cli` preset includes `mr:force-merge`; `agent` does not. Adding `--scope mr:merge` lets an agent merge only with passing checks.
104- `mr merge --mode squash|merge` creates a commit signed by the server's own key (generated on first start); the output names its fingerprint, `ermite signing-key show` prints the key. Every mode is allowed by default; `repo edit --merge-modes fast-forward,squash` disables `merge`.
105- `mr merge --auto` makes the server merge once CI passed on the head (`repo edit --allow-auto-merge` first); `--cancel-auto` cancels it; both are exclusive with each other and `--auto` with `--delete-branch`. `watch --json` adds `merge_request_auto_merge_enabled`, `merge_request_auto_merge_cancelled` (with `reason`), and `auto` (true) on `merge_request_merged` after an auto-merge. See [Merge requests](merge-requests.md#auto-merge).
106- Errors are one line on stderr (`ermite: …`) with exit status 1.
107- Shell completion completes repository names from the server.
108
109`ermite mr create` and `ermite mr close` print a confirmation followed by the full
110merge request web URL on its own line. With `--json`, merge request objects
111(create, show, list, close and merge) include `url` alongside the other fields.