Merge branch 'g1t-cli'
50 files+19194−3164 files not counted0/50 viewed
| 145 | 145 | - name: Check and test | |
| 146 | 146 | run: cargo test --locked --manifest-path apps/desktop/src-tauri/Cargo.toml --quiet | |
| 147 | 147 | - name: The release scripts' tests | |
| 148 | − | run: node --test scripts/desktop-release.test.mjs scripts/mobile-release.test.mjs | |
| 148 | + | run: node --test scripts/desktop-release.test.mjs scripts/mobile-release.test.mjs scripts/cli-release.test.mjs |
| 1 | + | # Releases the g1t CLI (crates/g1t): builds it for Linux and macOS on x64 | |
| 2 | + | # and arm64 and for Windows on x64, signs the release, and publishes it to | |
| 3 | + | # g1t.sh/downloads/cli/ (the g1t-downloads R2 bucket), where g1t.sh/install | |
| 4 | + | # and g1t.sh/install.ps1 find it. | |
| 5 | + | # | |
| 6 | + | # A release is a tag `cli-v<version>`, where the version is the one in | |
| 7 | + | # crates/g1t/Cargo.toml; or run it by hand. scripts/cli-release.mjs does the | |
| 8 | + | # work, and its header says what a release holds. It is signed with the | |
| 9 | + | # runner's release key (RUNNER_RELEASE_KEY, RUNNER_RELEASE_PUBLIC_KEY). | |
| 10 | + | # | |
| 11 | + | # Every platform builds in one job, in the rust-cross/cargo-zigbuild image: | |
| 12 | + | # the macOS builds link Apple's Security framework (the keychain), and that | |
| 13 | + | # image carries its SDK. It runs on g1t's own machines (g1t-4core), whose | |
| 14 | + | # jobs have a Docker Engine of their own. | |
| 15 | + | name: CLI release | |
| 16 | + | ||
| 17 | + | on: | |
| 18 | + | push: | |
| 19 | + | tags: ["cli-v*"] | |
| 20 | + | workflow_dispatch: | |
| 21 | + | ||
| 22 | + | permissions: | |
| 23 | + | contents: read | |
| 24 | + | ||
| 25 | + | concurrency: | |
| 26 | + | group: cli-release | |
| 27 | + | cancel-in-progress: false | |
| 28 | + | ||
| 29 | + | env: | |
| 30 | + | CLOUDFLARE_ACCOUNT_ID: ${{ vars.CLOUDFLARE_ACCOUNT_ID }} | |
| 31 | + | WRANGLER_SEND_METRICS: "false" | |
| 32 | + | ||
| 33 | + | jobs: | |
| 34 | + | build: | |
| 35 | + | name: Build every platform | |
| 36 | + | runs-on: g1t-4core | |
| 37 | + | timeout-minutes: 60 | |
| 38 | + | steps: | |
| 39 | + | - uses: actions/checkout@v5 | |
| 40 | + | - name: The tag names this version | |
| 41 | + | if: startsWith(github.ref, 'refs/tags/cli-v') | |
| 42 | + | run: | | |
| 43 | + | version="$(sed -n 's/^version = "\(.*\)"/\1/p' crates/g1t/Cargo.toml | head -1)" | |
| 44 | + | [ "cli-v$version" = "${GITHUB_REF_NAME}" ] || { echo "::error::The tag is ${GITHUB_REF_NAME}, but crates/g1t is $version"; exit 1; } | |
| 45 | + | - name: Build | |
| 46 | + | run: node scripts/cli-release.mjs build | |
| 47 | + | - uses: actions/upload-artifact@v4 | |
| 48 | + | with: | |
| 49 | + | name: cli | |
| 50 | + | path: target/cli-release/ | |
| 51 | + | overwrite: true | |
| 52 | + | ||
| 53 | + | publish: | |
| 54 | + | name: Sign and publish | |
| 55 | + | needs: build | |
| 56 | + | runs-on: ubuntu-latest | |
| 57 | + | # Production's secrets, without a deployment: a release is not a deploy | |
| 58 | + | # of g1t.sh. | |
| 59 | + | environment: | |
| 60 | + | name: production | |
| 61 | + | deployment: false | |
| 62 | + | timeout-minutes: 30 | |
| 63 | + | steps: | |
| 64 | + | - uses: actions/checkout@v5 | |
| 65 | + | - uses: actions/download-artifact@v4 | |
| 66 | + | with: | |
| 67 | + | name: cli | |
| 68 | + | path: target/cli-release | |
| 69 | + | - name: Sign | |
| 70 | + | env: | |
| 71 | + | RUNNER_RELEASE_KEY: ${{ secrets.RUNNER_RELEASE_KEY }} | |
| 72 | + | G1T_RUNNER_RELEASE_KEY: ${{ vars.RUNNER_RELEASE_PUBLIC_KEY }} | |
| 73 | + | run: | | |
| 74 | + | node scripts/cli-release.mjs sign | |
| 75 | + | node scripts/cli-release.mjs verify | |
| 76 | + | - name: Cache npm's downloads | |
| 77 | + | uses: actions/cache@v4 | |
| 78 | + | with: | |
| 79 | + | path: ~/.npm | |
| 80 | + | key: npm-${{ runner.os }}-${{ hashFiles('package-lock.json') }} | |
| 81 | + | restore-keys: npm-${{ runner.os }}- | |
| 82 | + | - name: Install Wrangler | |
| 83 | + | run: npm ci --prefer-offline --workspaces=false --no-audit --no-fund | |
| 84 | + | - name: Publish to g1t.sh/downloads/cli | |
| 85 | + | env: | |
| 86 | + | CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }} | |
| 87 | + | run: node scripts/cli-release.mjs publish |
| 128 | 128 | `.g1t/workflows/runner-release.yml` builds, signs and publishes it, and | |
| 129 | 129 | runners update themselves to it. `scripts/runner-release.mjs` does the | |
| 130 | 130 | same by hand. | |
| 131 | + | - **The g1t CLI** is released the same way: bump `version` in | |
| 132 | + | `crates/g1t/Cargo.toml`, merge, and push a `cli-v<version>` tag. | |
| 133 | + | `.g1t/workflows/cli-release.yml` builds it for every platform, signs | |
| 134 | + | the release with the runner's release key and publishes it to | |
| 135 | + | g1t.sh/downloads/cli/, where g1t.sh/install and g1t.sh/install.ps1 | |
| 136 | + | find it. `scripts/cli-release.mjs` does the same by hand. The command | |
| 137 | + | reference in the docs is generated from the CLI | |
| 138 | + | (`G1T_WRITE_DOCS=1 cargo test -p g1t cli_reference`), and its table of | |
| 139 | + | API operations from the OpenAPI document | |
| 140 | + | (`G1T_WRITE_OPS=1 cargo test -p g1t ops_table`); tests fail when either | |
| 141 | + | falls behind. The guide is [The g1t CLI](https://docs.g1t.sh/guides/cli/). | |
| 131 | 142 | - **The desktop app** is released the same way: bump `version` in | |
| 132 | 143 | `apps/desktop/src-tauri/Cargo.toml`, merge, and push a | |
| 133 | 144 | `desktop-v<version>` tag. `.g1t/workflows/desktop-release.yml` builds |
A large diff (1,467 lines) is not shown until you ask for it.
| 81 | 81 | items: [ | |
| 82 | 82 | { label: 'Quickstart', slug: 'quickstart' }, | |
| 83 | 83 | { label: 'How g1t works', slug: 'concepts/overview' }, | |
| 84 | + | { label: 'The g1t CLI', slug: 'guides/cli' }, | |
| 84 | 85 | { label: 'Home', slug: 'guides/home' }, | |
| 85 | 86 | { label: 'Notifications', slug: 'guides/notifications' }, | |
| 86 | 87 | { label: 'The desktop app', slug: 'guides/desktop' }, | |
| ⋯ | |||
| 208 | 209 | items: [ | |
| 209 | 210 | { label: 'API overview', slug: 'reference/api' }, | |
| 210 | 211 | { label: 'MCP tools', slug: 'reference/mcp' }, | |
| 212 | + | { label: 'CLI commands', slug: 'reference/cli' }, | |
| 211 | 213 | { label: 'Rate limits', slug: 'reference/rate-limits' }, | |
| 212 | 214 | { label: 'Try it in the explorer', link: '/api/reference/', attrs: { target: '_self' } }, | |
| 213 | 215 | { label: 'OpenAPI document', link: 'https://api.g1t.sh/openapi.json' }, | |
| 1 | + | --- | |
| 2 | + | title: The g1t CLI | |
| 3 | + | description: Install the g1t command line, sign in, and work with repositories, issues, pull requests, runs, deployments, secrets and logs from a terminal, a script or an agent. | |
| 4 | + | --- | |
| 5 | + | ||
| 6 | + | `g1t` is the command line for g1t. It does the work you would otherwise do on | |
| 7 | + | the site: open and review pull requests, wait on checks, read a failing run's | |
| 8 | + | logs, set secrets, read a project's logs, and call any operation of the | |
| 9 | + | [API](/reference/api/). It is one file with nothing to install alongside it, | |
| 10 | + | and it is built to be run by agents as much as by people: every command can | |
| 11 | + | print JSON, nothing waits for input unless a person is at the terminal, and | |
| 12 | + | exit codes say what happened. | |
| 13 | + | ||
| 14 | + | ```sh | |
| 15 | + | g1t issue list --label bug | |
| 16 | + | g1t pr create --fill | |
| 17 | + | g1t pr checks --watch --fail-fast | |
| 18 | + | g1t run logs --failed | |
| 19 | + | ``` | |
| 20 | + | ||
| 21 | + | Every command and flag is listed in the [command reference](/reference/cli/). | |
| 22 | + | ||
| 23 | + | ## Install | |
| 24 | + | ||
| 25 | + | On Linux or macOS: | |
| 26 | + | ||
| 27 | + | ```sh | |
| 28 | + | curl -fsSL https://g1t.sh/install | sh | |
| 29 | + | ``` | |
| 30 | + | ||
| 31 | + | On Windows, in PowerShell: | |
| 32 | + | ||
| 33 | + | ```powershell | |
| 34 | + | irm https://g1t.sh/install.ps1 | iex | |
| 35 | + | ``` | |
| 36 | + | ||
| 37 | + | The script picks the build for your system, checks it against the | |
| 38 | + | release's `SHA256SUMS`, and puts `g1t` in `~/.local/bin` (Windows: | |
| 39 | + | `%LOCALAPPDATA%\g1t\bin`, which it adds to your `PATH`). Set | |
| 40 | + | `G1T_INSTALL_DIR` to put it elsewhere, or `G1T_VERSION` to install a | |
| 41 | + | version other than the latest. Run it again to update. | |
| 42 | + | ||
| 43 | + | ### Without the script | |
| 44 | + | ||
| 45 | + | Each release is a single file per platform, at | |
| 46 | + | `https://g1t.sh/downloads/cli/latest/`: | |
| 47 | + | ||
| 48 | + | | Platform | File | | |
| 49 | + | | --- | --- | | |
| 50 | + | | Linux, x64 | `g1t-linux-x64` | | |
| 51 | + | | Linux, ARM | `g1t-linux-arm64` | | |
| 52 | + | | macOS, Apple silicon | `g1t-macos-arm64` | | |
| 53 | + | | macOS, Intel | `g1t-macos-x64` | | |
| 54 | + | | Windows, x64 | `g1t-windows-x64.exe` | | |
| 55 | + | ||
| 56 | + | ```sh | |
| 57 | + | curl -fsSLo g1t https://g1t.sh/downloads/cli/latest/g1t-linux-x64 | |
| 58 | + | chmod +x g1t && mv g1t ~/.local/bin/ | |
| 59 | + | ``` | |
| 60 | + | ||
| 61 | + | Check a download against `https://g1t.sh/downloads/cli/latest/SHA256SUMS`. | |
| 62 | + | `latest.json` beside it names the version and each file's SHA-256, and | |
| 63 | + | `latest.json.sig` is its signature. A given version's files are at | |
| 64 | + | `/downloads/cli/<version>/` and never change. | |
| 65 | + | ||
| 66 | + | To build it from source, with [Rust](https://www.rust-lang.org/tools/install): | |
| 67 | + | ||
| 68 | + | ```sh | |
| 69 | + | git clone https://g1t.sh/flagon-io/g1t | |
| 70 | + | cargo install --path g1t/crates/g1t | |
| 71 | + | ``` | |
| 72 | + | ||
| 73 | + | `g1t --version` prints the version you have. | |
| 74 | + | ||
| 75 | + | ## Sign in | |
| 76 | + | ||
| 77 | + | ```sh | |
| 78 | + | g1t auth login | |
| 79 | + | ``` | |
| 80 | + | ||
| 81 | + | `g1t` shows a one-time code and opens your browser at | |
| 82 | + | [g1t.sh/device](https://g1t.sh/device). Sign in there if you are not | |
| 83 | + | already, check the code matches, and approve. The command finishes on its | |
| 84 | + | own once you have. Where there is no browser (a server, a container, a | |
| 85 | + | remote shell), it prints the link instead: open it on any device. | |
| 86 | + | ||
| 87 | + | To use an [access token](/guides/authentication/#access-tokens) you already | |
| 88 | + | have, pipe it in: | |
| 89 | + | ||
| 90 | + | ```sh | |
| 91 | + | g1t auth login --with-token < token.txt | |
| 92 | + | ``` | |
| 93 | + | ||
| 94 | + | The token is kept in your system's credential store: the Keychain on | |
| 95 | + | macOS, Credential Manager on Windows, the Secret Service on Linux. Where | |
| 96 | + | there is none, as on most servers, it goes in the [config | |
| 97 | + | file](#settings-and-environment), readable only by you; `--insecure-storage` | |
| 98 | + | puts it there on purpose. | |
| 99 | + | ||
| 100 | + | | Command | What it does | | |
| 101 | + | | --- | --- | | |
| 102 | + | | `g1t auth status` | Each account you are signed in as, on each host, whether its token still works, and its scopes. Exits `4` when the active account's token does not work. | | |
| 103 | + | | `g1t auth token` | Prints the token in use, for another program. | | |
| 104 | + | | `g1t auth logout` | Forgets an account's token. | | |
| 105 | + | | `g1t auth switch` | Makes another signed-in account on the same host the active one. | | |
| 106 | + | ||
| 107 | + | ### G1T_TOKEN | |
| 108 | + | ||
| 109 | + | When `G1T_TOKEN` is set, every command uses it instead of a stored token. | |
| 110 | + | This is how to give `g1t` a token in containers, in agents' sandboxes, and | |
| 111 | + | in [workflows](/guides/actions/), where the job's own token is | |
| 112 | + | `secrets.G1T_TOKEN`: | |
| 113 | + | ||
| 114 | + | ```yaml | |
| 115 | + | - run: g1t pr comment ${{ github.event.pull_request.number }} -b "Preview is up." | |
| 116 | + | env: | |
| 117 | + | G1T_TOKEN: ${{ secrets.G1T_TOKEN }} | |
| 118 | + | ``` | |
| 119 | + | ||
| 120 | + | ### Self-hosted g1t | |
| 121 | + | ||
| 122 | + | `g1t` works with any g1t, not only g1t.sh. Sign in to yours with its | |
| 123 | + | address: | |
| 124 | + | ||
| 125 | + | ```sh | |
| 126 | + | g1t auth login --hostname git.example.com | |
| 127 | + | ``` | |
| 128 | + | ||
| 129 | + | `g1t` asks it where its API is (its `/.well-known/g1t.json`), and remembers. | |
| 130 | + | After that, commands in a clone of one of its repositories talk to it on | |
| 131 | + | their own. Elsewhere, name it with `--hostname` or `G1T_HOST`; the first host | |
| 132 | + | you sign in to is the default. You can be signed in to several hosts, and | |
| 133 | + | as several accounts on each. | |
| 134 | + | ||
| 135 | + | ## Use it with git | |
| 136 | + | ||
| 137 | + | ```sh | |
| 138 | + | g1t auth setup-git | |
| 139 | + | ``` | |
| 140 | + | ||
| 141 | + | This makes `g1t` git's credential helper for each host you are signed in | |
| 142 | + | to, so `git push`, `git fetch` and `git clone` over HTTPS use the same | |
| 143 | + | token, with nothing more to type. It changes your global git config only for | |
| 144 | + | those hosts' addresses (`credential.https://g1t.sh.helper`). `g1t auth login | |
| 145 | + | --git` does both at once. To see the config lines without changing anything, | |
| 146 | + | add `--dry-run`. | |
| 147 | + | ||
| 148 | + | [`g1t push`](/guides/containers/#push-large-layers-with-g1t-push), which sends container | |
| 149 | + | images to g1t's registry, uses the same signed-in token. | |
| 150 | + | ||
| 151 | + | ## Which repository | |
| 152 | + | ||
| 153 | + | Commands about a repository work on the one the current directory is a | |
| 154 | + | clone of, found from its git remotes: `upstream` if it is on g1t, then | |
| 155 | + | `origin`, then the first one that is. In a pull request's own [working | |
| 156 | + | copy](/guides/pull-requests/), they work on the repository the pull request | |
| 157 | + | is for. | |
| 158 | + | ||
| 159 | + | Anywhere else, or to choose another, pass `--repo` (`-R`), or set | |
| 160 | + | `G1T_REPO`: | |
| 161 | + | ||
| 162 | + | ```sh | |
| 163 | + | g1t issue list -R acme/web | |
| 164 | + | g1t pr view 14 -R git.example.com/acme/web | |
| 165 | + | ``` | |
| 166 | + | ||
| 167 | + | ## Everyday work | |
| 168 | + | ||
| 169 | + | ### Issues | |
| 170 | + | ||
| 171 | + | ```sh | |
| 172 | + | g1t issue list # open issues, newest first | |
| 173 | + | g1t issue list --label bug --assignee @me | |
| 174 | + | g1t issue view 12 --comments | |
| 175 | + | g1t issue create -t "Greeting should name the caller" -b "Take a name from the first argument." | |
| 176 | + | g1t issue comment 12 -b "Fixed in #14." | |
| 177 | + | g1t issue edit 12 --add-label p1 --add-assignee @me | |
| 178 | + | g1t issue close 12 --reason not_planned | |
| 179 | + | ``` | |
| 180 | + | ||
| 181 | + | `@me` is you. At a terminal, `g1t issue create` without `--title` asks for | |
| 182 | + | one and opens your editor for the body. | |
| 183 | + | ||
| 184 | + | ### Pull requests | |
| 185 | + | ||
| 186 | + | From a branch with your commits on it: | |
| 187 | + | ||
| 188 | + | ```sh | |
| 189 | + | git switch -c greet-by-name | |
| 190 | + | # ...commit... | |
| 191 | + | g1t pr create --fill --issue 12 | |
| 192 | + | ``` | |
| 193 | + | ||
| 194 | + | `g1t pr create` pushes the branch, then opens the pull request into the | |
| 195 | + | default branch (`--base` for another). `--fill` takes the title and body from | |
| 196 | + | the branch's commits; `--issue` says which issue it is for; `--draft` opens | |
| 197 | + | it as a draft. | |
| 198 | + | ||
| 199 | + | To start a pull request for an issue without a branch of your own, as g1t's | |
| 200 | + | agents do, run it with `--issue` from the default branch. g1t opens a draft | |
| 201 | + | with a [working copy](/guides/pull-requests/) of its own and prints the | |
| 202 | + | copy's git remote. Push your commits there, then mark it ready with a | |
| 203 | + | summary of what changed and why: | |
| 204 | + | ||
| 205 | + | ```sh | |
| 206 | + | g1t pr create --issue 12 | |
| 207 | + | git push https://g1t.sh/pulls/pr_….git HEAD:main | |
| 208 | + | g1t pr ready --summary "Reads a name from the first argument." | |
| 209 | + | ``` | |
| 210 | + | ||
| 211 | + | Then, for any pull request: | |
| 212 | + | ||
| 213 | + | ```sh | |
| 214 | + | g1t pr list | |
| 215 | + | g1t pr view 14 # the current branch's when left out | |
| 216 | + | g1t pr diff 14 | |
| 217 | + | g1t pr checkout 14 # check its head out locally | |
| 218 | + | g1t pr checks 14 --watch | |
| 219 | + | g1t pr review 14 --approve -b "Reads well." | |
| 220 | + | g1t pr review 14 --request-changes -b "Trim the name first." | |
| 221 | + | g1t pr merge 14 --delete-branch | |
| 222 | + | ``` | |
| 223 | + | ||
| 224 | + | `g1t pr merge` merges the way the repository is set to, once | |
| 225 | + | [required checks](/guides/checks/) pass and [rules](/guides/rules/) allow; | |
| 226 | + | `--admin` merges past them, with the Admin role. | |
| 227 | + | ||
| 228 | + | ### Checks and runs | |
| 229 | + | ||
| 230 | + | `g1t pr checks` lists a pull request's checks: g1t Actions jobs, check runs | |
| 231 | + | and commit statuses. With `--watch` it waits until they have all finished, | |
| 232 | + | redrawing at a terminal and printing a line per change when piped. | |
| 233 | + | `--fail-fast` stops at the first failure instead of waiting for the rest. It | |
| 234 | + | exits `0` when every check passed, `1` when one failed, and, without | |
| 235 | + | `--watch`, `8` while any are still running. | |
| 236 | + | ||
| 237 | + | ```sh | |
| 238 | + | g1t run list --branch main | |
| 239 | + | g1t run view # the current branch's latest run | |
| 240 | + | g1t run watch run_01kpx7b3c6d9e2f5g8h1j4k7mr | |
| 241 | + | g1t run logs --failed | |
| 242 | + | g1t run rerun --failed | |
| 243 | + | ``` | |
| 244 | + | ||
| 245 | + | A run is named by its id (`run_…`), its number, or its address; left out, | |
| 246 | + | it is the current branch's latest. `g1t run logs --failed` prints only the | |
| 247 | + | steps that failed, each with its last 60 lines (`-n` for more or fewer): | |
| 248 | + | what you need to see why, without the rest of the log. `g1t run watch` | |
| 249 | + | exits `1` if the run fails. | |
| 250 | + | ||
| 251 | + | ### Deployments, logs and secrets | |
| 252 | + | ||
| 253 | + | ```sh | |
| 254 | + | g1t deploy list --env production | |
| 255 | + | g1t deploy view dep_01kq8m3t5v7x9z1b3d5f7h9k2m | |
| 256 | + | ||
| 257 | + | g1t logs --since 1h --level error,fatal | |
| 258 | + | g1t logs -q '"payment failed"' --follow | |
| 259 | + | g1t logs --errors --state open | |
| 260 | + | ||
| 261 | + | g1t secret list | |
| 262 | + | echo "$NPM_TOKEN" | g1t secret set NPM_TOKEN | |
| 263 | + | g1t secret set STRIPE_KEY --env production < stripe-key.txt | |
| 264 | + | g1t secret set NPM_TOKEN --brokered-host registry.npmjs.org < npm-token.txt | |
| 265 | + | g1t secret delete STRIPE_KEY --env preview | |
| 266 | + | g1t secret list --workspace acme | |
| 267 | + | ``` | |
| 268 | + | ||
| 269 | + | `g1t logs` reads the [observability](/guides/observability/) data of the | |
| 270 | + | current repository's project, or of `--project WORKSPACE/SLUG`. A secret's | |
| 271 | + | value is read from stdin, so it stays out of your shell's history; at a | |
| 272 | + | terminal with nothing piped, `g1t` asks for it without echoing. Values are | |
| 273 | + | never printed. `--brokered-host` makes it a [brokered | |
| 274 | + | secret](/guides/secrets-and-variables/#brokered-secrets). | |
| 275 | + | ||
| 276 | + | ### What needs you | |
| 277 | + | ||
| 278 | + | ```sh | |
| 279 | + | g1t status | |
| 280 | + | ``` | |
| 281 | + | ||
| 282 | + | Your open pull requests and their checks, reviews asked of you, what is | |
| 283 | + | assigned to you, and failing checks, across every repository you can see. | |
| 284 | + | ||
| 285 | + | ## Scripting with JSON | |
| 286 | + | ||
| 287 | + | Every command takes `--json`. Alone, it prints every field the API returns; | |
| 288 | + | with a comma-separated list, only those: | |
| 289 | + | ||
| 290 | + | ```sh | |
| 291 | + | g1t pr list --json number,title,check_status | |
| 292 | + | ``` | |
| 293 | + | ||
| 294 | + | ```json | |
| 295 | + | [{"check_status":"passed","number":14,"title":"Greeting should name the caller"}] | |
| 296 | + | ``` | |
| 297 | + | ||
| 298 | + | The fields are the API's own, named as in the [API reference](/reference/api/) | |
| 299 | + | and always `snake_case`. A field that does not exist is an error that lists | |
| 300 | + | the ones that do. Piped, JSON is one compact line with its keys in a fixed | |
| 301 | + | order, so the same input gives the same output; at a terminal it is | |
| 302 | + | indented. | |
| 303 | + | ||
| 304 | + | `--jq` runs a [jq](https://jqlang.org/manual/) expression over the JSON, | |
| 305 | + | with nothing else to install. Strings come out bare, everything else as | |
| 306 | + | JSON: | |
| 307 | + | ||
| 308 | + | ```sh | |
| 309 | + | g1t pr list --jq '.[] | select(.check_status == "failed") | .number' | |
| 310 | + | g1t run list --jq '.[] | [.id, .conclusion] | @tsv' | |
| 311 | + | ``` | |
| 312 | + | ||
| 313 | + | Without `--json`, output piped to another program is one record per line, | |
| 314 | + | fields separated by tabs, with no header and no color, ready for `cut`, | |
| 315 | + | `awk` or `while read`. Lists show 20 entries unless `--limit` (`-L`) says | |
| 316 | + | otherwise. | |
| 317 | + | ||
| 318 | + | ### Exit codes | |
| 319 | + | ||
| 320 | + | | Code | Meaning | | |
| 321 | + | | --- | --- | | |
| 322 | + | | `0` | It worked. | | |
| 323 | + | | `1` | It failed: the API refused it, the network failed, checks or a run failed. | | |
| 324 | + | | `2` | The command was used wrongly: an unknown flag, a missing argument, a JSON field that does not exist. | | |
| 325 | + | | `4` | Signing in is needed, or the token was refused. | | |
| 326 | + | | `8` | Checks are still running (`g1t pr checks` without `--watch`). | | |
| 327 | + | ||
| 328 | + | An error is one line on stderr, starting `g1t:`. When a token lacks a | |
| 329 | + | [scope](/guides/authentication/#scopes) the call needs, the line names it. | |
| 330 | + | ||
| 331 | + | ### No questions when piped | |
| 332 | + | ||
| 333 | + | `g1t` asks for a missing title, opens an editor for a body, or offers a | |
| 334 | + | choice only when stdin and stderr are both a terminal. Anywhere else, and | |
| 335 | + | whenever `G1T_PROMPT_DISABLED` is set, a command missing something fails at | |
| 336 | + | once with exit code `2` and names the flag that supplies it. | |
| 337 | + | ||
| 338 | + | ## Call any operation | |
| 339 | + | ||
| 340 | + | `g1t api` calls any operation of the [API](/reference/api/) by its name, | |
| 341 | + | with your token, and fills the repository in from where you are: | |
| 342 | + | ||
| 343 | + | ```sh | |
| 344 | + | g1t api list_issues -f state=closed --jq '.[].title' | |
| 345 | + | g1t api create_label -f name=p1 -f color=d73a4a | |
| 346 | + | g1t api get_workflow_run -f id=run_01kpx7b3c6d9e2f5g8h1j4k7mr | |
| 347 | + | g1t api --list label # the operations about labels | |
| 348 | + | ``` | |
| 349 | + | ||
| 350 | + | A path works too, with `{owner}`, `{name}` and `{workspace}` filled in: | |
| 351 | + | ||
| 352 | + | ```sh | |
| 353 | + | g1t api /repos/{owner}/{name}/labels | |
| 354 | + | g1t api user --jq .username | |
| 355 | + | ``` | |
| 356 | + | ||
| 357 | + | `-f key=value` sends a string, `-F key=value` sends `true`, `false`, `null` | |
| 358 | + | and numbers as JSON and `@file` as a file's contents, and `key[]=value` adds | |
| 359 | + | to a list. Fields go in the query of a `GET` and in the JSON body otherwise. | |
| 360 | + | `-X` sets the method, `-H` adds a header, and `--input file` sends a file as | |
| 361 | + | the body. `--paginate` follows each next page, and with `--slurp` puts every | |
| 362 | + | page's items in one array. A request the API refuses prints its error body | |
| 363 | + | and exits `1`. | |
| 364 | + | ||
| 365 | + | In Git Bash on Windows, an argument starting with `/` is turned into a | |
| 366 | + | Windows path before `g1t` sees it: leave the leading slash off | |
| 367 | + | (`g1t api repos/{owner}/{name}`), or set `MSYS_NO_PATHCONV=1`. | |
| 368 | + | ||
| 369 | + | ## From agents and harnesses | |
| 370 | + | ||
| 371 | + | An agent with a shell, such as Claude Code, Codex or Cursor, can use `g1t` | |
| 372 | + | the way you do. A command and its JSON cost an agent less of its context | |
| 373 | + | than a set of tool definitions, and the agent finds what it needs with | |
| 374 | + | `--help`. For clients without a shell, use the [MCP server](/reference/mcp/). | |
| 375 | + | ||
| 376 | + | 1. Install `g1t` where the agent runs, as [above](#install). | |
| 377 | + | 2. Give it a token. Either sign in once with `g1t auth login` as the user | |
| 378 | + | the agent runs as, or set `G1T_TOKEN` in its environment. Make a token | |
| 379 | + | with only the [scopes](/guides/authentication/#scopes) it needs. | |
| 380 | + | 3. Tell it `g1t` is there. A few lines in the project's `CLAUDE.md` or | |
| 381 | + | `AGENTS.md` are enough: | |
| 382 | + | ||
| 383 | + | ```md | |
| 384 | + | This repository is on g1t. Use the `g1t` CLI for issues, pull requests, | |
| 385 | + | checks and runs; add `--json` to read results, and see `g1t <command> --help`. | |
| 386 | + | ||
| 387 | + | - Open a pull request: `g1t pr create --fill --issue <n>` | |
| 388 | + | - Wait for checks: `g1t pr checks --watch --fail-fast` (exit 0 passed, 1 failed) | |
| 389 | + | - See why a run failed: `g1t run logs --failed` | |
| 390 | + | - Anything else: `g1t api --list <word>`, then `g1t api <operation>` | |
| 391 | + | ``` | |
| 392 | + | ||
| 393 | + | `g1t` never waits for input in an agent's shell, since its stdin is not a | |
| 394 | + | terminal. Its JSON is compact and in a stable order, its lists are short | |
| 395 | + | by default, and `g1t pr checks --watch --fail-fast` and `g1t run logs | |
| 396 | + | --failed` give an agent the one thing it is waiting for, and no more. | |
| 397 | + | ||
| 398 | + | ## Aliases and completion | |
| 399 | + | ||
| 400 | + | An alias is a shortcut for a command you type often. `$1`, `$2`… take the | |
| 401 | + | arguments after it, and the rest go on the end: | |
| 402 | + | ||
| 403 | + | ```sh | |
| 404 | + | g1t alias set bugs 'issue list --label bug' | |
| 405 | + | g1t alias set co 'pr checkout' | |
| 406 | + | g1t alias set mine '!g1t pr list --author @me --json number,title' | |
| 407 | + | g1t bugs --limit 5 | |
| 408 | + | ``` | |
| 409 | + | ||
| 410 | + | An alias starting with `!` runs in `sh`. `g1t alias list` lists them, and | |
| 411 | + | `g1t alias delete` removes one. | |
| 412 | + | ||
| 413 | + | `g1t completion <shell>` prints a completion script for `bash`, `zsh`, | |
| 414 | + | `fish`, `powershell` or `elvish`: | |
| 415 | + | ||
| 416 | + | ```sh | |
| 417 | + | g1t completion bash > ~/.local/share/bash-completion/completions/g1t | |
| 418 | + | g1t completion zsh > "${fpath[1]}/_g1t" | |
| 419 | + | g1t completion fish > ~/.config/fish/completions/g1t.fish | |
| 420 | + | g1t completion powershell >> $PROFILE | |
| 421 | + | ``` | |
| 422 | + | ||
| 423 | + | ## Settings and environment | |
| 424 | + | ||
| 425 | + | `g1t` keeps the hosts you are signed in to, their accounts and your aliases | |
| 426 | + | in `config.json`, in `~/.config/g1t` (`%APPDATA%\g1t` on Windows; | |
| 427 | + | `$XDG_CONFIG_HOME/g1t` when that is set). | |
| 428 | + | ||
| 429 | + | | Variable | | | |
| 430 | + | | --- | --- | | |
| 431 | + | | `G1T_TOKEN` | A token to use instead of the stored one. | | |
| 432 | + | | `G1T_HOST` | The host to use when no repository names one. | | |
| 433 | + | | `G1T_REPO` | The repository, as `[HOST/]OWNER/NAME`. | | |
| 434 | + | | `G1T_CONFIG_DIR` | Where to keep `config.json`. | | |
| 435 | + | | `G1T_KEYRING` | `off` keeps tokens out of the system's credential store. | | |
| 436 | + | | `G1T_PROMPT_DISABLED` | Never ask anything. | | |
| 437 | + | | `G1T_EDITOR`, `VISUAL`, `EDITOR` | The editor for bodies and summaries. | | |
| 438 | + | | `G1T_BROWSER`, `BROWSER` | The browser `--web` and `g1t browse` open. | | |
| 439 | + | | `NO_COLOR` | Plain output at a terminal too. | | |
| 440 | + | | `G1T_DEBUG` | Print each request's method, address and status on stderr. | |
| 178 | 178 | 1. a token on stdin, with `--token-stdin` | |
| 179 | 179 | (`echo "$G1T_TOKEN" | g1t push … --token-stdin`); | |
| 180 | 180 | 2. the `G1T_TOKEN` environment variable, as in [workflows](#in-workflows); | |
| 181 | − | 3. what `docker login g1t.sh` stored, in `~/.docker/config.json` or the | |
| 181 | + | 3. the account [`g1t auth login`](/guides/cli/#sign-in) signed in to on the | |
| 182 | + | registry's host; | |
| 183 | + | 4. what `docker login g1t.sh` stored, in `~/.docker/config.json` or the | |
| 182 | 184 | credential store it names. | |
| 183 | 185 | ||
| 184 | 186 | | Option | | | |
| ⋯ | |||
| 192 | 194 | ||
| 193 | 195 | ### Getting g1t | |
| 194 | 196 | ||
| 195 | − | One file for each platform, from `https://g1t.sh/downloads/cli/latest/`: | |
| 197 | + | `g1t push` is part of the [g1t CLI](/guides/cli/). Install it with one line: | |
| 196 | 198 | ||
| 197 | 199 | ```sh | |
| 198 | − | # Linux (x64; use g1t-linux-arm64 on ARM) | |
| 199 | − | curl -fsSLo g1t https://g1t.sh/downloads/cli/latest/g1t-linux-x64 && chmod +x g1t | |
| 200 | − | # macOS (Apple silicon; use g1t-macos-x64 on Intel) | |
| 201 | − | curl -fsSLo g1t https://g1t.sh/downloads/cli/latest/g1t-macos-arm64 && chmod +x g1t | |
| 200 | + | curl -fsSL https://g1t.sh/install | sh | |
| 202 | 201 | ``` | |
| 203 | 202 | ||
| 204 | 203 | ```powershell | |
| 205 | − | # Windows | |
| 206 | − | Invoke-WebRequest https://g1t.sh/downloads/cli/latest/g1t-windows-x64.exe -OutFile g1t.exe | |
| 204 | + | irm https://g1t.sh/install.ps1 | iex | |
| 207 | 205 | ``` | |
| 208 | 206 | ||
| 209 | − | Check a download against `https://g1t.sh/downloads/cli/latest/SHA256SUMS`. | |
| 210 | − | To build it from source instead, with | |
| 211 | − | [Rust](https://www.rust-lang.org/tools/install): | |
| 212 | − | ||
| 213 | − | ```sh | |
| 214 | − | git clone https://g1t.sh/flagon-io/g1t | |
| 215 | − | cd g1t | |
| 216 | − | cargo install --path crates/g1t | |
| 217 | − | ``` | |
| 207 | + | [Installing the CLI](/guides/cli/#install) covers the single-file downloads, | |
| 208 | + | checking them, and building it from source. | |
| 218 | 209 | ||
| 219 | 210 | ## Storage and pull limits | |
| 220 | 211 | ||
| 1 | + | --- | |
| 2 | + | title: CLI commands | |
| 3 | + | description: Every g1t command with its arguments and flags, written from the CLI's own definitions. | |
| 4 | + | --- | |
| 5 | + | ||
| 6 | + | <!-- Generated from crates/g1t by `G1T_WRITE_DOCS=1 cargo test -p g1t cli_reference`. Do not edit by hand. --> | |
| 7 | + | ||
| 8 | + | Every command of the [g1t CLI](/guides/cli/), with its arguments and flags. | |
| 9 | + | `g1t <command> --help` prints the same at a terminal. Each command that talks | |
| 10 | + | to the API names the operations it calls, which link to the | |
| 11 | + | [API reference](/reference/api/); [`g1t api`](#g1t-api) calls any other. | |
| 12 | + | ||
| 13 | + | ## Flags every command takes | |
| 14 | + | ||
| 15 | + | | Flag | | | |
| 16 | + | | --- | --- | | |
| 17 | + | | `-R, --repo <[HOST/]OWNER/NAME>` | The repository, as [HOST/]OWNER/NAME, instead of the current directory's. | | |
| 18 | + | | `--hostname <HOST>` | The g1t host, such as g1t.sh or git.example.com. | | |
| 19 | + | | `--json [FIELDS]` | Print JSON: every field, or only the comma-separated FIELDS. | | |
| 20 | + | | `--jq <EXPRESSION>` | Run a jq expression over the JSON and print what it gives. | | |
| 21 | + | ||
| 22 | + | ## g1t auth | |
| 23 | + | ||
| 24 | + | Sign in, sign out, and set git up to use g1t's credentials. | |
| 25 | + | ||
| 26 | + | ### g1t auth login | |
| 27 | + | ||
| 28 | + | Sign in to a g1t host. | |
| 29 | + | ||
| 30 | + | ```text | |
| 31 | + | g1t auth login [OPTIONS] | |
| 32 | + | ``` | |
| 33 | + | ||
| 34 | + | | Argument or flag | | | |
| 35 | + | | --- | --- | | |
| 36 | + | | `--with-token` | Read a token from stdin instead of approving in the browser. | | |
| 37 | + | | `--insecure-storage` | Keep the token in the config file, not the system keychain. | | |
| 38 | + | | `--no-browser` | Do not open the browser; just print the link. | | |
| 39 | + | | `--git` | Also set git up to use g1t's credentials (see `g1t auth setup-git`). | | |
| 40 | + | ||
| 41 | + | ```text | |
| 42 | + | Without --with-token, g1t shows a code and a link; approve it in the browser, signed in. | |
| 43 | + | With --with-token, the token is read from stdin: | |
| 44 | + | g1t auth login --with-token < token.txt | |
| 45 | + | ``` | |
| 46 | + | ||
| 47 | + | Calls [`device_code`](/reference/api/accounts/device-code/), [`device_token`](/reference/api/accounts/device-token/), [`whoami`](/reference/api/accounts/whoami/). | |
| 48 | + | ||
| 49 | + | ### g1t auth logout | |
| 50 | + | ||
| 51 | + | Sign out of an account on a host. | |
| 52 | + | ||
| 53 | + | ```text | |
| 54 | + | g1t auth logout [OPTIONS] | |
| 55 | + | ``` | |
| 56 | + | ||
| 57 | + | | Argument or flag | | | |
| 58 | + | | --- | --- | | |
| 59 | + | | `-u, --user <USER>` | The account, when more than one is signed in on the host. | | |
| 60 | + | ||
| 61 | + | ### g1t auth status | |
| 62 | + | ||
| 63 | + | Show which accounts are signed in, and whether their tokens work. | |
| 64 | + | ||
| 65 | + | ```text | |
| 66 | + | g1t auth status [OPTIONS] | |
| 67 | + | ``` | |
| 68 | + | ||
| 69 | + | | Argument or flag | | | |
| 70 | + | | --- | --- | | |
| 71 | + | | `--show-token` | Print each token too. | | |
| 72 | + | ||
| 73 | + | Calls [`whoami`](/reference/api/accounts/whoami/). | |
| 74 | + | ||
| 75 | + | ### g1t auth token | |
| 76 | + | ||
| 77 | + | Print the token in use, for another program. | |
| 78 | + | ||
| 79 | + | ```text | |
| 80 | + | g1t auth token [OPTIONS] | |
| 81 | + | ``` | |
| 82 | + | ||
| 83 | + | | Argument or flag | | | |
| 84 | + | | --- | --- | | |
| 85 | + | | `-u, --user <USER>` | The account, when more than one is signed in on the host. | | |
| 86 | + | ||
| 87 | + | ### g1t auth switch | |
| 88 | + | ||
| 89 | + | Make another signed-in account on a host the active one. | |
| 90 | + | ||
| 91 | + | ```text | |
| 92 | + | g1t auth switch [OPTIONS] | |
| 93 | + | ``` | |
| 94 | + | ||
| 95 | + | | Argument or flag | | | |
| 96 | + | | --- | --- | | |
| 97 | + | | `-u, --user <USER>` | The account, when more than one is signed in on the host. | | |
| 98 | + | ||
| 99 | + | ### g1t auth setup-git | |
| 100 | + | ||
| 101 | + | Make git use g1t's credentials for pushing and fetching over HTTPS. | |
| 102 | + | ||
| 103 | + | ```text | |
| 104 | + | g1t auth setup-git [OPTIONS] | |
| 105 | + | ``` | |
| 106 | + | ||
| 107 | + | | Argument or flag | | | |
| 108 | + | | --- | --- | | |
| 109 | + | | `--dry-run` | Print the git config commands instead of running them. | | |
| 110 | + | ||
| 111 | + | ## g1t repo | |
| 112 | + | ||
| 113 | + | Repositories: view, clone, create, list. | |
| 114 | + | ||
| 115 | + | ### g1t repo view | |
| 116 | + | ||
| 117 | + | Show a repository. | |
| 118 | + | ||
| 119 | + | ```text | |
| 120 | + | g1t repo view [OPTIONS] [REPOSITORY] | |
| 121 | + | ``` | |
| 122 | + | ||
| 123 | + | | Argument or flag | | | |
| 124 | + | | --- | --- | | |
| 125 | + | | `[REPOSITORY]` | OWNER/NAME; the current repository when left out. | | |
| 126 | + | | `-w, --web` | Open it in the browser. | | |
| 127 | + | ||
| 128 | + | Calls [`get_repo`](/reference/api/repositories/get-repo/). | |
| 129 | + | ||
| 130 | + | ### g1t repo clone | |
| 131 | + | ||
| 132 | + | Clone a repository. | |
| 133 | + | ||
| 134 | + | ```text | |
| 135 | + | g1t repo clone [OPTIONS] <REPOSITORY> [DIRECTORY] [-- <GIT_FLAGS>...] | |
| 136 | + | ``` | |
| 137 | + | ||
| 138 | + | | Argument or flag | | | |
| 139 | + | | --- | --- | | |
| 140 | + | | `<REPOSITORY>` | OWNER/NAME, or NAME for one of your own. | | |
| 141 | + | | `[DIRECTORY]` | Where to clone it. | | |
| 142 | + | | `[GIT_FLAGS]` | After `--`. Flags for git clone, after --. | | |
| 143 | + | ||
| 144 | + | Calls [`whoami`](/reference/api/accounts/whoami/). | |
| 145 | + | ||
| 146 | + | ### g1t repo create | |
| 147 | + | ||
| 148 | + | Make a repository. | |
| 149 | + | ||
| 150 | + | ```text | |
| 151 | + | g1t repo create [OPTIONS] [NAME] | |
| 152 | + | ``` | |
| 153 | + | ||
| 154 | + | | Argument or flag | | | |
| 155 | + | | --- | --- | | |
| 156 | + | | `[NAME]` | NAME, or WORKSPACE/NAME. | | |
| 157 | + | | `--public` | Anyone can see it. Repositories are private unless this is given. | | |
| 158 | + | | `--private` | Only people with a role on it can see it (the default). | | |
| 159 | + | | `-d, --description <DESCRIPTION>` | | | |
| 160 | + | | `-c, --clone` | Clone it once it is made. | | |
| 161 | + | | `--source <DIR>` | Add it as a remote of this directory's repository and push it there. | | |
| 162 | + | | `--remote <REMOTE>` | The remote's name, with --source. Default: `origin`. | | |
| 163 | + | ||
| 164 | + | Calls [`create_repo`](/reference/api/repositories/create-repo/). | |
| 165 | + | ||
| 166 | + | ### g1t repo list | |
| 167 | + | ||
| 168 | + | List repositories you can see. | |
| 169 | + | ||
| 170 | + | ```text | |
| 171 | + | g1t repo list [OPTIONS] [WORKSPACE] | |
| 172 | + | ``` | |
| 173 | + | ||
| 174 | + | | Argument or flag | | | |
| 175 | + | | --- | --- | | |
| 176 | + | | `[WORKSPACE]` | Only this workspace's. | | |
| 177 | + | | `-q, --query <QUERY>` | Only those whose name or description holds this. | | |
| 178 | + | | `-L, --limit <LIMIT>` | Default: `20`. | | |
| 179 | + | ||
| 180 | + | Calls [`list_repos`](/reference/api/repositories/list-repos/). | |
| 181 | + | ||
| 182 | + | ## g1t issue | |
| 183 | + | ||
| 184 | + | Issues: list, view, create, comment, close, reopen, edit. | |
| 185 | + | ||
| 186 | + | ### g1t issue list | |
| 187 | + | ||
| 188 | + | List issues. | |
| 189 | + | ||
| 190 | + | ```text | |
| 191 | + | g1t issue list [OPTIONS] | |
| 192 | + | ``` | |
| 193 | + | ||
| 194 | + | | Argument or flag | | | |
| 195 | + | | --- | --- | | |
| 196 | + | | `-s, --state <STATE>` | One of `open`, `closed`, `all`. Default: `open`. | | |
| 197 | + | | `-l, --label <LABEL>` | Only issues with this label. | | |
| 198 | + | | `-m, --milestone <MILESTONE>` | Only issues in the milestone of this number. | | |
| 199 | + | | `-a, --assignee <ASSIGNEE>` | Only issues assigned to this person (@me for you). | | |
| 200 | + | | `-A, --author <AUTHOR>` | Only issues opened by this person (@me for you). | | |
| 201 | + | | `-L, --limit <LIMIT>` | Default: `20`. | | |
| 202 | + | ||
| 203 | + | Calls [`list_issues`](/reference/api/issues/list-issues/). | |
| 204 | + | ||
| 205 | + | ### g1t issue view | |
| 206 | + | ||
| 207 | + | Show an issue, with its comments. | |
| 208 | + | ||
| 209 | + | ```text | |
| 210 | + | g1t issue view [OPTIONS] <NUMBER> | |
| 211 | + | ``` | |
| 212 | + | ||
| 213 | + | | Argument or flag | | | |
| 214 | + | | --- | --- | | |
| 215 | + | | `<NUMBER>` | The issue's number. | | |
| 216 | + | | `-c, --comments` | Show its comments too. | | |
| 217 | + | | `-w, --web` | Open it in the browser. | | |
| 218 | + | ||
| 219 | + | Calls [`get_issue`](/reference/api/issues/get-issue/). | |
| 220 | + | ||
| 221 | + | ### g1t issue create | |
| 222 | + | ||
| 223 | + | Open an issue. | |
| 224 | + | ||
| 225 | + | ```text | |
| 226 | + | g1t issue create [OPTIONS] | |
| 227 | + | ``` | |
| 228 | + | ||
| 229 | + | | Argument or flag | | | |
| 230 | + | | --- | --- | | |
| 231 | + | | `-t, --title <TITLE>` | | | |
| 232 | + | | `-b, --body <BODY>` | The text. Markdown. | | |
| 233 | + | | `-F, --body-file <FILE>` | Read the text from a file, or - for stdin. | | |
| 234 | + | | `-l, --label <LABEL>` | A label; repeat for more. | | |
| 235 | + | | `-a, --assignee <ASSIGNEE>` | Someone to assign; repeat for more (@me for you). | | |
| 236 | + | | `-m, --milestone <MILESTONE>` | A milestone's number. | | |
| 237 | + | | `-w, --web` | Open the new-issue page in the browser instead. | | |
| 238 | + | ||
| 239 | + | Calls [`create_issue`](/reference/api/issues/create-issue/), [`update_issue`](/reference/api/issues/update-issue/). | |
| 240 | + | ||
| 241 | + | ### g1t issue comment | |
| 242 | + | ||
| 243 | + | Comment on an issue. | |
| 244 | + | ||
| 245 | + | ```text | |
| 246 | + | g1t issue comment [OPTIONS] [NUMBER] | |
| 247 | + | ``` | |
| 248 | + | ||
| 249 | + | | Argument or flag | | | |
| 250 | + | | --- | --- | | |
| 251 | + | | `[NUMBER]` | The number; for a pull request, the current branch's when left out. | | |
| 252 | + | | `-b, --body <BODY>` | The text. Markdown. | | |
| 253 | + | | `-F, --body-file <FILE>` | Read the text from a file, or - for stdin. | | |
| 254 | + | ||
| 255 | + | Calls [`add_comment`](/reference/api/issues/add-comment/). | |
| 256 | + | ||
| 257 | + | ### g1t issue close | |
| 258 | + | ||
| 259 | + | Close an issue. | |
| 260 | + | ||
| 261 | + | ```text | |
| 262 | + | g1t issue close [OPTIONS] <NUMBER> | |
| 263 | + | ``` | |
| 264 | + | ||
| 265 | + | | Argument or flag | | | |
| 266 | + | | --- | --- | | |
| 267 | + | | `<NUMBER>` | | | |
| 268 | + | | `-r, --reason <REASON>` | One of `completed`, `not-planned`. | | |
| 269 | + | | `-c, --comment <COMMENT>` | Leave a comment as it closes. | | |
| 270 | + | ||
| 271 | + | Calls [`close_issue`](/reference/api/issues/close-issue/), [`add_comment`](/reference/api/issues/add-comment/). | |
| 272 | + | ||
| 273 | + | ### g1t issue reopen | |
| 274 | + | ||
| 275 | + | Reopen an issue. | |
| 276 | + | ||
| 277 | + | ```text | |
| 278 | + | g1t issue reopen [OPTIONS] <NUMBER> | |
| 279 | + | ``` | |
| 280 | + | ||
| 281 | + | | Argument or flag | | | |
| 282 | + | | --- | --- | | |
| 283 | + | | `<NUMBER>` | | | |
| 284 | + | | `-c, --comment <COMMENT>` | Leave a comment as it reopens. | | |
| 285 | + | ||
| 286 | + | Calls [`reopen_issue`](/reference/api/issues/reopen-issue/), [`add_comment`](/reference/api/issues/add-comment/). | |
| 287 | + | ||
| 288 | + | ### g1t issue edit | |
| 289 | + | ||
| 290 | + | Change an issue's title, body, labels, assignees or milestone. | |
| 291 | + | ||
| 292 | + | ```text | |
| 293 | + | g1t issue edit [OPTIONS] <NUMBER> | |
| 294 | + | ``` | |
| 295 | + | ||
| 296 | + | | Argument or flag | | | |
| 297 | + | | --- | --- | | |
| 298 | + | | `<NUMBER>` | | | |
| 299 | + | | `-t, --title <TITLE>` | | | |
| 300 | + | | `-b, --body <BODY>` | The text. Markdown. | | |
| 301 | + | | `-F, --body-file <FILE>` | Read the text from a file, or - for stdin. | | |
| 302 | + | | `--add-label <LABEL>` | | | |
| 303 | + | | `--remove-label <LABEL>` | | | |
| 304 | + | | `--add-assignee <LOGIN>` | | | |
| 305 | + | | `--remove-assignee <LOGIN>` | | | |
| 306 | + | | `-m, --milestone <MILESTONE>` | A milestone's number. | | |
| 307 | + | | `--remove-milestone` | Take it out of its milestone. | | |
| 308 | + | ||
| 309 | + | Calls [`update_issue`](/reference/api/issues/update-issue/), [`get_issue`](/reference/api/issues/get-issue/). | |
| 310 | + | ||
| 311 | + | ## g1t pr | |
| 312 | + | ||
| 313 | + | Pull requests: list, view, create, check out, diff, checks, review, merge. | |
| 314 | + | ||
| 315 | + | ### g1t pr list | |
| 316 | + | ||
| 317 | + | List pull requests. | |
| 318 | + | ||
| 319 | + | ```text | |
| 320 | + | g1t pr list [OPTIONS] | |
| 321 | + | ``` | |
| 322 | + | ||
| 323 | + | | Argument or flag | | | |
| 324 | + | | --- | --- | | |
| 325 | + | | `-s, --state <STATE>` | One of `open`, `closed`, `merged`, `all`. Default: `open`. | | |
| 326 | + | | `-B, --base <BASE>` | Only those merging into this branch. | | |
| 327 | + | | `-l, --label <LABEL>` | | | |
| 328 | + | | `-A, --author <AUTHOR>` | Only those opened by this person (@me for you). | | |
| 329 | + | | `-d, --draft` | Only drafts. | | |
| 330 | + | | `-L, --limit <LIMIT>` | Default: `20`. | | |
| 331 | + | ||
| 332 | + | Calls [`list_pull_requests`](/reference/api/pull-requests/list-pull-requests/). | |
| 333 | + | ||
| 334 | + | ### g1t pr view | |
| 335 | + | ||
| 336 | + | Show a pull request. | |
| 337 | + | ||
| 338 | + | ```text | |
| 339 | + | g1t pr view [OPTIONS] [NUMBER] | |
| 340 | + | ``` | |
| 341 | + | ||
| 342 | + | | Argument or flag | | | |
| 343 | + | | --- | --- | | |
| 344 | + | | `[NUMBER]` | The number; the current branch's when left out. | | |
| 345 | + | | `-c, --comments` | | | |
| 346 | + | | `-w, --web` | | | |
| 347 | + | ||
| 348 | + | Calls [`get_pull_request`](/reference/api/pull-requests/get-pull-request/), [`list_pull_requests`](/reference/api/pull-requests/list-pull-requests/). | |
| 349 | + | ||
| 350 | + | ### g1t pr create | |
| 351 | + | ||
| 352 | + | Open a pull request from a branch, or start one for an issue. | |
| 353 | + | ||
| 354 | + | ```text | |
| 355 | + | g1t pr create [OPTIONS] | |
| 356 | + | ``` | |
| 357 | + | ||
| 358 | + | | Argument or flag | | | |
| 359 | + | | --- | --- | | |
| 360 | + | | `-t, --title <TITLE>` | | | |
| 361 | + | | `-b, --body <BODY>` | The text. Markdown. | | |
| 362 | + | | `-F, --body-file <FILE>` | Read the text from a file, or - for stdin. | | |
| 363 | + | | `-B, --base <BASE>` | The branch to merge into; the default branch when left out. | | |
| 364 | + | | `-H, --head <HEAD>` | The branch with the changes; the current one when left out. | | |
| 365 | + | | `-i, --issue <ISSUE>` | The issue it is for. Without a branch, starts a draft in a working copy of its own. | | |
| 366 | + | | `-f, --fill` | Take the title and body from the branch's commits. | | |
| 367 | + | | `-d, --draft` | Open it as a draft. | | |
| 368 | + | | `--no-push` | Do not push the branch first. | | |
| 369 | + | ||
| 370 | + | Calls [`create_pull_request`](/reference/api/pull-requests/create-pull-request/), [`get_repo`](/reference/api/repositories/get-repo/), [`convert_pull_request_to_draft`](/reference/api/pull-requests/convert-pull-request-to-draft/). | |
| 371 | + | ||
| 372 | + | ### g1t pr checkout | |
| 373 | + | ||
| 374 | + | Check a pull request's changes out locally. | |
| 375 | + | ||
| 376 | + | ```text | |
| 377 | + | g1t pr checkout [OPTIONS] <NUMBER> | |
| 378 | + | ``` | |
| 379 | + | ||
| 380 | + | | Argument or flag | | | |
| 381 | + | | --- | --- | | |
| 382 | + | | `<NUMBER>` | | | |
| 383 | + | | `-b, --branch <BRANCH>` | The local branch's name; pr-NUMBER when left out. | | |
| 384 | + | | `-f, --force` | Reset the local branch to the pull request's head even if it has other commits. | | |
| 385 | + | ||
| 386 | + | Calls [`get_pull_request`](/reference/api/pull-requests/get-pull-request/). | |
| 387 | + | ||
| 388 | + | ### g1t pr diff | |
| 389 | + | ||
| 390 | + | Show a pull request's changes as a diff. | |
| 391 | + | ||
| 392 | + | ```text | |
| 393 | + | g1t pr diff [OPTIONS] [NUMBER] | |
| 394 | + | ``` | |
| 395 | + | ||
| 396 | + | | Argument or flag | | | |
| 397 | + | | --- | --- | | |
| 398 | + | | `[NUMBER]` | | | |
| 399 | + | | `--name-only` | Only the changed files' names. | | |
| 400 | + | | `--color <COLOR>` | Color: auto, always or never. Default: `auto`. | | |
| 401 | + | ||
| 402 | + | Calls [`get_pull_request_changes`](/reference/api/pull-requests/get-pull-request-changes/). | |
| 403 | + | ||
| 404 | + | ### g1t pr checks | |
| 405 | + | ||
| 406 | + | Show a pull request's checks; --watch waits for them. | |
| 407 | + | ||
| 408 | + | ```text | |
| 409 | + | g1t pr checks [OPTIONS] [NUMBER] | |
| 410 | + | ``` | |
| 411 | + | ||
| 412 | + | | Argument or flag | | | |
| 413 | + | | --- | --- | | |
| 414 | + | | `[NUMBER]` | | | |
| 415 | + | | `-w, --watch` | Wait until every check has finished. | | |
| 416 | + | | `--fail-fast` | With --watch, stop at the first failing check. | | |
| 417 | + | | `-i, --interval <INTERVAL>` | Seconds between looks, with --watch. Default: `10`. | | |
| 418 | + | ||
| 419 | + | Calls [`get_pull_request`](/reference/api/pull-requests/get-pull-request/), [`list_check_runs_for_ref`](/reference/api/checks/list-check-runs-for-ref/), [`get_combined_status`](/reference/api/checks/get-combined-status/). | |
| 420 | + | ||
| 421 | + | ### g1t pr review | |
| 422 | + | ||
| 423 | + | Approve a pull request, or ask for changes. | |
| 424 | + | ||
| 425 | + | ```text | |
| 426 | + | g1t pr review [OPTIONS] <--approve|--request-changes|--comment> [NUMBER] | |
| 427 | + | ``` | |
| 428 | + | ||
| 429 | + | | Argument or flag | | | |
| 430 | + | | --- | --- | | |
| 431 | + | | `[NUMBER]` | | | |
| 432 | + | | `-a, --approve` | | | |
| 433 | + | | `-r, --request-changes` | | | |
| 434 | + | | `-c, --comment` | Comment without approving or asking for changes. | | |
| 435 | + | | `-b, --body <BODY>` | The text. Markdown. | | |
| 436 | + | | `-F, --body-file <FILE>` | Read the text from a file, or - for stdin. | | |
| 437 | + | ||
| 438 | + | Calls [`review_pull_request`](/reference/api/pull-requests/review-pull-request/), [`add_comment`](/reference/api/issues/add-comment/). | |
| 439 | + | ||
| 440 | + | ### g1t pr merge | |
| 441 | + | ||
| 442 | + | Merge a pull request. | |
| 443 | + | ||
| 444 | + | ```text | |
| 445 | + | g1t pr merge [OPTIONS] [NUMBER] | |
| 446 | + | ``` | |
| 447 | + | ||
| 448 | + | | Argument or flag | | | |
| 449 | + | | --- | --- | | |
| 450 | + | | `[NUMBER]` | | | |
| 451 | + | | `--keep-issue-open` | Leave the issue it is for open. | | |
| 452 | + | | `--admin` | Merge past failing required checks and rules (needs the Admin role). | | |
| 453 | + | | `-d, --delete-branch` | Delete the local and remote branch afterwards. | | |
| 454 | + | ||
| 455 | + | Calls [`merge_pull_request`](/reference/api/pull-requests/merge-pull-request/), [`delete_branch`](/reference/api/repositories/delete-branch/). | |
| 456 | + | ||
| 457 | + | ### g1t pr ready | |
| 458 | + | ||
| 459 | + | Mark a draft ready for review, or turn it back into a draft. | |
| 460 | + | ||
| 461 | + | ```text | |
| 462 | + | g1t pr ready [OPTIONS] [NUMBER] | |
| 463 | + | ``` | |
| 464 | + | ||
| 465 | + | | Argument or flag | | | |
| 466 | + | | --- | --- | | |
| 467 | + | | `[NUMBER]` | | | |
| 468 | + | | `-s, --summary <SUMMARY>` | What changed and why; it becomes the description. The current one when left out. | | |
| 469 | + | | `--undo` | Turn it back into a draft. | | |
| 470 | + | ||
| 471 | + | Calls [`mark_pull_request_ready`](/reference/api/pull-requests/mark-pull-request-ready/), [`convert_pull_request_to_draft`](/reference/api/pull-requests/convert-pull-request-to-draft/). | |
| 472 | + | ||
| 473 | + | ### g1t pr comment | |
| 474 | + | ||
| 475 | + | Comment on a pull request. | |
| 476 | + | ||
| 477 | + | ```text | |
| 478 | + | g1t pr comment [OPTIONS] [NUMBER] | |
| 479 | + | ``` | |
| 480 | + | ||
| 481 | + | | Argument or flag | | | |
| 482 | + | | --- | --- | | |
| 483 | + | | `[NUMBER]` | The number; for a pull request, the current branch's when left out. | | |
| 484 | + | | `-b, --body <BODY>` | The text. Markdown. | | |
| 485 | + | | `-F, --body-file <FILE>` | Read the text from a file, or - for stdin. | | |
| 486 | + | ||
| 487 | + | Calls [`add_comment`](/reference/api/issues/add-comment/). | |
| 488 | + | ||
| 489 | + | ### g1t pr close | |
| 490 | + | ||
| 491 | + | Close a pull request without merging it. | |
| 492 | + | ||
| 493 | + | ```text | |
| 494 | + | g1t pr close [OPTIONS] [NUMBER] | |
| 495 | + | ``` | |
| 496 | + | ||
| 497 | + | | Argument or flag | | | |
| 498 | + | | --- | --- | | |
| 499 | + | | `[NUMBER]` | The number; the current branch's when left out. | | |
| 500 | + | ||
| 501 | + | Calls [`close_pull_request`](/reference/api/pull-requests/close-pull-request/). | |
| 502 | + | ||
| 503 | + | ### g1t pr reopen | |
| 504 | + | ||
| 505 | + | Reopen a closed pull request. | |
| 506 | + | ||
| 507 | + | ```text | |
| 508 | + | g1t pr reopen [OPTIONS] [NUMBER] | |
| 509 | + | ``` | |
| 510 | + | ||
| 511 | + | | Argument or flag | | | |
| 512 | + | | --- | --- | | |
| 513 | + | | `[NUMBER]` | The number; the current branch's when left out. | | |
| 514 | + | ||
| 515 | + | Calls [`reopen_pull_request`](/reference/api/pull-requests/reopen-pull-request/). | |
| 516 | + | ||
| 517 | + | ## g1t run | |
| 518 | + | ||
| 519 | + | Workflow runs: list, view, watch, logs, rerun, cancel. | |
| 520 | + | ||
| 521 | + | ### g1t run list | |
| 522 | + | ||
| 523 | + | List workflow runs, newest first. | |
| 524 | + | ||
| 525 | + | ```text | |
| 526 | + | g1t run list [OPTIONS] | |
| 527 | + | ``` | |
| 528 | + | ||
| 529 | + | | Argument or flag | | | |
| 530 | + | | --- | --- | | |
| 531 | + | | `-w, --workflow <WORKFLOW>` | Only this workflow's: its file name or id. | | |
| 532 | + | | `-b, --branch <BRANCH>` | | | |
| 533 | + | | `-e, --event <EVENT>` | Only runs for this event: push, pull_request, schedule... | | |
| 534 | + | | `-c, --commit <COMMIT>` | Only runs of this commit. | | |
| 535 | + | | `--pr <PR>` | Only runs for this pull request. | | |
| 536 | + | | `-L, --limit <LIMIT>` | Default: `20`. | | |
| 537 | + | ||
| 538 | + | Calls [`list_workflow_runs`](/reference/api/actions/list-workflow-runs/). | |
| 539 | + | ||
| 540 | + | ### g1t run view | |
| 541 | + | ||
| 542 | + | Show a run's jobs and steps. | |
| 543 | + | ||
| 544 | + | ```text | |
| 545 | + | g1t run view [OPTIONS] [RUN] | |
| 546 | + | ``` | |
| 547 | + | ||
| 548 | + | | Argument or flag | | | |
| 549 | + | | --- | --- | | |
| 550 | + | | `[RUN]` | | | |
| 551 | + | | `-j, --job <JOB>` | Show this job's steps only. | | |
| 552 | + | | `--log` | Print the log too. | | |
| 553 | + | | `--log-failed` | Print the failing steps' logs too. | | |
| 554 | + | | `-w, --web` | | | |
| 555 | + | | `--exit-status` | Exit 1 when the run failed. | | |
| 556 | + | ||
| 557 | + | Calls [`get_workflow_run`](/reference/api/actions/get-workflow-run/), [`get_job_logs`](/reference/api/actions/get-job-logs/). | |
| 558 | + | ||
| 559 | + | ### g1t run watch | |
| 560 | + | ||
| 561 | + | Follow a run until it finishes; exits 1 if it fails. | |
| 562 | + | ||
| 563 | + | ```text | |
| 564 | + | g1t run watch [OPTIONS] [RUN] | |
| 565 | + | ``` | |
| 566 | + | ||
| 567 | + | | Argument or flag | | | |
| 568 | + | | --- | --- | | |
| 569 | + | | `[RUN]` | | | |
| 570 | + | | `-i, --interval <INTERVAL>` | Seconds between looks. Default: `3`. | | |
| 571 | + | ||
| 572 | + | Calls [`get_workflow_run`](/reference/api/actions/get-workflow-run/). | |
| 573 | + | ||
| 574 | + | ### g1t run logs | |
| 575 | + | ||
| 576 | + | Print a run's logs; --failed prints only the failing steps' tails. | |
| 577 | + | ||
| 578 | + | ```text | |
| 579 | + | g1t run logs [OPTIONS] [RUN] | |
| 580 | + | ``` | |
| 581 | + | ||
| 582 | + | | Argument or flag | | | |
| 583 | + | | --- | --- | | |
| 584 | + | | `[RUN]` | | | |
| 585 | + | | `-j, --job <JOB>` | Only this job's (its id, key or name). | | |
| 586 | + | | `-f, --failed` | Only the failing steps, and only their last lines. | | |
| 587 | + | | `-n, --tail <TAIL>` | How many lines of each failing step to print, with --failed. Default: `60`. | | |
| 588 | + | ||
| 589 | + | Calls [`get_workflow_run`](/reference/api/actions/get-workflow-run/), [`get_job_logs`](/reference/api/actions/get-job-logs/). | |
| 590 | + | ||
| 591 | + | ### g1t run rerun | |
| 592 | + | ||
| 593 | + | Run a run again: all of it, its failed jobs, or one job. | |
| 594 | + | ||
| 595 | + | ```text | |
| 596 | + | g1t run rerun [OPTIONS] [RUN] | |
| 597 | + | ``` | |
| 598 | + | ||
| 599 | + | | Argument or flag | | | |
| 600 | + | | --- | --- | | |
| 601 | + | | `[RUN]` | | | |
| 602 | + | | `--failed` | Only the jobs that failed. | | |
| 603 | + | | `-j, --job <JOB>` | Only this job (its id). | | |
| 604 | + | | `-d, --debug` | With debug logging. | | |
| 605 | + | ||
| 606 | + | Calls [`rerun_workflow_run`](/reference/api/actions/rerun-workflow-run/), [`rerun_failed_jobs`](/reference/api/actions/rerun-failed-jobs/), [`rerun_job`](/reference/api/actions/rerun-job/). | |
| 607 | + | ||
| 608 | + | ### g1t run cancel | |
| 609 | + | ||
| 610 | + | Cancel a run. | |
| 611 | + | ||
| 612 | + | ```text | |
| 613 | + | g1t run cancel [OPTIONS] [RUN] | |
| 614 | + | ``` | |
| 615 | + | ||
| 616 | + | | Argument or flag | | | |
| 617 | + | | --- | --- | | |
| 618 | + | | `[RUN]` | The run's id (run_…) or number; the current branch's latest when left out. | | |
| 619 | + | ||
| 620 | + | Calls [`cancel_workflow_run`](/reference/api/actions/cancel-workflow-run/). | |
| 621 | + | ||
| 622 | + | ## g1t secret | |
| 623 | + | ||
| 624 | + | Secrets for workflows and deployments, a repository's or a workspace's. | |
| 625 | + | ||
| 626 | + | ### g1t secret list | |
| 627 | + | ||
| 628 | + | List secrets' names (never their values). | |
| 629 | + | ||
| 630 | + | ```text | |
| 631 | + | g1t secret list [OPTIONS] | |
| 632 | + | ``` | |
| 633 | + | ||
| 634 | + | | Argument or flag | | | |
| 635 | + | | --- | --- | | |
| 636 | + | | `-w, --workspace <WORKSPACE>` | A workspace's secrets instead of the repository's. | | |
| 637 | + | | `-e, --env <ENVIRONMENT>` | Only the value for this environment (production, preview...). | | |
| 638 | + | ||
| 639 | + | Calls [`list_actions_secrets`](/reference/api/secrets-and-variables/list-actions-secrets/), [`list_actions_secrets_for_workspace`](/reference/api/secrets-and-variables/list-actions-secrets-for-workspace/). | |
| 640 | + | ||
| 641 | + | ### g1t secret set | |
| 642 | + | ||
| 643 | + | Set a secret. The value is read from stdin when not given. | |
| 644 | + | ||
| 645 | + | ```text | |
| 646 | + | g1t secret set [OPTIONS] <NAME> | |
| 647 | + | ``` | |
| 648 | + | ||
| 649 | + | | Argument or flag | | | |
| 650 | + | | --- | --- | | |
| 651 | + | | `<NAME>` | The secret's name; uppercased. | | |
| 652 | + | | `-b, --body <BODY>` | The value. Read from stdin when left out, so it stays out of your shell's history. | | |
| 653 | + | | `-w, --workspace <WORKSPACE>` | A workspace's secrets instead of the repository's. | | |
| 654 | + | | `-e, --env <ENVIRONMENT>` | Only the value for this environment (production, preview...). | | |
| 655 | + | | `--available-to <WHO>` | Who can read it: workflows, deployments, or both (repeat). | | |
| 656 | + | | `--brokered-host <HOST>` | Broker it: jobs get a stand-in, and g1t fills the value in only on requests to this host. Repeat for more. | | |
| 657 | + | | `--note <NOTE>` | A note for whoever reads the list. | | |
| 658 | + | ||
| 659 | + | Calls [`set_actions_secret`](/reference/api/secrets-and-variables/set-actions-secret/), [`set_actions_secret_for_workspace`](/reference/api/secrets-and-variables/set-actions-secret-for-workspace/). | |
| 660 | + | ||
| 661 | + | ### g1t secret delete | |
| 662 | + | ||
| 663 | + | Delete a secret. | |
| 664 | + | ||
| 665 | + | ```text | |
| 666 | + | g1t secret delete [OPTIONS] <NAME> | |
| 667 | + | ``` | |
| 668 | + | ||
| 669 | + | | Argument or flag | | | |
| 670 | + | | --- | --- | | |
| 671 | + | | `<NAME>` | | | |
| 672 | + | | `-w, --workspace <WORKSPACE>` | A workspace's secrets instead of the repository's. | | |
| 673 | + | | `-e, --env <ENVIRONMENT>` | Only the value for this environment (production, preview...). | | |
| 674 | + | ||
| 675 | + | Calls [`delete_actions_secret`](/reference/api/secrets-and-variables/delete-actions-secret/), [`delete_actions_secret_for_workspace`](/reference/api/secrets-and-variables/delete-actions-secret-for-workspace/). | |
| 676 | + | ||
| 677 | + | ## g1t deploy | |
| 678 | + | ||
| 679 | + | Deployments: list and view. | |
| 680 | + | ||
| 681 | + | ### g1t deploy list | |
| 682 | + | ||
| 683 | + | List deployments, newest first. | |
| 684 | + | ||
| 685 | + | ```text | |
| 686 | + | g1t deploy list [OPTIONS] | |
| 687 | + | ``` | |
| 688 | + | ||
| 689 | + | | Argument or flag | | | |
| 690 | + | | --- | --- | | |
| 691 | + | | `-e, --env <ENV>` | | | |
| 692 | + | | `-s, --state <STATE>` | queued, in_progress, success, failure, error or inactive. | | |
| 693 | + | | `--source <SOURCE>` | api, actions or g1t_page. | | |
| 694 | + | | `-L, --limit <LIMIT>` | Default: `20`. | | |
| 695 | + | ||
| 696 | + | Calls [`list_deployments`](/reference/api/deployments/list-deployments/). | |
| 697 | + | ||
| 698 | + | ### g1t deploy view | |
| 699 | + | ||
| 700 | + | Show a deployment and its statuses. | |
| 701 | + | ||
| 702 | + | ```text | |
| 703 | + | g1t deploy view [OPTIONS] <ID> | |
| 704 | + | ``` | |
| 705 | + | ||
| 706 | + | | Argument or flag | | | |
| 707 | + | | --- | --- | | |
| 708 | + | | `<ID>` | | | |
| 709 | + | | `-w, --web` | | | |
| 710 | + | ||
| 711 | + | Calls [`get_deployment`](/reference/api/deployments/get-deployment/). | |
| 712 | + | ||
| 713 | + | ## g1t logs | |
| 714 | + | ||
| 715 | + | A project's logs and errors. | |
| 716 | + | ||
| 717 | + | ```text | |
| 718 | + | g1t logs [OPTIONS] | |
| 719 | + | ``` | |
| 720 | + | ||
| 721 | + | | Argument or flag | | | |
| 722 | + | | --- | --- | | |
| 723 | + | | `-p, --project <PROJECT>` | The project; the current repository's when left out. | | |
| 724 | + | | `--errors` | Grouped errors instead of log lines. | | |
| 725 | + | | `-q, --query <QUERY>` | Lines holding all of these words, or a "quoted phrase". | | |
| 726 | + | | `-l, --level <LEVEL>` | Levels: trace, debug, info, warn, error, fatal (comma-separated). | | |
| 727 | + | | `-e, --env <ENV>` | | | |
| 728 | + | | `--service <SERVICE>` | | | |
| 729 | + | | `-s, --since <SINCE>` | How far back: 15m, 2h, 1d, or a time like 2026-10-12T09:00:00Z. | | |
| 730 | + | | `--state <STATE>` | With --errors: open, resolved or ignored. | | |
| 731 | + | | `-f, --follow` | Keep printing new lines as they come. | | |
| 732 | + | | `-L, --limit <LIMIT>` | Default: `50`. | | |
| 733 | + | ||
| 734 | + | Calls [`list_logs`](/reference/api/observability/list-logs/), [`list_errors`](/reference/api/observability/list-errors/), [`list_projects`](/reference/api/projects/list-projects/), [`get_repo`](/reference/api/repositories/get-repo/). | |
| 735 | + | ||
| 736 | + | ## g1t status | |
| 737 | + | ||
| 738 | + | What needs you: your pull requests, reviews asked of you, your issues, failing checks. | |
| 739 | + | ||
| 740 | + | ```text | |
| 741 | + | g1t status [OPTIONS] | |
| 742 | + | ``` | |
| 743 | + | ||
| 744 | + | Calls [`search`](/reference/api/search/search/), [`list_notifications`](/reference/api/notifications/list-notifications/), [`get_pull_request`](/reference/api/pull-requests/get-pull-request/). | |
| 745 | + | ||
| 746 | + | ## g1t api | |
| 747 | + | ||
| 748 | + | Call any API operation or path, with your token. | |
| 749 | + | ||
| 750 | + | ```text | |
| 751 | + | g1t api [OPTIONS] [ENDPOINT] | |
| 752 | + | ``` | |
| 753 | + | ||
| 754 | + | | Argument or flag | | | |
| 755 | + | | --- | --- | | |
| 756 | + | | `[ENDPOINT]` | An operation's name, or a path. | | |
| 757 | + | | `--list [QUERY]` | List the operations, or those matching this word. | | |
| 758 | + | | `-X, --method <METHOD>` | The HTTP method: GET unless fields are given, then POST. | | |
| 759 | + | | `-f, --raw-field <KEY=VALUE>` | A string field, key=value. key[]=value adds to a list. | | |
| 760 | + | | `-F, --field <KEY=VALUE>` | A typed field: true, false, null and numbers become JSON; @file reads a file. | | |
| 761 | + | | `-H, --header <KEY:VALUE>` | A request header, key:value. | | |
| 762 | + | | `--input <FILE>` | The request body, from a file or - for stdin. | | |
| 763 | + | | `--paginate` | Follow next pages until there are none. | | |
| 764 | + | | `--slurp` | With --paginate, put every page's items into one array. | | |
| 765 | + | | `-i, --include` | Print the status line and headers too. | | |
| 766 | + | | `--silent` | Print nothing on success. | | |
| 767 | + | ||
| 768 | + | ```text | |
| 769 | + | ENDPOINT is an operation's name (list_issues) or a path (/repos/{owner}/{name}/issues). | |
| 770 | + | {owner}, {name}, {repo} and {workspace} are filled in from the current repository, | |
| 771 | + | and an operation's other path parameters from -f/-F fields of the same name. | |
| 772 | + | ||
| 773 | + | Examples: | |
| 774 | + | g1t api list_issues -f state=closed | |
| 775 | + | g1t api /user --jq .username | |
| 776 | + | g1t api create_issue -f title='Broken link' -f labels[]=docs | |
| 777 | + | g1t api list_workflow_runs --paginate --jq '.[].conclusion' | |
| 778 | + | g1t api --list issue | |
| 779 | + | ``` | |
| 780 | + | ||
| 781 | + | ## g1t browse | |
| 782 | + | ||
| 783 | + | Open the repository, an issue or a pull request in the browser. | |
| 784 | + | ||
| 785 | + | ```text | |
| 786 | + | g1t browse [OPTIONS] [TARGET] | |
| 787 | + | ``` | |
| 788 | + | ||
| 789 | + | | Argument or flag | | | |
| 790 | + | | --- | --- | | |
| 791 | + | | `[TARGET]` | An issue or pull request number, a file path (path:line), or a commit. | | |
| 792 | + | | `-b, --branch <BRANCH>` | The branch to show files on. | | |
| 793 | + | | `-s, --settings` | | | |
| 794 | + | | `--issues` | | | |
| 795 | + | | `--pulls` | | | |
| 796 | + | | `--actions` | | | |
| 797 | + | | `-n, --no-browser` | Print the address instead of opening it. | | |
| 798 | + | ||
| 799 | + | ## g1t alias | |
| 800 | + | ||
| 801 | + | Shortcuts for commands you type often. | |
| 802 | + | ||
| 803 | + | ### g1t alias set | |
| 804 | + | ||
| 805 | + | Make an alias: g1t alias set co 'pr checkout'. Start it with ! to run it through the shell. | |
| 806 | + | ||
| 807 | + | ```text | |
| 808 | + | g1t alias set [OPTIONS] <NAME> <EXPANSION> | |
| 809 | + | ``` | |
| 810 | + | ||
| 811 | + | | Argument or flag | | | |
| 812 | + | | --- | --- | | |
| 813 | + | | `<NAME>` | | | |
| 814 | + | | `<EXPANSION>` | What it expands to. $1, $2... take the arguments after it. | | |
| 815 | + | ||
| 816 | + | ### g1t alias list | |
| 817 | + | ||
| 818 | + | List aliases. | |
| 819 | + | ||
| 820 | + | ```text | |
| 821 | + | g1t alias list [OPTIONS] | |
| 822 | + | ``` | |
| 823 | + | ||
| 824 | + | ### g1t alias delete | |
| 825 | + | ||
| 826 | + | Delete an alias. | |
| 827 | + | ||
| 828 | + | ```text | |
| 829 | + | g1t alias delete [OPTIONS] <NAME> | |
| 830 | + | ``` | |
| 831 | + | ||
| 832 | + | | Argument or flag | | | |
| 833 | + | | --- | --- | | |
| 834 | + | | `<NAME>` | | | |
| 835 | + | ||
| 836 | + | ## g1t completion | |
| 837 | + | ||
| 838 | + | Print a shell completion script. | |
| 839 | + | ||
| 840 | + | ```text | |
| 841 | + | g1t completion [OPTIONS] <SHELL> | |
| 842 | + | ``` | |
| 843 | + | ||
| 844 | + | | Argument or flag | | | |
| 845 | + | | --- | --- | | |
| 846 | + | | `<SHELL>` | One of `bash`, `elvish`, `fish`, `powershell`, `zsh`. | | |
| 847 | + | ||
| 848 | + | ## g1t push | |
| 849 | + | ||
| 850 | + | Push a local container image to g1t's registry, in chunks. | |
| 851 | + | ||
| 852 | + | ```text | |
| 853 | + | g1t push [OPTIONS] [IMAGE] | |
| 854 | + | ``` | |
| 855 | + | ||
| 856 | + | | Argument or flag | | | |
| 857 | + | | --- | --- | | |
| 858 | + | | `[IMAGE]` | The local image, [REGISTRY/]NAME[:TAG]. | | |
| 859 | + | | `--as <ADDRESS>` | Where to push, when the image's own name is not an address on g1t.sh. The tag defaults to latest. | | |
| 860 | + | | `--chunk-size <SIZE>` | How much of a layer each request carries: 5MB to 95MB. Default: `90MB`. | | |
| 861 | + | | `--token-stdin` | Read the g1t token from stdin. | | |
| 862 | + | | `--archive <FILE>` | Push a tarball `docker save` wrote, instead of asking docker for the image. | | |
| 863 | + | ||
| 864 | + | ```text | |
| 865 | + | The token is the first of: --token-stdin, G1T_TOKEN, the account `g1t auth login` | |
| 866 | + | signed in for the registry's host, or what `docker login g1t.sh` stored. | |
| 867 | + | ``` |
| 1 | + | # Installs the g1t CLI on Windows: | |
| 2 | + | # | |
| 3 | + | # irm https://g1t.sh/install.ps1 | iex | |
| 4 | + | # | |
| 5 | + | # It downloads the build from g1t.sh/downloads/cli, checks it against the | |
| 6 | + | # release's SHA256SUMS, puts it in %LOCALAPPDATA%\g1t\bin, and adds that to | |
| 7 | + | # your PATH. | |
| 8 | + | # | |
| 9 | + | # G1T_INSTALL_DIR where to put g1t.exe | |
| 10 | + | # G1T_VERSION a version to install, such as 0.2.0 (default: the latest) | |
| 11 | + | # | |
| 12 | + | # Docs: https://docs.g1t.sh/guides/cli/ | |
| 13 | + | $ErrorActionPreference = 'Stop' | |
| 14 | + | $ProgressPreference = 'SilentlyContinue' | |
| 15 | + | ||
| 16 | + | $base = if ($env:G1T_DOWNLOAD_URL) { $env:G1T_DOWNLOAD_URL } else { 'https://g1t.sh/downloads/cli' } | |
| 17 | + | $version = if ($env:G1T_VERSION) { $env:G1T_VERSION.TrimStart('v') } else { 'latest' } | |
| 18 | + | $dir = if ($env:G1T_INSTALL_DIR) { $env:G1T_INSTALL_DIR } else { Join-Path $env:LOCALAPPDATA 'g1t\bin' } | |
| 19 | + | ||
| 20 | + | $arch = $env:PROCESSOR_ARCHITECTURE | |
| 21 | + | if ($arch -ne 'AMD64' -and $arch -ne 'ARM64') { throw "g1t install: there is no build for $arch." } | |
| 22 | + | # Windows on ARM runs the x64 build. | |
| 23 | + | $file = 'g1t-windows-x64.exe' | |
| 24 | + | ||
| 25 | + | [Net.ServicePointManager]::SecurityProtocol = [Net.ServicePointManager]::SecurityProtocol -bor [Net.SecurityProtocolType]::Tls12 | |
| 26 | + | $tmp = Join-Path ([IO.Path]::GetTempPath()) ('g1t-' + [Guid]::NewGuid()) | |
| 27 | + | New-Item -ItemType Directory -Path $tmp | Out-Null | |
| 28 | + | try { | |
| 29 | + | Write-Host "Downloading g1t ($version, windows x64)..." | |
| 30 | + | $exe = Join-Path $tmp 'g1t.exe' | |
| 31 | + | Invoke-WebRequest -UseBasicParsing -Uri "$base/$version/$file" -OutFile $exe | |
| 32 | + | $sumsFile = Join-Path $tmp 'SHA256SUMS' | |
| 33 | + | Invoke-WebRequest -UseBasicParsing -Uri "$base/$version/SHA256SUMS" -OutFile $sumsFile | |
| 34 | + | $want = Get-Content $sumsFile | | |
| 35 | + | Where-Object { ($_ -split '\s+')[1] -eq $file } | | |
| 36 | + | ForEach-Object { ($_ -split '\s+')[0] } | | |
| 37 | + | Select-Object -First 1 | |
| 38 | + | if (-not $want) { throw "g1t install: SHA256SUMS names no $file." } | |
| 39 | + | $have = (Get-FileHash -Algorithm SHA256 -Path $exe).Hash.ToLower() | |
| 40 | + | if ($have -ne $want.ToLower()) { throw "g1t install: the download's SHA-256 is $have, not $want. Nothing was installed." } | |
| 41 | + | New-Item -ItemType Directory -Force -Path $dir | Out-Null | |
| 42 | + | Move-Item -Force -Path $exe -Destination (Join-Path $dir 'g1t.exe') | |
| 43 | + | } | |
| 44 | + | finally { | |
| 45 | + | Remove-Item -Recurse -Force -Path $tmp -ErrorAction SilentlyContinue | |
| 46 | + | } | |
| 47 | + | ||
| 48 | + | $userPath = [Environment]::GetEnvironmentVariable('Path', 'User') | |
| 49 | + | if (-not (($userPath -split ';') -contains $dir)) { | |
| 50 | + | $joined = if ($userPath) { "$userPath;$dir" } else { $dir } | |
| 51 | + | [Environment]::SetEnvironmentVariable('Path', $joined, 'User') | |
| 52 | + | $env:Path = "$env:Path;$dir" | |
| 53 | + | Write-Host "Added $dir to your PATH; terminals opened from now on have it." | |
| 54 | + | } | |
| 55 | + | $installed = & (Join-Path $dir 'g1t.exe') --version | |
| 56 | + | Write-Host "Installed $installed to $dir\g1t.exe" | |
| 57 | + | Write-Host 'Next: g1t auth login' |
| 1 | + | #!/bin/sh | |
| 2 | + | # Installs the g1t CLI on Linux or macOS: | |
| 3 | + | # | |
| 4 | + | # curl -fsSL https://g1t.sh/install | sh | |
| 5 | + | # | |
| 6 | + | # It downloads the build for this system from g1t.sh/downloads/cli, checks it | |
| 7 | + | # against the release's SHA256SUMS, and puts it in ~/.local/bin. | |
| 8 | + | # | |
| 9 | + | # G1T_INSTALL_DIR where to put g1t (default: ~/.local/bin) | |
| 10 | + | # G1T_VERSION a version to install, such as 0.2.0 (default: the latest) | |
| 11 | + | # | |
| 12 | + | # Docs: https://docs.g1t.sh/guides/cli/ | |
| 13 | + | set -eu | |
| 14 | + | ||
| 15 | + | base="${G1T_DOWNLOAD_URL:-https://g1t.sh/downloads/cli}" | |
| 16 | + | version="${G1T_VERSION:-latest}" | |
| 17 | + | version="${version#v}" | |
| 18 | + | dir="${G1T_INSTALL_DIR:-$HOME/.local/bin}" | |
| 19 | + | ||
| 20 | + | say() { printf '%s\n' "$*" >&2; } | |
| 21 | + | fail() { | |
| 22 | + | say "g1t install: $*" | |
| 23 | + | exit 1 | |
| 24 | + | } | |
| 25 | + | ||
| 26 | + | case "$(uname -s)" in | |
| 27 | + | Linux) os=linux ;; | |
| 28 | + | Darwin) os=macos ;; | |
| 29 | + | MINGW* | MSYS* | CYGWIN*) fail "on Windows, run this in PowerShell instead: irm https://g1t.sh/install.ps1 | iex" ;; | |
| 30 | + | *) fail "there is no build for $(uname -s)." ;; | |
| 31 | + | esac | |
| 32 | + | case "$(uname -m)" in | |
| 33 | + | x86_64 | amd64) arch=x64 ;; | |
| 34 | + | arm64 | aarch64) arch=arm64 ;; | |
| 35 | + | *) fail "there is no build for $(uname -m)." ;; | |
| 36 | + | esac | |
| 37 | + | # An Intel shell on Apple silicon (Rosetta) gets the native build. | |
| 38 | + | if [ "$os" = macos ] && [ "$arch" = x64 ] && [ "$(sysctl -n sysctl.proc_translated 2>/dev/null || echo 0)" = 1 ]; then | |
| 39 | + | arch=arm64 | |
| 40 | + | fi | |
| 41 | + | file="g1t-$os-$arch" | |
| 42 | + | ||
| 43 | + | if command -v curl >/dev/null 2>&1; then | |
| 44 | + | get() { curl -fsSL --retry 3 -o "$2" "$1"; } | |
| 45 | + | elif command -v wget >/dev/null 2>&1; then | |
| 46 | + | get() { wget -q -O "$2" "$1"; } | |
| 47 | + | else | |
| 48 | + | fail "this needs curl or wget." | |
| 49 | + | fi | |
| 50 | + | ||
| 51 | + | tmp="$(mktemp -d)" | |
| 52 | + | trap 'rm -rf "$tmp"' EXIT INT TERM | |
| 53 | + | ||
| 54 | + | say "Downloading g1t ($version, $os $arch)..." | |
| 55 | + | get "$base/$version/$file" "$tmp/g1t" || fail "could not download $base/$version/$file." | |
| 56 | + | get "$base/$version/SHA256SUMS" "$tmp/SHA256SUMS" || fail "could not download $base/$version/SHA256SUMS." | |
| 57 | + | ||
| 58 | + | # A name may carry sha256sum's binary-mode `*`. | |
| 59 | + | want="$(awk -v f="$file" '{ sub(/^[*]/, "", $2) } $2 == f { print $1 }' "$tmp/SHA256SUMS")" | |
| 60 | + | [ -n "$want" ] || fail "SHA256SUMS names no $file." | |
| 61 | + | if command -v sha256sum >/dev/null 2>&1; then | |
| 62 | + | have="$(sha256sum "$tmp/g1t" | awk '{ print $1 }')" | |
| 63 | + | elif command -v shasum >/dev/null 2>&1; then | |
| 64 | + | have="$(shasum -a 256 "$tmp/g1t" | awk '{ print $1 }')" | |
| 65 | + | else | |
| 66 | + | fail "this needs sha256sum or shasum to check the download." | |
| 67 | + | fi | |
| 68 | + | [ "$want" = "$have" ] || fail "the download's SHA-256 is $have, not $want. Nothing was installed." | |
| 69 | + | ||
| 70 | + | chmod +x "$tmp/g1t" | |
| 71 | + | mkdir -p "$dir" || fail "could not make $dir. Set G1T_INSTALL_DIR to a directory you can write to." | |
| 72 | + | mv "$tmp/g1t" "$dir/g1t" || fail "could not write $dir/g1t. Set G1T_INSTALL_DIR to a directory you can write to." | |
| 73 | + | ||
| 74 | + | say "Installed $("$dir/g1t" --version) to $dir/g1t" | |
| 75 | + | case ":$PATH:" in | |
| 76 | + | *":$dir:"*) ;; | |
| 77 | + | *) say "$dir is not on your PATH. Add it to your shell's profile: export PATH=\"$dir:\$PATH\"" ;; | |
| 78 | + | esac | |
| 79 | + | say "Next: g1t auth login" |
| 95 | 95 | route("download", "routes/download.tsx"), | |
| 96 | 96 | // Releases of the desktop app, the self-hosted runner and the g1t CLI, from R2. | |
| 97 | 97 | route("downloads/:tool/*", "routes/downloads-runner.ts"), | |
| 98 | + | // The g1t CLI's install scripts, for Linux and macOS and for Windows. `install` is reserved. | |
| 99 | + | route("install", "routes/install-script.ts", { id: "routes/install-sh" }), | |
| 100 | + | route("install.ps1", "routes/install-script.ts", { id: "routes/install-ps1" }), | |
| 98 | 101 | // A workspace's own pages sit under `-`, which no repository can be named. | |
| 99 | 102 | route(":owner", "routes/workspace/layout.tsx", [ | |
| 100 | 103 | index("routes/workspace/overview.tsx"), |
| 1 | + | /** | |
| 2 | + | * The g1t CLI's install scripts: g1t.sh/install for Linux and macOS | |
| 3 | + | * (`curl -fsSL https://g1t.sh/install | sh`) and g1t.sh/install.ps1 for | |
| 4 | + | * Windows (`irm https://g1t.sh/install.ps1 | iex`). Each downloads the newest | |
| 5 | + | * release from g1t.sh/downloads/cli/ (scripts/cli-release.mjs), checks it | |
| 6 | + | * against the release's SHA256SUMS, and installs it. `install` is a | |
| 7 | + | * reserved name. | |
| 8 | + | */ | |
| 9 | + | import type { Route } from "./+types/install-script"; | |
| 10 | + | import sh from "../content/install/install.sh?raw"; | |
| 11 | + | import ps1 from "../content/install/install.ps1?raw"; | |
| 12 | + | ||
| 13 | + | export function loader({ request }: Route.LoaderArgs) { | |
| 14 | + | const windows = new URL(request.url).pathname.endsWith(".ps1"); | |
| 15 | + | return new Response(windows ? ps1 : sh, { | |
| 16 | + | headers: { | |
| 17 | + | "content-type": "text/plain; charset=utf-8", | |
| 18 | + | "cache-control": "public, max-age=300", | |
| 19 | + | "x-content-type-options": "nosniff", | |
| 20 | + | }, | |
| 21 | + | }); | |
| 22 | + | } |
| 1 | 1 | [package] | |
| 2 | 2 | name = "g1t" | |
| 3 | − | version = "0.1.0" | |
| 3 | + | version = "0.2.0" | |
| 4 | 4 | edition.workspace = true | |
| 5 | 5 | license.workspace = true | |
| 6 | 6 | repository.workspace = true | |
| 7 | − | description = "The g1t command line: g1t push sends a local image to g1t.sh in chunks, so a layer can be any size." | |
| 7 | + | description = "The g1t command line: repositories, issues, pull requests, workflow runs, deployments, secrets and logs on g1t, from a terminal or an agent's shell." | |
| 8 | + | ||
| 9 | + | [[bin]] | |
| 10 | + | name = "g1t" | |
| 11 | + | path = "src/main.rs" | |
| 8 | 12 | ||
| 9 | 13 | [dependencies] | |
| 14 | + | anstyle-query = "1.1" | |
| 10 | 15 | base64 = "0.22" | |
| 16 | + | clap = { version = "4.6", features = ["derive", "env", "wrap_help"] } | |
| 17 | + | clap_complete = "4.6" | |
| 11 | 18 | flate2 = "1" | |
| 12 | 19 | hex = "0.4" | |
| 20 | + | jaq-core = "3.1" | |
| 21 | + | jaq-json = "2.0" | |
| 22 | + | jaq-std = "3.0" | |
| 23 | + | keyring = "4.2" | |
| 24 | + | rpassword = "7" | |
| 25 | + | serde = { workspace = true } | |
| 13 | 26 | serde_json = { workspace = true } | |
| 14 | 27 | sha2 = "0.10" | |
| 15 | 28 | tar = { version = "0.4", default-features = false } | |
| 29 | + | terminal_size = "0.4" | |
| 16 | 30 | ureq = { version = "2", default-features = false, features = ["tls"] } | |
| 31 | + |
Loading the diff…
Loading the diff…
Loading the diff…
Loading the diff…
Loading the diff…
Loading the diff…
Loading the diff…
Loading the diff…
Loading the diff…
Loading the diff…
Loading the diff…
Loading the diff…
Loading the diff…
Loading the diff…
Loading the diff…
Loading the diff…
Loading the diff…
Loading the diff…
Loading the diff…
Loading the diff…
Loading the diff…
Loading the diff…
Loading the diff…
Loading the diff…
Loading the diff…
Loading the diff…
Loading the diff…
A large diff (6,912 lines) is not shown until you ask for it.
Loading the diff…
Loading the diff…
Loading the diff…
Loading the diff…
Loading the diff…
Loading the diff…
Loading the diff…
Loading the diff…
Loading the diff…