- **switch tea to the Cobra command tree:** `internal/app` wires the packages from parts 1–4 into explicit noun/verb commands with `--repo`, `--json` / `--jq`, `--sudo` and `--debug`; `main.go` points at it. Build, release and docs tooling (`tools/cli-docs`, Makefile, goreleaser, snap, CI) and README / CONTRIBUTING are updated. - **remove the urfave/cli command tree:** deletes `cmd/`, `modules/`, the old integration tests, contrib completion scripts and the generated `docs/CLI.md`, and drops their dependencies. This commit only deletes. ## Breaking changes This is a breaking release. It requires Gitea 28 or newer; configuration moves to separate `config.yml` and `hosts.yml` files and requires fresh authentication, and command names, aliases, flags and output formats change. `docs/migration-1.0.md` maps every old command, flag and environment variable to its replacement. ## Issues fixes #1118 fixes #1116 fixes #1115 fixes #1094 fixes #1091 fixes #1073 fixes #1052 fixes #1032 fixes #1023 fixes #966 fixes #908 fixes #833 fixes #831 fixes #817 fixes #804 fixes #779 fixes #770 fixes #737 fixes #697 fixes #726 fixes #677 fixes #672 fixes #633 fixes #632 fixes #560 fixes #556 fixes #523 fixes #516 fixes #510 fixes #504 fixes #500 fixes #482 fixes #406 fixes #403 fixes #373 fixes #351 fixes #344 fixes #326 fixes #325 fixes #323 fixes #246 fixes #240 fixes #232 fixes #197 fixes #172 fixes #141 fixes #69 fixes #1110 fixes #569 fixes #480 fixes #666 fixes #670 fixes #457 fixes #643 fixes #498 fixes #490 fixes #1069 fixes #834 fixes #602 fixes #328 fixes #417 fixes #571 fixes #1029 fixes #489 fixes #1050 fixes #162 fixes #430 fixes #1087 fixes #683 Reviewed-on: https://gitea.com/gitea/tea/pulls/1126 Reviewed-by: TheFox0x7 <95654+thefox0x7@noreply.gitea.com>
18 KiB
Migrating to tea 1.0
tea 1.0 rebuilds the CLI around explicit, singular noun verb commands (similar
to GitHub's gh), a split configuration, and per-instance accounts. There are no
compatibility aliases: old command names, plural groups and most short flags are
gone, and scripts need updating. This guide lists what changed and what to use
instead.
Quick checklist:
- Make sure your instances run Gitea 28 or newer (Server requirements).
- Move the old configuration away, or point tea 1.0 at a new directory (Configuration).
- Log in again (Logging in).
- Replace the old
!tea login helperGit credential entries (Git credential helper). - Regenerate shell completions (Shell completion).
- Update scripts: global flags, commands, arguments and output.
Run tea <command> --help for the full flag list of any command.
Server requirements
Requires Gitea 28 or newer. tea no longer probes /api/v1/version or
/swagger.v1.json to adapt to older servers: on an older instance, commands
that need a newer endpoint fail with the server's HTTP error instead of a
"not supported" message.
Configuration and login
Old configuration file
Older releases kept logins and preferences in one file, config.yml in the tea
directory under the platform configuration directory (~/.config/tea/config.yml
on Linux; very old releases used ~/.tea/tea.yml). tea 1.0 stores preferences in
config.yml and instances and accounts in hosts.yml, in the same directory by
default; tea config path prints both paths. When it finds an old-format file it
stops with:
legacy tea configuration: archive the old config.yml or select a separate TEA_CONFIG_DIR, then run tea auth login; existing files have not been changed
Nothing is imported automatically. Either archive the old file:
mv ~/.config/tea/config.yml ~/.config/tea/config.yml.old # adjust the path on macOS and Windows
or keep it and give tea 1.0 its own directory with TEA_CONFIG_DIR. Do not run
an old tea against a directory written by tea 1.0: it reads the new config.yml
as an empty login list and overwrites it on its next save.
tea config list shows effective preferences. Old settings map as follows:
Old config.yml |
tea 1.0 |
|---|---|
preferences.editor: true |
tea config set editor "<command>" (a command, not a switch) |
preferences.flag_defaults.remote |
tea config set remote <name> |
login default: true |
tea config set default_host <url> |
login insecure, ssh_host |
tea config set --host <url> insecure true, ... ssh_host <host[:port]> |
login ssh_key, ssh_agent, ssh_certificate_principal, ssh_key_agent_pub |
tea config set --host <url> --user <name> ssh_key … (also ssh_agent, ssh_certificate_principal, ssh_key_fingerprint) |
Logging in again
Accounts are identified by instance URL and username instead of a login name.
tea auth login --host <url> replaces tea login add:
| Old | tea 1.0 |
|---|---|
tea login add --url URL --token TOKEN |
tea auth login --host URL --with-token < token-file (the token is read from stdin) |
tea login add --oauth |
tea auth login --host URL --oauth |
tea login add --ssh-key PATH / -s |
tea auth login --host URL --ssh-key PATH |
--ssh-agent-key / -a, --ssh-agent-principal / -c |
same long flags, no shorthands |
--insecure / -i |
--insecure |
--user, --password, --otp, --scopes (create a token with basic auth) |
removed: create a token in the web UI (Settings → Applications) or use --oauth |
--name, --no-version-check |
removed |
--redirect-url |
removed: OAuth always listens on a random loopback port |
--git-credentials / --helper / -j |
tea auth setup-git --host URL |
Token logins of the old release kept the token in plain text under
logins[].token in the old config.yml, so you can pipe it straight into
tea auth login --with-token instead of creating a new one.
Credentials go to the operating-system keyring (service tea-cli-v2). Pass
--credential-store file to store them in private files under the configuration
directory instead. The old release's OAuth tokens (keyring service tea-cli, and
credentials.json in the old configuration directory) are not read; delete them once you
have logged in again.
Managing accounts:
| Old | tea 1.0 |
|---|---|
tea login list, tea login status, tea whoami |
tea auth status (--verify checks each credential) |
tea login default NAME |
tea config set default_host URL, and tea auth switch USER --host URL for the active account |
tea login edit |
tea config set --host URL <key> <value> |
tea login delete NAME, tea logout NAME |
tea auth logout --host URL [--user USER] |
tea login oauth-refresh |
tea auth refresh |
Environment variables
| Variable | tea 1.0 |
|---|---|
GITEA_TOKEN, GITEA_INSTANCE_URL |
supported; TEA_HOST is an alternative to GITEA_INSTANCE_URL |
GITEA_INSTANCE_INSECURE, GITEA_INSTANCE_SSH_HOST |
supported |
GH_TOKEN |
no longer read: use GITEA_TOKEN |
GITEA_SERVER_URL, GITEA_SERVER_TOKEN, GITEA_SERVER_USER, GITEA_SERVER_PASSWORD, GITEA_SERVER_OTP, GITEA_SCOPES |
removed with tea login add |
New variables: TEA_CONFIG_DIR, TEA_HOST, TEA_USER, TEA_REPO, TEA_EDITOR,
TEA_PAGER and TEA_COLOR; see tea config --help. Environment credentials are
never written to disk.
Git credential helper
tea login helper setup and tea login add --git-credentials wrote two entries
to ~/.gitconfig for each instance: an empty credential.<url>.helper and
!tea login helper. tea 1.0 has no login command, so Git now gets an error
from that helper and falls back to prompting. Remove both entries, then register
the new helper:
git config --global --get-all credential.https://gitea.example.org.helper
git config --global --unset-all credential.https://gitea.example.org.helper '^!tea login helper$'
git config --global --unset-all credential.https://gitea.example.org.helper '^$'
tea auth setup-git --host https://gitea.example.org
tea repo clone, tea pr checkout, tea pr clean, tea repo sync and
tea pr create --agit authenticate Git without any helper; tea auth setup-git
is only needed for plain git commands. Add --local to configure only the
current repository.
Global flags
| Old | tea 1.0 |
|---|---|
--repo / -r |
--repo / -R |
--remote / -R |
--remote (no shorthand) |
--login / -l |
--host URL, plus --user NAME when the instance has several accounts |
--output / -o, --fields / -f |
--json [fields] and --jq <expression> |
--debug / --vvv |
--debug |
--confirm / -y, --force / -f on destructive commands |
--yes |
-R now means --repo: tea issue list -R origin fails with
invalid repository URL instead of selecting the origin remote. Use
--remote origin.
New global flags: --no-input disables prompts, editors and browsers, --yes
accepts confirmations, --cwd selects the directory used for repository
discovery, and --sudo USER acts as another user (administrators only).
Renamed commands
All command groups are singular, and the built-in aliases (ls, rm, c, e,
i, ms, co, lgtm, …) are gone. tea alias set NAME EXPANSION defines your
own top-level shortcuts, for example tea alias set co 'pr checkout'; aliases
for subcommands such as issue ls are not possible.
Top-level groups:
| Old | tea 1.0 |
|---|---|
issues, issue, i |
issue |
pulls, pull, pr |
pr |
labels |
label |
milestones, ms |
milestone |
releases, r |
release |
times, t |
time |
organizations, org |
org |
repos |
repo |
branches, b |
branch |
actions secrets |
secret |
actions variables |
variable |
actions runs |
run |
actions workflows |
workflow |
webhooks, hooks |
webhook |
comments, c |
issue comment / pr comment |
notifications, n |
notification |
ssh-keys |
ssh-key |
admin users, admin u |
admin user |
logins, login, logout, whoami |
auth (see Logging in) |
clone, C |
repo clone |
open, o |
removed (see Removed features) |
Groups no longer run a default action: tea issues listed issues and
tea issues 5 showed issue 5; use tea issue list and tea issue view 5.
The same applies to pulls, notifications and the other groups.
Subcommands:
| Old | tea 1.0 |
|---|---|
issues reopen, pulls reopen (alias open) |
issue reopen, pr reopen |
pulls approve <n> [comment] |
pr review <n> --event APPROVED [--body TEXT] |
pulls reject <n> <comment> |
pr review <n> --event REQUEST_CHANGES --body TEXT |
pulls review <n> |
pr review <n> |
pulls review-comments |
pr review comments |
pulls reply, resolve, unresolve |
pr review reply, pr review resolve, pr review unresolve |
labels update --id ID |
label edit ID |
labels delete --id ID |
label delete ID |
labels list --save |
label export |
milestones issues <name> |
milestone issue list <milestone-id>, or milestone issue list --by-name <name> |
milestones issues add|remove |
milestone issue add|remove <milestone-id> <number>... (--by-name selects by title) |
releases assets create |
release asset upload |
times add |
time create |
times list [user|#issue] |
time list [--username USER|--issue N] |
repos search |
search repo |
repos create-from-template |
repo create --template OWNER/REPO |
actions secrets create |
secret set |
actions variables list --name NAME |
variable view NAME |
actions runs delete (alias cancel) |
run delete; run cancel cancels without deleting |
actions workflows dispatch |
workflow run |
webhooks update |
webhook edit |
comments add <n> [body] |
issue comment create <n> --body TEXT (also pr comment create) |
notifications read|unread [all|id] |
notification mark-read|mark-unread [id]...; use --all for every filtered notification |
ssh-keys add |
ssh-key create |
login helper setup |
auth setup-git |
completion pwsh |
completion powershell |
Renamed flags that appear on many commands:
| Old | tea 1.0 |
|---|---|
--description / -d, --description-file (issues, pulls, comments) |
--body, --body-file |
--note / -n, --note-file / -f (releases) |
--body, --body-file |
--content / -c (wiki) |
--body, --body-file |
--labels / -L, --assignees / -a, --milestones / -m |
--label, --assignee, --milestone |
--referenced-version / -v |
--ref |
--keyword / -k |
--search |
--from / -F (issue list) |
--since |
--states / -s, --types / -t (notifications) |
--status, --type |
--page / -p, --limit / --lm |
--page, --limit |
--style / -s (pr merge) |
--method / -s |
--owner / -O, --init, --labels, --trustmodel, --branch, --template (repo create) |
--org, --auto-init, --label-template, --trust-model, --default-branch, --as-template |
--inactive (webhook) |
--active=false |
--out (man) |
--output-file / -o |
Most other short flags were dropped; the long names are unchanged unless listed here. Two flags kept their name but changed meaning:
workflow run:-fwas--followand now means--field KEY=VALUE;--followhas no shorthand.-r(--ref) and-i(--input) are unchanged.api:--field(-f) sent a string and--Field(-F) a typed value. Now--raw-field/-fsends a string and--field/-Fa typed value, so the shorthands behave as before.--data/-dbecame--input FILE(or-for stdin),--includelost-i, and--output/-obecame--output-file.
Changed positional arguments
| Command | Old | tea 1.0 |
|---|---|---|
milestone close|reopen|delete|edit|view |
milestone name | milestone ID; add --by-name to select by exact title |
milestone issue list|add|remove |
milestone name | milestone ID; add --by-name to select by exact title |
release asset delete <tag> |
attachment name | asset ID; add --by-name to select by exact name |
label edit|delete |
--id ID |
ID |
repo delete |
--name NAME --owner OWNER |
optional OWNER/REPO argument (or --repo) |
issue comment create |
optional body argument | --body, --body-file or --editor |
A milestone whose title is a number is now read as an ID unless you pass
--by-name. Destructive commands still ask for confirmation unless --yes is
given.
Output formats
--output / -o (table, simple, csv, tsv, yaml, json) and --fields
are gone. Human output is plain text; scripts should use JSON:
# old: tea issues list --fields index,title -o csv
tea issue list --json number,title --jq '.[] | "\(.number),\(.title)"'
# old: tea notifications --mine -o simple | xargs notify-send
tea notification list --mine --json title --jq '.[].title' | xargs -n1 notify-send
--json alone prints every field; --json a,b selects fields and rejects unknown
names; --jq filters the result. Commands that produce no resource, such as
deletes, reject --json with a usage error instead of printing nothing.
Lists print aligned columns without a header row and with fewer columns than
before: the ID or number first, then the title or name, then the state and a few
details (issue list and pr list show number, title, state and author). Do not
parse them; the columns may change. On a color terminal the first column links to
the resource. Tabs and line breaks in list cells become spaces, and control
characters such as escape sequences are dropped from all human output, bodies
included. Commands that change several resources at once, such as
issue close 1 2, issue edit, milestone close, release edit or
notification mark-read, print one table of the changed items in the matching
list's columns. When a list continues past the requested page, tea prints a
--page hint on stderr.
Issue, pull request and other bodies are printed as raw Markdown instead of being
rendered. Long output on a terminal goes through a pager (TEA_PAGER, the
pager preference or PAGER). Each command starts the pager at most once.
Removed features
| Feature | Replacement |
|---|---|
tea open [number|issues|pulls|releases|commits|branches|wiki|labels|milestones|activity|settings|<ref>] |
tea issue view N --web, tea pr view N --web, tea repo view --web; for other pages open $(tea repo view --json url --jq .url)/releases and similar |
Basic-auth token creation (login add --user/--password/--otp/--scopes) |
create a token in the web UI, or tea auth login --oauth |
login edit |
tea config set --host URL <key> <value> |
Output formats and --fields |
--json and --jq |
| Markdown rendering of bodies | raw Markdown, optionally paged |
contrib/autocomplete.* scripts and the --generate-shell-completion protocol |
tea completion <shell> |
GH_TOKEN, GITEA_SERVER_*, GITEA_SCOPES |
GITEA_TOKEN, tea auth login |
--vvv |
--debug |
Shell completion
Completion scripts saved from an older tea completion (or the removed
contrib/autocomplete.* files) call tea with --generate-shell-completion, which
tea 1.0 rejects, so completion silently stops working. Regenerate them:
source <(tea completion bash) # ~/.bashrc
source <(tea completion zsh) # ~/.zshrc
tea completion fish > ~/.config/fish/completions/tea.fish
tea completion powershell | Out-String | Invoke-Expression # PowerShell profile
Packagers can ship the pre-generated scripts and man pages from the release docs
archive, or run make docs.
Behavior changes
pr checkout Ncreates or reuses the local branchpr/N; it no longer switches to another local branch that already points at the PR head. Use--branch NAMEto check out into a branch you choose (it must point at the PR head;--updatefast-forwards it) or--detachfor a detached checkout.-bnow takes the branch name.webhook editmust be told what to do with the delivery authorization header on every call, because Gitea replaces it: pass--authorization-header,--authorization-header-fileor--clear-authorization. The signing secret cannot be edited; recreate the hook to rotate it.notification mark-read,mark-unread,pinandunpinact on the given IDs; pass--allto apply them to every notification matching the filters.--no-inputdisables prompts, editors and browsers. With--json, tea never prompts unless--interactiveis given; required values must come from flags.- Destructive commands confirm on a terminal and need
--yeselsewhere. --limitaccepts 1 to 100 and--pagea positive number; other values are usage errors instead of being passed to the server.- In
--jsonoutput, timestamps the server leaves unset print as"", or asnullfor optional fields such as deadlines, instead of0001-01-01T00:00:00Z. - More input is checked before anything is sent: release titles, issue titles
and comment bodies cannot be empty, a review needs a body or inline comments
(unless it approves), team creation needs a permission, migrations from
GitHub, Gitea, GitLab and Gogs need an access token, and
workflow runneeds a ref (--refor a checked-out branch). pr mergemerges the head it read and refuses when the branch moved in the meantime; run it again to merge the new head.- Preferences follow the git/gh order: an explicit
tea config setvalue wins overVISUAL/EDITOR,PAGERandBROWSER, which win over the defaults;TEA_EDITOR,TEA_PAGERandTEA_COLORoverride both.