Merge branch 'cli:trunk' into trunk

This commit is contained in:
Zack Sloane 2023-12-05 22:23:09 -05:00 committed by GitHub
commit 4fb6b2d66c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
54 changed files with 374 additions and 333 deletions

View file

@ -1,32 +0,0 @@
name: Discussion Triage
run-name: ${{ github.event.issue.title }}
on:
issues:
types:
- labeled
jobs:
create-discussion:
if: github.event.label.name == 'discuss'
runs-on: ubuntu-latest
steps:
- name: Create a discussion in github/cli
run: |
export DISCUSSION_TITLE="Triage: ${ISSUE_TITLE} (#${ISSUE_NUMBER})"
gh api graphql -f query='
mutation($repositoryId: ID!, $categoryId: ID!, $title: String!, $body: String!) {
createDiscussion(
input: {repositoryId: $repositoryId, categoryId: $categoryId, title: $title, body: $body}
) {
discussion {
id
}
}
}' -f repositoryId="${GITHUB_CLI_REPOSITORY_ID}" -f categoryId="${TRIAGE_CATEGORY_ID}" -f title="${DISCUSSION_TITLE}" -f body="@${LABELLER} added the discuss label to https://github.com/cli/cli/issues/${ISSUE_NUMBER}"
env:
GITHUB_TOKEN: ${{ secrets.CLI_DISCUSSION_TRIAGE_TOKEN }}
ISSUE_TITLE: ${{ github.event.issue.title }}
ISSUE_NUMBER: ${{ github.event.issue.number }}
LABELLER: ${{ github.event.sender.login }}
GITHUB_CLI_REPOSITORY_ID: "R_kgDODAqwpw"
TRIAGE_CATEGORY_ID: "DIC_kwDODAqwp84CajJa"

67
.github/workflows/triage.yml vendored Normal file
View file

@ -0,0 +1,67 @@
name: Discussion Triage
run-name: ${{ github.event_name == 'issues' && github.event.issue.title || github.event.pull_request.title }}
on:
issues:
types:
- labeled
pull_request_target:
types:
- labeled
env:
TARGET_REPO: github/cli
jobs:
issue:
runs-on: ubuntu-latest
if: github.event_name == 'issues' && github.event.action == 'labeled' && github.event.label.name == 'discuss'
steps:
- name: Create issue based on source issue
env:
BODY: ${{ github.event.issue.body }}
CREATED: ${{ github.event.issue.created_at }}
GH_TOKEN: ${{ secrets.CLI_DISCUSSION_TRIAGE_TOKEN }}
LINK: ${{ github.repository }}#${{ github.event.issue.number }}
TITLE: ${{ github.event.issue.title }}
TRIGGERED_BY: ${{ github.triggering_actor }}
run: |
# Markdown quote source body by replacing newlines for newlines and markdown quoting
BODY="${BODY//$'\n'/$'\n'> }"
# Create issue using dynamically constructed body within heredoc
cat << EOF | gh issue create --title "Triage issue \"$TITLE\"" --body-file - --repo "$TARGET_REPO" --label triage
**Title:** $TITLE
**Issue:** $LINK
**Created:** $CREATED
**Triggered by:** @$TRIGGERED_BY
---
> $BODY
EOF
pull_request:
runs-on: ubuntu-latest
if: github.event_name == 'pull_request_target' && github.event.action == 'labeled' && github.event.label.name == 'discuss'
steps:
- name: Create issue based on source pull request
env:
BODY: ${{ github.event.pull_request.body }}
CREATED: ${{ github.event.pull_request.created_at }}
GH_TOKEN: ${{ secrets.CLI_DISCUSSION_TRIAGE_TOKEN }}
LINK: ${{ github.repository }}#${{ github.event.pull_request.number }}
TITLE: ${{ github.event.pull_request.title }}
TRIGGERED_BY: ${{ github.triggering_actor }}
run: |
# Markdown quote source body by replacing newlines for newlines and markdown quoting
BODY="${BODY//$'\n'/$'\n'> }"
# Create issue using dynamically constructed body within heredoc
cat << EOF | gh issue create --title "Triage PR \"$TITLE\"" --body-file - --repo "$TARGET_REPO" --label triage
**Title:** $TITLE
**Pull request:** $LINK
**Created:** $CREATED
**Triggered by:** @$TRIGGERED_BY
---
> $BODY
EOF

View file

@ -472,6 +472,39 @@ func (c *Client) SetRemoteBranches(ctx context.Context, remote string, refspec s
return nil
}
func (c *Client) AddRemote(ctx context.Context, name, urlStr string, trackingBranches []string) (*Remote, error) {
args := []string{"remote", "add"}
for _, branch := range trackingBranches {
args = append(args, "-t", branch)
}
args = append(args, name, urlStr)
cmd, err := c.Command(ctx, args...)
if err != nil {
return nil, err
}
if _, err := cmd.Output(); err != nil {
return nil, err
}
var urlParsed *url.URL
if strings.HasPrefix(urlStr, "https") {
urlParsed, err = url.Parse(urlStr)
if err != nil {
return nil, err
}
} else {
urlParsed, err = ParseURL(urlStr)
if err != nil {
return nil, err
}
}
remote := &Remote{
Name: name,
FetchURL: urlParsed,
PushURL: urlParsed,
}
return remote, nil
}
// Below are commands that make network calls and need authentication credentials supplied from gh.
func (c *Client) Fetch(ctx context.Context, remote string, refspec string, mods ...CommandModifier) error {
@ -541,42 +574,6 @@ func (c *Client) Clone(ctx context.Context, cloneURL string, args []string, mods
return target, nil
}
func (c *Client) AddRemote(ctx context.Context, name, urlStr string, trackingBranches []string, mods ...CommandModifier) (*Remote, error) {
args := []string{"remote", "add"}
for _, branch := range trackingBranches {
args = append(args, "-t", branch)
}
args = append(args, name, urlStr)
cmd, err := c.Command(ctx, args...)
if err != nil {
return nil, err
}
for _, mod := range mods {
mod(cmd)
}
if _, err := cmd.Output(); err != nil {
return nil, err
}
var urlParsed *url.URL
if strings.HasPrefix(urlStr, "https") {
urlParsed, err = url.Parse(urlStr)
if err != nil {
return nil, err
}
} else {
urlParsed, err = ParseURL(urlStr)
if err != nil {
return nil, err
}
}
remote := &Remote{
Name: name,
FetchURL: urlParsed,
PushURL: urlParsed,
}
return remote, nil
}
func resolveGitPath() (string, error) {
path, err := safeexec.LookPath("git")
if err != nil {

View file

@ -26,36 +26,36 @@ func actionsExplainer(cs *iostreams.ColorScheme) string {
header := cs.Bold("Welcome to GitHub Actions on the command line.")
runHeader := cs.Bold("Interacting with workflow runs")
workflowHeader := cs.Bold("Interacting with workflow files")
cacheHeader := cs.Bold("Interacting with the Actions cache")
cacheHeader := cs.Bold("Interacting with the GitHub Actions cache")
return heredoc.Docf(`
%s
%[2]s
GitHub CLI integrates with Actions to help you manage runs and workflows.
GitHub CLI integrates with GitHub Actions to help you manage runs and workflows.
%s
%[3]s
gh run list: List recent workflow runs
gh run view: View details for a workflow run or one of its jobs
gh run watch: Watch a workflow run while it executes
gh run rerun: Rerun a failed workflow run
gh run download: Download artifacts generated by runs
To see more help, run 'gh help run <subcommand>'
To see more help, run %[1]sgh help run <subcommand>%[1]s
%s
%[4]s
gh workflow list: List workflow files in your repository
gh workflow view: View details for a workflow file
gh workflow enable: Enable a workflow file
gh workflow disable: Disable a workflow file
gh workflow run: Trigger a workflow_dispatch run for a workflow file
To see more help, run 'gh help workflow <subcommand>'
To see more help, run %[1]sgh help workflow <subcommand>%[1]s
%s
gh cache list: List all the caches saved in Actions for a repository
gh cache delete: Delete one or all saved caches in Actions for a repository
%[5]s
gh cache list: List all the caches saved in GitHub Actions for a repository
gh cache delete: Delete one or all saved caches in GitHub Actions for a repository
To see more help, run 'gh help cache <subcommand>'
To see more help, run %[1]sgh help cache <subcommand>%[1]s
`, header, runHeader, workflowHeader, cacheHeader)
`, "`", header, runHeader, workflowHeader, cacheHeader)
}

View file

@ -14,11 +14,11 @@ func NewCmdAlias(f *cmdutil.Factory) *cobra.Command {
cmd := &cobra.Command{
Use: "alias <command>",
Short: "Create command shortcuts",
Long: heredoc.Doc(`
Long: heredoc.Docf(`
Aliases can be used to make shortcuts for gh commands or to compose multiple commands.
Run "gh help alias set" to learn more.
`),
Run %[1]sgh help alias set%[1]s to learn more.
`, "`"),
}
cmdutil.DisableAuthCheck(cmd)

View file

@ -34,7 +34,7 @@ func NewCmdImport(f *cmdutil.Factory, runF func(*ImportOptions) error) *cobra.Co
cmd := &cobra.Command{
Use: "import [<filename> | -]",
Short: "Import aliases from a YAML file",
Long: heredoc.Doc(`
Long: heredoc.Docf(`
Import aliases from the contents of a YAML file.
Aliases should be defined as a map in YAML, where the keys represent aliases and
@ -47,12 +47,12 @@ func NewCmdImport(f *cmdutil.Factory, runF func(*ImportOptions) error) *cobra.Co
issue list
--label=enhancement
Use "-" to read aliases (in YAML format) from standard input.
Use %[1]s-%[1]s to read aliases (in YAML format) from standard input.
The output from the gh command "alias list" can be used to produce a YAML file
The output from %[1]sgh alias list%[1]s can be used to produce a YAML file
containing your aliases, which you can use to import them from one machine to
another. Run "gh help alias list" to learn more.
`),
another. Run %[1]sgh help alias list%[1]s to learn more.
`, "`"),
Example: heredoc.Doc(`
# Import aliases from a file
$ gh alias import aliases.yml

View file

@ -35,21 +35,21 @@ func NewCmdSet(f *cmdutil.Factory, runF func(*SetOptions) error) *cobra.Command
cmd := &cobra.Command{
Use: "set <alias> <expansion>",
Short: "Create a shortcut for a gh command",
Long: heredoc.Doc(`
Long: heredoc.Docf(`
Define a word that will expand to a full gh command when invoked.
The expansion may specify additional arguments and flags. If the expansion includes
positional placeholders such as "$1", extra arguments that follow the alias will be
positional placeholders such as %[1]s$1%[1]s, extra arguments that follow the alias will be
inserted appropriately. Otherwise, extra arguments will be appended to the expanded
command.
Use "-" as expansion argument to read the expansion string from standard input. This
Use %[1]s-%[1]s as expansion argument to read the expansion string from standard input. This
is useful to avoid quoting issues when defining expansions.
If the expansion starts with "!" or if "--shell" was given, the expansion is a shell
expression that will be evaluated through the "sh" interpreter when the alias is
If the expansion starts with %[1]s!%[1]s or if %[1]s--shell%[1]s was given, the expansion is a shell
expression that will be evaluated through the %[1]ssh%[1]s interpreter when the alias is
invoked. This allows for chaining multiple commands via piping and redirection.
`),
`, "`"),
Example: heredoc.Doc(`
# note: Command Prompt on Windows requires using double quotes for arguments
$ gh alias set pv 'pr view'

View file

@ -71,43 +71,43 @@ func NewCmdApi(f *cmdutil.Factory, runF func(*ApiOptions) error) *cobra.Command
Makes an authenticated HTTP request to the GitHub API and prints the response.
The endpoint argument should either be a path of a GitHub API v3 endpoint, or
"graphql" to access the GitHub API v4.
%[1]sgraphql%[1]s to access the GitHub API v4.
Placeholder values "{owner}", "{repo}", and "{branch}" in the endpoint
Placeholder values %[1]s{owner}%[1]s, %[1]s{repo}%[1]s, and %[1]s{branch}%[1]s in the endpoint
argument will get replaced with values from the repository of the current
directory or the repository specified in the GH_REPO environment variable.
directory or the repository specified in the %[1]sGH_REPO%[1]s environment variable.
Note that in some shells, for example PowerShell, you may need to enclose
any value that contains "{...}" in quotes to prevent the shell from
any value that contains %[1]s{...}%[1]s in quotes to prevent the shell from
applying special meaning to curly braces.
The default HTTP request method is "GET" normally and "POST" if any parameters
The default HTTP request method is %[1]sGET%[1]s normally and %[1]sPOST%[1]s if any parameters
were added. Override the method with %[1]s--method%[1]s.
Pass one or more %[1]s-f/--raw-field%[1]s values in "key=value" format to add static string
Pass one or more %[1]s-f/--raw-field%[1]s values in %[1]skey=value%[1]s format to add static string
parameters to the request payload. To add non-string or placeholder-determined values, see
%[1]s--field%[1]s below. Note that adding request parameters will automatically switch the
request method to POST. To send the parameters as a GET query string instead, use
%[1]s-F/--field%[1]s below. Note that adding request parameters will automatically switch the
request method to %[1]sPOST%[1]s. To send the parameters as a %[1]sGET%[1]s query string instead, use
%[1]s--method GET%[1]s.
The %[1]s-F/--field%[1]s flag has magic type conversion based on the format of the value:
- literal values "true", "false", "null", and integer numbers get converted to
- literal values %[1]strue%[1]s, %[1]sfalse%[1]s, %[1]snull%[1]s, and integer numbers get converted to
appropriate JSON types;
- placeholder values "{owner}", "{repo}", and "{branch}" get populated with values
- placeholder values %[1]s{owner}%[1]s, %[1]s{repo}%[1]s, and %[1]s{branch}%[1]s get populated with values
from the repository of the current directory;
- if the value starts with "@", the rest of the value is interpreted as a
filename to read the value from. Pass "-" to read from standard input.
- if the value starts with %[1]s@%[1]s, the rest of the value is interpreted as a
filename to read the value from. Pass %[1]s-%[1]s to read from standard input.
For GraphQL requests, all fields other than "query" and "operationName" are
For GraphQL requests, all fields other than %[1]squery%[1]s and %[1]soperationName%[1]s are
interpreted as GraphQL variables.
To pass nested parameters in the request payload, use "key[subkey]=value" syntax when
To pass nested parameters in the request payload, use %[1]skey[subkey]=value%[1]s syntax when
declaring fields. To pass nested values as arrays, declare multiple fields with the
syntax "key[]=value1", "key[]=value2". To pass an empty array, use "key[]" without a
syntax %[1]skey[]=value1%[1]s, %[1]skey[]=value2%[1]s. To pass an empty array, use %[1]skey[]%[1]s without a
value.
To pass pre-constructed JSON or payloads in other formats, a request body may be read
from file specified by %[1]s--input%[1]s. Use "-" to read from standard input. When passing the
from file specified by %[1]s--input%[1]s. Use %[1]s-%[1]s to read from standard input. When passing the
request body this way, any parameters specified via field flags are added to the query
string of the endpoint URL.

View file

@ -63,13 +63,13 @@ func NewCmdLogin(f *cmdutil.Factory, runF func(*LoginOptions) error) *cobra.Comm
See %[1]sgh auth status%[1]s for its stored location.
Alternatively, use %[1]s--with-token%[1]s to pass in a token on standard input.
The minimum required scopes for the token are: "repo", "read:org".
The minimum required scopes for the token are: %[1]srepo%[1]s, %[1]sread:org%[1]s, and %[1]sgist%[1]s.
Alternatively, gh will use the authentication token found in environment variables.
This method is most suitable for "headless" use of gh such as in automation. See
%[1]sgh help environment%[1]s for more info.
To use gh in GitHub Actions, add %[1]sGH_TOKEN: ${{ github.token }}%[1]s to "env".
To use gh in GitHub Actions, add %[1]sGH_TOKEN: ${{ github.token }}%[1]s to %[1]senv%[1]s.
`, "`"),
Example: heredoc.Doc(`
# start interactive setup

View file

@ -33,11 +33,11 @@ func NewCmdLogout(f *cmdutil.Factory, runF func(*LogoutOptions) error) *cobra.Co
Use: "logout",
Args: cobra.ExactArgs(0),
Short: "Log out of a GitHub host",
Long: heredoc.Doc(`Remove authentication for a GitHub host.
Long: heredoc.Docf(`Remove authentication for a GitHub host.
This command removes the authentication configuration for a host either specified
interactively or via --hostname.
`),
interactively or via %[1]s--hostname%[1]s.
`, "`"),
Example: heredoc.Doc(`
$ gh auth logout
# => select what host to log out of via a prompt

View file

@ -60,19 +60,19 @@ func NewCmdRefresh(f *cmdutil.Factory, runF func(*RefreshOptions) error) *cobra.
Use: "refresh",
Args: cobra.ExactArgs(0),
Short: "Refresh stored authentication credentials",
Long: heredoc.Doc(`Expand or fix the permission scopes for stored credentials.
Long: heredoc.Docf(`Expand or fix the permission scopes for stored credentials.
The --scopes flag accepts a comma separated list of scopes you want
The %[1]s--scopes%[1]s flag accepts a comma separated list of scopes you want
your gh credentials to have. If no scopes are provided, the command
maintains previously added scopes.
The --remove-scopes flag accepts a comma separated list of scopes you
The %[1]s--remove-scopes%[1]s flag accepts a comma separated list of scopes you
want to remove from your gh credentials. Scope removal is idempotent.
The minimum set of scopes ("repo", "read:org" and "gist") cannot be removed.
The minimum set of scopes (%[1]srepo%[1]s, %[1]sread:org%[1]s, and %[1]sgist%[1]s) cannot be removed.
The --reset-scopes flag resets the scopes for your gh credentials to
The %[1]s--reset-scopes%[1]s flag resets the scopes for your gh credentials to
the default set of scopes for your auth flow.
`),
`, "`"),
Example: heredoc.Doc(`
$ gh auth refresh --scopes write:org,read:public_key
# => open a browser to add write:org and read:public_key scopes

View file

@ -33,7 +33,7 @@ func NewCmdSetupGit(f *cmdutil.Factory, runF func(*SetupGitOptions) error) *cobr
Use: "setup-git",
Short: "Setup git with GitHub CLI",
Long: heredoc.Docf(`
This command configures git to use GitHub CLI as a credential helper.
This command configures %[1]sgit%[1]s to use GitHub CLI as a credential helper.
For more information on git credential helpers please reference:
https://git-scm.com/docs/gitcredentials.

View file

@ -53,39 +53,39 @@ func newSSHCmd(app *App) *cobra.Command {
sshCmd := &cobra.Command{
Use: "ssh [<flags>...] [-- <ssh-flags>...] [<command>]",
Short: "SSH into a codespace",
Long: heredoc.Doc(`
The 'ssh' command is used to SSH into a codespace. In its simplest form, you can
run 'gh cs ssh', select a codespace interactively, and connect.
Long: heredoc.Docf(`
The %[1]sssh%[1]s command is used to SSH into a codespace. In its simplest form, you can
run %[1]sgh cs ssh%[1]s, select a codespace interactively, and connect.
The 'ssh' command will automatically create a public/private ssh key pair in the
~/.ssh directory if you do not have an existing valid key pair. When selecting the
The %[1]sssh%[1]s command will automatically create a public/private ssh key pair in the
%[1]s~/.ssh%[1]s directory if you do not have an existing valid key pair. When selecting the
key pair to use, the preferred order is:
1. Key specified by -i in <ssh-flags>
1. Key specified by %[1]s-i%[1]s in %[1]s<ssh-flags>%[1]s
2. Automatic key, if it already exists
3. First valid key pair in ssh config (according to ssh -G)
3. First valid key pair in ssh config (according to %[1]sssh -G%[1]s)
4. Automatic key, newly created
The 'ssh' command also supports deeper integration with OpenSSH using a '--config'
The %[1]sssh%[1]s command also supports deeper integration with OpenSSH using a %[1]s--config%[1]s
option that generates per-codespace ssh configuration in OpenSSH format.
Including this configuration in your ~/.ssh/config improves the user experience
of tools that integrate with OpenSSH, such as bash/zsh completion of ssh hostnames,
remote path completion for scp/rsync/sshfs, git ssh remotes, and so on.
Including this configuration in your %[1]s~/.ssh/config%[1]s improves the user experience
of tools that integrate with OpenSSH, such as Bash/Zsh completion of ssh hostnames,
remote path completion for %[1]sscp/rsync/sshfs%[1]s, %[1]sgit%[1]s ssh remotes, and so on.
Once that is set up (see the second example below), you can ssh to codespaces as
if they were ordinary remote hosts (using 'ssh', not 'gh cs ssh').
if they were ordinary remote hosts (using %[1]sssh%[1]s, not %[1]sgh cs ssh%[1]s).
Note that the codespace you are connecting to must have an SSH server pre-installed.
If the docker image being used for the codespace does not have an SSH server,
install it in your Dockerfile or, for codespaces that use Debian-based images,
you can add the following to your devcontainer.json:
install it in your %[1]sDockerfile%[1]s or, for codespaces that use Debian-based images,
you can add the following to your %[1]sdevcontainer.json%[1]s:
"features": {
"ghcr.io/devcontainers/features/sshd:1": {
"version": "latest"
"features": {
"ghcr.io/devcontainers/features/sshd:1": {
"version": "latest"
}
}
}
`),
`, "`"),
Example: heredoc.Doc(`
$ gh codespace ssh
@ -693,7 +693,7 @@ func newCpCmd(app *App) *cobra.Command {
Use: "cp [-e] [-r] [-- [<scp flags>...]] <sources>... <dest>",
Short: "Copy files between local and remote file systems",
Long: heredoc.Docf(`
The cp command copies files between the local and remote file systems.
The %[1]scp%[1]s command copies files between the local and remote file systems.
As with the UNIX %[1]scp%[1]s command, the first argument specifies the source and the last
specifies the destination; additional sources may be specified after the first,
@ -701,7 +701,7 @@ func newCpCmd(app *App) *cobra.Command {
The %[1]s--recursive%[1]s flag is required if any source is a directory.
A "remote:" prefix on any file name argument indicates that it refers to
A %[1]sremote:%[1]s prefix on any file name argument indicates that it refers to
the file system of the remote (Codespace) machine. It is resolved relative
to the home directory of the remote user.
@ -711,8 +711,8 @@ func newCpCmd(app *App) *cobra.Command {
environment variables, and backticks. For security, do not use this flag with arguments
provided by untrusted users; see <https://lwn.net/Articles/835962/> for discussion.
By default, the 'cp' command will create a public/private ssh key pair to authenticate with
the codespace inside the ~/.ssh directory.
By default, the %[1]scp%[1]s command will create a public/private ssh key pair to authenticate with
the codespace inside the %[1]s~/.ssh directory%[1]s.
`, "`"),
Example: heredoc.Doc(`
$ gh codespace cp -e README.md 'remote:/workspaces/$RepositoryName/'

View file

@ -38,14 +38,14 @@ func NewCmdExtension(f *cmdutil.Factory) *cobra.Command {
Long: heredoc.Docf(`
GitHub CLI extensions are repositories that provide additional gh commands.
The name of the extension repository must start with "gh-" and it must contain an
The name of the extension repository must start with %[1]sgh-%[1]s and it must contain an
executable of the same name. All arguments passed to the %[1]sgh <extname>%[1]s invocation
will be forwarded to the %[1]sgh-<extname>%[1]s executable of the extension.
An extension cannot override any of the core gh commands. If an extension name conflicts
with a core gh command you can use %[1]sgh extension exec <extname>%[1]s.
with a core gh command, you can use %[1]sgh extension exec <extname>%[1]s.
See the list of available extensions at <https://github.com/topics/gh-extension>.
For the list of available extensions, see <https://github.com/topics/gh-extension>.
`, "`"),
Aliases: []string{"extensions", "ext"},
}
@ -93,36 +93,36 @@ func NewCmdExtension(f *cmdutil.Factory) *cobra.Command {
cmd := &cobra.Command{
Use: "search [<query>]",
Short: "Search extensions to the GitHub CLI",
Long: heredoc.Doc(`
Long: heredoc.Docf(`
Search for gh extensions.
With no arguments, this command prints out the first 30 extensions
available to install sorted by number of stars. More extensions can
be fetched by specifying a higher limit with the --limit flag.
be fetched by specifying a higher limit with the %[1]s--limit%[1]s flag.
When connected to a terminal, this command prints out three columns.
The first has a if the extension is already installed locally. The
second is the full name of the extension repository in NAME/OWNER
second is the full name of the extension repository in %[1]sOWNER/REPO%[1]s
format. The third is the extension's description.
When not connected to a terminal, the character is rendered as the
word "installed" but otherwise the order and content of the columns
is the same.
are the same.
This command behaves similarly to 'gh search repos' but does not
This command behaves similarly to %[1]sgh search repos%[1]s but does not
support as many search qualifiers. For a finer grained search of
extensions, try using:
gh search repos --topic "gh-extension"
and adding qualifiers as needed. See 'gh help search repos' to learn
and adding qualifiers as needed. See %[1]sgh help search repos%[1]s to learn
more about repository search.
For listing just the extensions that are already installed locally,
see:
gh ext list
`),
`, "`"),
Example: heredoc.Doc(`
# List the first 30 extensions sorted by star count, descending
$ gh ext search
@ -297,17 +297,17 @@ func NewCmdExtension(f *cmdutil.Factory) *cobra.Command {
cmd := &cobra.Command{
Use: "install <repository>",
Short: "Install a gh extension from a repository",
Long: heredoc.Doc(`
Long: heredoc.Docf(`
Install a GitHub repository locally as a GitHub CLI extension.
The repository argument can be specified in "owner/repo" format as well as a full URL.
The repository argument can be specified in %[1]sOWNER/REPO%[1]s format as well as a full URL.
The URL format is useful when the repository is not hosted on github.com.
To install an extension in development from the current directory, use "." as the
To install an extension in development from the current directory, use %[1]s.%[1]s as the
value of the repository argument.
See the list of available extensions at <https://github.com/topics/gh-extension>.
`),
For the list of available extensions, see <https://github.com/topics/gh-extension>.
`, "`"),
Example: heredoc.Doc(`
$ gh extension install owner/gh-extension
$ gh extension install https://git.example.com/owner/gh-extension
@ -347,7 +347,11 @@ func NewCmdExtension(f *cmdutil.Factory) *cobra.Command {
return err
}
if err := m.Install(repo, pinFlag); err != nil {
io.StartProgressIndicator()
err = m.Install(repo, pinFlag)
io.StopProgressIndicator()
if err != nil {
if errors.Is(err, releaseNotFoundErr) {
return fmt.Errorf("%s Could not find a release of %s for %s",
cs.FailureIcon(), args[0], cs.Cyan(pinFlag))
@ -431,17 +435,17 @@ func NewCmdExtension(f *cmdutil.Factory) *cobra.Command {
cmd := &cobra.Command{
Use: "browse",
Short: "Enter a UI for browsing, adding, and removing extensions",
Long: heredoc.Doc(`
Long: heredoc.Docf(`
This command will take over your terminal and run a fully interactive
interface for browsing, adding, and removing gh extensions. A terminal
width greater than 100 columns is recommended.
To learn how to control this interface, press ? after running to see
To learn how to control this interface, press %[1]s?%[1]s after running to see
the help text.
Press q to quit.
Press %[1]sq%[1]s to quit.
Running this command with --single-column should make this command
Running this command with %[1]s--single-column%[1]s should make this command
more intelligible for users who rely on assistive technology like screen
readers or high zoom.
@ -449,8 +453,8 @@ func NewCmdExtension(f *cmdutil.Factory) *cobra.Command {
gh ext search
along with gh ext install, gh ext remove, and gh repo view.
`),
along with %[1]sgh ext install%[1]s, %[1]sgh ext remove%[1]s, and %[1]sgh repo view%[1]s.
`, "`"),
Args: cobra.NoArgs,
RunE: func(cmd *cobra.Command, args []string) error {
if !io.CanPrompt() {
@ -492,14 +496,14 @@ func NewCmdExtension(f *cmdutil.Factory) *cobra.Command {
&cobra.Command{
Use: "exec <name> [args]",
Short: "Execute an installed extension",
Long: heredoc.Doc(`
Long: heredoc.Docf(`
Execute an extension using the short name. For example, if the extension repository is
"owner/gh-extension", you should pass "extension". You can use this command when
%[1]sowner/gh-extension%[1]s, you should pass %[1]sextension%[1]s. You can use this command when
the short name conflicts with a core gh command.
All arguments after the extension name will be forwarded to the executable
of the extension.
`),
`, "`"),
Example: heredoc.Doc(`
# execute a label extension instead of the core gh label command
$ gh extension exec label

View file

@ -40,15 +40,15 @@ func NewCmdClone(f *cmdutil.Factory, runF func(*CloneOptions) error) *cobra.Comm
Use: "clone <gist> [<directory>] [-- <gitflags>...]",
Args: cmdutil.MinimumArgs(1, "cannot clone: gist argument required"),
Short: "Clone a gist locally",
Long: heredoc.Doc(`
Long: heredoc.Docf(`
Clone a GitHub gist locally.
A gist can be supplied as argument in either of the following formats:
- by ID, e.g. 5b0e0062eb8e9654adad7bb1d81cc75f
- by URL, e.g. "https://gist.github.com/OWNER/5b0e0062eb8e9654adad7bb1d81cc75f"
- by ID, e.g. %[1]s5b0e0062eb8e9654adad7bb1d81cc75f%[1]s
- by URL, e.g. %[1]shttps://gist.github.com/OWNER/5b0e0062eb8e9654adad7bb1d81cc75f%[1]s
Pass additional 'git clone' flags by listing them after '--'.
`),
Pass additional %[1]sgit clone%[1]s flags by listing them after %[1]s--%[1]s.
`, "`"),
RunE: func(cmd *cobra.Command, args []string) error {
opts.Gist = args[0]
opts.GitArgs = args[1:]

View file

@ -50,14 +50,14 @@ func NewCmdCreate(f *cmdutil.Factory, runF func(*CreateOptions) error) *cobra.Co
cmd := &cobra.Command{
Use: "create [<filename>... | -]",
Short: "Create a new gist",
Long: heredoc.Doc(`
Long: heredoc.Docf(`
Create a new GitHub gist with given contents.
Gists can be created from one or multiple files. Alternatively, pass "-" as
Gists can be created from one or multiple files. Alternatively, pass %[1]s-%[1]s as
file name to read from standard input.
By default, gists are secret; use '--public' to make publicly listed ones.
`),
By default, gists are secret; use %[1]s--public%[1]s to make publicly listed ones.
`, "`"),
Example: heredoc.Doc(`
# publish file 'hello.py' as a public gist
$ gh gist create --public hello.py

View file

@ -56,12 +56,12 @@ func NewCmdCreate(f *cmdutil.Factory, runF func(*CreateOptions) error) *cobra.Co
cmd := &cobra.Command{
Use: "create",
Short: "Create a new issue",
Long: heredoc.Doc(`
Long: heredoc.Docf(`
Create an issue on GitHub.
Adding an issue to projects requires authorization with the "project" scope.
To authorize, run "gh auth refresh -s project".
`),
Adding an issue to projects requires authorization with the %[1]sproject%[1]s scope.
To authorize, run %[1]sgh auth refresh -s project%[1]s.
`, "`"),
Example: heredoc.Doc(`
$ gh issue create --title "I found a bug" --body "Nothing works"
$ gh issue create --label "bug,help wanted"

View file

@ -50,12 +50,12 @@ func NewCmdEdit(f *cmdutil.Factory, runF func(*EditOptions) error) *cobra.Comman
cmd := &cobra.Command{
Use: "edit {<numbers> | <urls>}",
Short: "Edit issues",
Long: heredoc.Doc(`
Long: heredoc.Docf(`
Edit one or more issues within the same repository.
Editing issues' projects requires authorization with the "project" scope.
To authorize, run "gh auth refresh -s project".
`),
Editing issues' projects requires authorization with the %[1]sproject%[1]s scope.
To authorize, run %[1]sgh auth refresh -s project%[1]s.
`, "`"),
Example: heredoc.Doc(`
$ gh issue edit 23 --title "I found a bug" --body "Nothing works"
$ gh issue edit 23 --add-label "bug,help wanted" --remove-label "core"

View file

@ -48,11 +48,11 @@ func NewCmdView(f *cmdutil.Factory, runF func(*ViewOptions) error) *cobra.Comman
cmd := &cobra.Command{
Use: "view {<number> | <url>}",
Short: "View an issue",
Long: heredoc.Doc(`
Long: heredoc.Docf(`
Display the title, body, and other information about an issue.
With '--web', open the issue in a web browser instead.
`),
With %[1]s--web%[1]s flag, open the issue in a web browser instead.
`, "`"),
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
// support `-R, --repo` override

View file

@ -34,7 +34,7 @@ func newCmdClone(f *cmdutil.Factory, runF func(*cloneOptions) error) *cobra.Comm
cmd := &cobra.Command{
Use: "clone <source-repository>",
Short: "Clones labels from one repository to another",
Long: heredoc.Doc(`
Long: heredoc.Docf(`
Clones labels from a source repository to a destination repository on GitHub.
By default, the destination repository is the current repository.
@ -44,8 +44,8 @@ func newCmdClone(f *cmdutil.Factory, runF func(*cloneOptions) error) *cobra.Comm
Labels from the source repository that already exist in the destination
repository will be skipped. You can overwrite existing labels in the
destination repository using the --force flag.
`),
destination repository using the %[1]s--force%[1]s flag.
`, "`"),
Example: heredoc.Doc(`
# clone and overwrite labels from cli/cli repository into the current repository
$ gh label clone cli/cli --force

View file

@ -57,14 +57,14 @@ func newCmdCreate(f *cmdutil.Factory, runF func(*createOptions) error) *cobra.Co
cmd := &cobra.Command{
Use: "create <name>",
Short: "Create a new label",
Long: heredoc.Doc(`
Create a new label on GitHub, or updates an existing one with --force.
Long: heredoc.Docf(`
Create a new label on GitHub, or update an existing one with %[1]s--force%[1]s.
Must specify name for the label. The description and color are optional.
If a color isn't provided, a random one will be chosen.
The label color needs to be 6 character hex value.
`),
`, "`"),
Example: heredoc.Doc(`
# create new bug label
$ gh label create bug --description "Something isn't working" --color E99695

View file

@ -118,8 +118,8 @@ func NewCmdCreate(f *cmdutil.Factory, runF func(*CreateOptions) error) *cobra.Co
By default, users with write access to the base repository can push new commits to the
head branch of the pull request. Disable this with %[1]s--no-maintainer-edit%[1]s.
Adding a pull request to projects requires authorization with the "project" scope.
To authorize, run "gh auth refresh -s project".
Adding a pull request to projects requires authorization with the %[1]sproject%[1]s scope.
To authorize, run %[1]sgh auth refresh -s project%[1]s.
`, "`"),
Example: heredoc.Doc(`
$ gh pr create --title "The bug is fixed" --body "Everything works again"

View file

@ -50,14 +50,14 @@ func NewCmdDiff(f *cmdutil.Factory, runF func(*DiffOptions) error) *cobra.Comman
cmd := &cobra.Command{
Use: "diff [<number> | <url> | <branch>]",
Short: "View changes in a pull request",
Long: heredoc.Doc(`
Long: heredoc.Docf(`
View changes in a pull request.
Without an argument, the pull request that belongs to the current branch
is selected.
With '--web', open the pull request diff in a web browser instead.
`),
With %[1]s--web%[1]s flag, open the pull request diff in a web browser instead.
`, "`"),
Args: cobra.MaximumNArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
opts.Finder = shared.NewFinder(f)

View file

@ -47,15 +47,15 @@ func NewCmdEdit(f *cmdutil.Factory, runF func(*EditOptions) error) *cobra.Comman
cmd := &cobra.Command{
Use: "edit [<number> | <url> | <branch>]",
Short: "Edit a pull request",
Long: heredoc.Doc(`
Long: heredoc.Docf(`
Edit a pull request.
Without an argument, the pull request that belongs to the current branch
is selected.
Editing a pull request's projects requires authorization with the "project" scope.
To authorize, run "gh auth refresh -s project".
`),
Editing a pull request's projects requires authorization with the %[1]sproject%[1]s scope.
To authorize, run %[1]sgh auth refresh -s project%[1]s.
`, "`"),
Example: heredoc.Doc(`
$ gh pr edit 23 --title "I found a bug" --body "Nothing works"
$ gh pr edit 23 --add-label "bug,help wanted" --remove-label "core"

View file

@ -78,17 +78,17 @@ func NewCmdMerge(f *cmdutil.Factory, runF func(*MergeOptions) error) *cobra.Comm
cmd := &cobra.Command{
Use: "merge [<number> | <url> | <branch>]",
Short: "Merge a pull request",
Long: heredoc.Doc(`
Long: heredoc.Docf(`
Merge a pull request on GitHub.
Without an argument, the pull request that belongs to the current branch
is selected.
When targeting a branch that requires a merge queue, no merge strategy is required.
If required checks have not yet passed, AutoMerge will be enabled.
If required checks have not yet passed, auto-merge will be enabled.
If required checks have passed, the pull request will be added to the merge queue.
To bypass a merge queue and merge directly, pass the '--admin' flag.
`),
To bypass a merge queue and merge directly, pass the %[1]s--admin%[1]s flag.
`, "`"),
Args: cobra.MaximumNArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
opts.Finder = shared.NewFinder(f)
@ -302,6 +302,8 @@ func (m *mergeContext) merge() error {
return cmdutil.FlagErrorf("--merge, --rebase, or --squash required when not running interactively")
}
_ = m.infof("Merging pull request #%d (%s)\n", m.pr.Number, m.pr.Title)
apiClient := api.NewClientFromHTTP(m.httpClient)
r, err := api.GitHubRepo(apiClient, m.baseRepo)
if err != nil {

View file

@ -1275,7 +1275,7 @@ func TestPRMergeTTY(t *testing.T) {
t.Fatalf("Got unexpected error running `pr merge` %s", err)
}
assert.Equal(t, "✓ Merged pull request #3 (It was the best of times)\n", output.Stderr())
assert.Equal(t, "Merging pull request #3 (It was the best of times)\n✓ Merged pull request #3 (It was the best of times)\n", output.Stderr())
}
func TestPRMergeTTY_withDeleteBranch(t *testing.T) {
@ -1346,6 +1346,7 @@ func TestPRMergeTTY_withDeleteBranch(t *testing.T) {
assert.Equal(t, "", output.String())
assert.Equal(t, heredoc.Doc(`
Merging pull request #3 (It was the best of times)
Merged pull request #3 (It was the best of times)
Deleted local branch blueberries and switched to branch main
Deleted remote branch blueberries
@ -1437,7 +1438,7 @@ func TestPRMergeTTY_squashEditCommitMsgAndSubject(t *testing.T) {
assert.NoError(t, err)
assert.Equal(t, "", stdout.String())
assert.Equal(t, "✓ Squashed and merged pull request #123 (title)\n", stderr.String())
assert.Equal(t, "Merging pull request #123 (title)\n✓ Squashed and merged pull request #123 (title)\n", stderr.String())
}
func TestPRMergeEmptyStrategyNonTTY(t *testing.T) {
@ -1473,7 +1474,7 @@ func TestPRTTY_cancelled(t *testing.T) {
shared.RunCommandFinder(
"",
&api.PullRequest{ID: "THE-ID", Number: 123, MergeStateStatus: "CLEAN"},
&api.PullRequest{ID: "THE-ID", Number: 123, Title: "title", MergeStateStatus: "CLEAN"},
ghrepo.New("OWNER", "REPO"),
)
@ -1516,7 +1517,7 @@ func TestPRTTY_cancelled(t *testing.T) {
t.Fatalf("got error %v", err)
}
assert.Equal(t, "Cancelled.\n", output.Stderr())
assert.Equal(t, "Merging pull request #123 (title)\nCancelled.\n", output.Stderr())
}
func Test_mergeMethodSurvey(t *testing.T) {
@ -1866,7 +1867,7 @@ func TestPrAddToMergeQueueAdmin(t *testing.T) {
}
assert.Equal(t, "", output.String())
assert.Equal(t, "✓ Merged pull request #1 (The title of the PR)\n", output.Stderr())
assert.Equal(t, "Merging pull request #1 (The title of the PR)\n✓ Merged pull request #1 (The title of the PR)\n", output.Stderr())
}
func TestPrAddToMergeQueueAdminWithMergeStrategy(t *testing.T) {

View file

@ -31,14 +31,14 @@ func NewCmdReady(f *cmdutil.Factory, runF func(*ReadyOptions) error) *cobra.Comm
cmd := &cobra.Command{
Use: "ready [<number> | <url> | <branch>]",
Short: "Mark a pull request as ready for review",
Long: heredoc.Doc(`
Long: heredoc.Docf(`
Mark a pull request as ready for review.
Without an argument, the pull request that belongs to the current branch
is marked as ready.
If supported by your plan, convert to draft with --undo
`),
If supported by your plan, convert to draft with %[1]s--undo%[1]s
`, "`"),
Args: cobra.MaximumNArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
opts.Finder = shared.NewFinder(f)

View file

@ -42,14 +42,14 @@ func NewCmdView(f *cmdutil.Factory, runF func(*ViewOptions) error) *cobra.Comman
cmd := &cobra.Command{
Use: "view [<number> | <url> | <branch>]",
Short: "View a pull request",
Long: heredoc.Doc(`
Long: heredoc.Docf(`
Display the title, body, and other information about a pull request.
Without an argument, the pull request that belongs to the current branch
is displayed.
With '--web', open the pull request in a web browser instead.
`),
With %[1]s--web%[1]s flag, open the pull request in a web browser instead.
`, "`"),
Args: cobra.MaximumNArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
opts.Finder = shared.NewFinder(f)

View file

@ -62,13 +62,13 @@ func NewCmdEditItem(f *cmdutil.Factory, runF func(config editItemConfig) error)
editItemCmd := &cobra.Command{
Use: "item-edit",
Short: "Edit an item in a project",
Long: heredoc.Doc(`
Long: heredoc.Docf(`
Edit either a draft issue or a project item. Both usages require the ID of the item to edit.
For non-draft issues, the ID of the project is also required, and only a single field value can be updated per invocation.
Remove project item field value using "--clear" flag.
`),
Remove project item field value using %[1]s--clear%[1]s flag.
`, "`"),
Example: heredoc.Doc(`
# edit an item's text field value
gh project item-edit --id <item-ID> --field-id <field-ID> --project-id <project-ID> --text "new text"

View file

@ -94,11 +94,11 @@ func NewCmdCreate(f *cmdutil.Factory, runF func(*CreateOptions) error) *cobra.Co
To create a release from an annotated git tag, first create one locally with
git, push the tag to GitHub, then run this command.
Use %[1]s--notes-from-tag%[1]s to automatically generate the release notes
from the annotated git tag.
from the annotated git tag.
When using automatically generated release notes, a release title will also be automatically
generated unless a title was explicitly passed. Additional release notes can be prepended to
automatically generated notes by using the notes parameter.
automatically generated notes by using the %[1]s--notes%[1]s flag.
`, "`"),
Example: heredoc.Doc(`
Interactively create a release

View file

@ -46,13 +46,13 @@ func NewCmdDownload(f *cmdutil.Factory, runF func(*DownloadOptions) error) *cobr
cmd := &cobra.Command{
Use: "download [<tag>]",
Short: "Download release assets",
Long: heredoc.Doc(`
Long: heredoc.Docf(`
Download assets from a GitHub release.
Without an explicit tag name argument, assets are downloaded from the
latest release in the project. In this case, "--pattern" or "--archive"
is required.
`),
latest release in the project. In this case, %[1]s--pattern%[1]s or %[1]s--archive%[1]s
is required.
`, "`"),
Example: heredoc.Doc(`
# download all assets from a specific release
$ gh release download v1.2.3

View file

@ -38,12 +38,12 @@ func NewCmdUpload(f *cmdutil.Factory, runF func(*UploadOptions) error) *cobra.Co
cmd := &cobra.Command{
Use: "upload <tag> <files>...",
Short: "Upload assets to a release",
Long: heredoc.Doc(`
Long: heredoc.Docf(`
Upload asset files to a GitHub Release.
To define a display label for an asset, append text starting with '#' after the
To define a display label for an asset, append text starting with %[1]%#%[1]% after the
file name.
`),
`, "`"),
Args: cobra.MinimumNArgs(2),
RunE: func(cmd *cobra.Command, args []string) error {
// support `-R, --repo` override

View file

@ -44,14 +44,14 @@ func NewCmdClone(f *cmdutil.Factory, runF func(*CloneOptions) error) *cobra.Comm
Short: "Clone a repository locally",
Long: heredoc.Docf(`
Clone a GitHub repository locally. Pass additional %[1]sgit clone%[1]s flags by listing
them after "--".
them after %[1]s--%[1]s.
If the "OWNER/" portion of the "OWNER/REPO" repository argument is omitted, it
If the %[1]sOWNER/%[1]s portion of the %[1]sOWNER/REPO%[1]s repository argument is omitted, it
defaults to the name of the authenticating user.
If the repository is a fork, its parent repository will be added as an additional
git remote called "upstream". The remote name can be configured using %[1]s--upstream-remote-name%[1]s.
The %[1]s--upstream-remote-name%[1]s option supports an "@owner" value which will name
git remote called %[1]supstream%[1]s. The remote name can be configured using %[1]s--upstream-remote-name%[1]s.
The %[1]s--upstream-remote-name%[1]s option supports an %[1]s@owner%[1]s value which will name
the remote after the owner of the parent repository.
If the repository is a fork, its parent repository will be set as the default remote repository.

View file

@ -101,7 +101,7 @@ func NewCmdEdit(f *cmdutil.Factory, runF func(options *EditOptions) error) *cobr
Long: heredoc.Docf(`
Edit repository settings.
To toggle a setting off, use the %[1]s--flag=false%[1]s syntax.
To toggle a setting off, use the %[1]s--<flag>=false%[1]s syntax.
Note that changing repository visibility to private will cause loss of stars and watchers.
`, "`"),

View file

@ -88,13 +88,13 @@ func NewCmdFork(f *cmdutil.Factory, runF func(*ForkOptions) error) *cobra.Comman
With no argument, creates a fork of the current repository. Otherwise, forks
the specified repository.
By default, the new fork is set to be your "origin" remote and any existing
origin remote is renamed to "upstream". To alter this behavior, you can set
By default, the new fork is set to be your %[1]sorigin%[1]s remote and any existing
origin remote is renamed to %[1]supstream%[1]s. To alter this behavior, you can set
a name for the new fork's remote with %[1]s--remote-name%[1]s.
The "upstream" remote will be set as the default remote repository.
The %[1]supstream%[1]s remote will be set as the default remote repository.
Additional git clone flags can be passed after %[1]s--%[1]s.
Additional %[1]sgit clone%[1]s flags can be passed after %[1]s--%[1]s.
`, "`"),
RunE: func(cmd *cobra.Command, args []string) error {
promptOk := opts.IO.CanPrompt()

View file

@ -29,7 +29,7 @@ func explainer() string {
- viewing and creating pull requests
- viewing and creating issues
- viewing and creating releases
- working with Actions
- working with GitHub Actions
- adding repository and environment secrets`)
}

View file

@ -379,7 +379,7 @@ func TestDefaultRun(t *testing.T) {
}
}
},
wantStdout: "This command sets the default remote repository to use when querying the\nGitHub API for the locally cloned repository.\n\ngh uses the default repository for things like:\n\n - viewing and creating pull requests\n - viewing and creating issues\n - viewing and creating releases\n - working with Actions\n - adding repository and environment secrets\n\n✓ Set OWNER2/REPO2 as the default repository for the current directory\n",
wantStdout: "This command sets the default remote repository to use when querying the\nGitHub API for the locally cloned repository.\n\ngh uses the default repository for things like:\n\n - viewing and creating pull requests\n - viewing and creating issues\n - viewing and creating releases\n - working with GitHub Actions\n - adding repository and environment secrets\n\n✓ Set OWNER2/REPO2 as the default repository for the current directory\n",
},
{
name: "interactive mode only one known host",
@ -453,7 +453,7 @@ func TestDefaultRun(t *testing.T) {
}
}
},
wantStdout: "This command sets the default remote repository to use when querying the\nGitHub API for the locally cloned repository.\n\ngh uses the default repository for things like:\n\n - viewing and creating pull requests\n - viewing and creating issues\n - viewing and creating releases\n - working with Actions\n - adding repository and environment secrets\n\n✓ Set OWNER2/REPO2 as the default repository for the current directory\n",
wantStdout: "This command sets the default remote repository to use when querying the\nGitHub API for the locally cloned repository.\n\ngh uses the default repository for things like:\n\n - viewing and creating pull requests\n - viewing and creating issues\n - viewing and creating releases\n - working with GitHub Actions\n - adding repository and environment secrets\n\n✓ Set OWNER2/REPO2 as the default repository for the current directory\n",
},
}

View file

@ -46,7 +46,7 @@ func NewCmdSync(f *cmdutil.Factory, runF func(*SyncOptions) error) *cobra.Comman
Use: "sync [<destination-repository>]",
Short: "Sync a repository",
Long: heredoc.Docf(`
Sync destination repository from source repository. Syncing uses the main branch
Sync destination repository from source repository. Syncing uses the default branch
of the source repository to update the matching branch on the destination
repository so they are equal. A fast forward update will be used except when the
%[1]s--force%[1]s flag is specified, then the two branches will
@ -83,7 +83,7 @@ func NewCmdSync(f *cmdutil.Factory, runF func(*SyncOptions) error) *cobra.Comman
}
cmd.Flags().StringVarP(&opts.SrcArg, "source", "s", "", "Source repository")
cmd.Flags().StringVarP(&opts.Branch, "branch", "b", "", "Branch to sync (default: main branch)")
cmd.Flags().StringVarP(&opts.Branch, "branch", "b", "", "Branch to sync (default: default branch)")
cmd.Flags().BoolVarP(&opts.Force, "force", "", false, "Hard reset the branch of the destination repository to match the source repository")
return cmd
}

View file

@ -171,9 +171,10 @@ func rootHelpFunc(f *cmdutil.Factory, command *cobra.Command, args []string) {
if _, ok := command.Annotations["help:environment"]; ok {
helpEntries = append(helpEntries, helpEntry{"ENVIRONMENT VARIABLES", command.Annotations["help:environment"]})
}
helpEntries = append(helpEntries, helpEntry{"LEARN MORE", `
Use 'gh <command> <subcommand> --help' for more information about a command.
Read the manual at https://cli.github.com/manual`})
helpEntries = append(helpEntries, helpEntry{"LEARN MORE", heredoc.Docf(`
Use %[1]sgh <command> <subcommand> --help%[1]s for more information about a command.
Read the manual at https://cli.github.com/manual
`, "`")})
out := f.IOStreams.Out
for _, e := range helpEntries {

View file

@ -21,7 +21,7 @@ var HelpTopics = []helpTopic{
{
name: "mintty",
short: "Information about using gh with MinTTY",
long: heredoc.Doc(`
long: heredoc.Docf(`
MinTTY is the terminal emulator that comes by default with Git
for Windows. It has known issues with gh's ability to prompt a
user for input.
@ -31,75 +31,75 @@ var HelpTopics = []helpTopic{
- Reinstall Git for Windows, checking "Enable experimental support for pseudo consoles".
- Use a different terminal emulator with Git for Windows like Windows Terminal.
You can run "C:\Program Files\Git\bin\bash.exe" from any terminal emulator to continue
You can run %[1]sC:\Program Files\Git\bin\bash.exe%[1]s from any terminal emulator to continue
using all of the tooling in Git For Windows without MinTTY.
- Prefix invocations of gh with winpty, eg: "winpty gh auth login".
- Prefix invocations of gh with %[1]swinpty%[1]s, eg: %[1]swinpty gh auth login%[1]s.
NOTE: this can lead to some UI bugs.
`),
`, "`"),
},
{
name: "environment",
short: "Environment variables that can be used with gh",
long: heredoc.Doc(`
GH_TOKEN, GITHUB_TOKEN (in order of precedence): an authentication token for github.com
long: heredoc.Docf(`
%[1]sGH_TOKEN%[1]s, %[1]sGITHUB_TOKEN%[1]s (in order of precedence): an authentication token for github.com
API requests. Setting this avoids being prompted to authenticate and takes precedence over
previously stored credentials.
GH_ENTERPRISE_TOKEN, GITHUB_ENTERPRISE_TOKEN (in order of precedence): an authentication
token for API requests to GitHub Enterprise. When setting this, also set GH_HOST.
%[1]sGH_ENTERPRISE_TOKEN%[1]s, %[1]sGITHUB_ENTERPRISE_TOKEN%[1]s (in order of precedence): an authentication
token for API requests to GitHub Enterprise. When setting this, also set %[1]sGH_HOST%[1]s.
GH_HOST: specify the GitHub hostname for commands that would otherwise assume the
%[1]sGH_HOST%[1]s: specify the GitHub hostname for commands that would otherwise assume the
"github.com" host when not in a context of an existing repository. When setting this,
also set GH_ENTERPRISE_TOKEN.
also set %[1]sGH_ENTERPRISE_TOKEN%[1]s.
GH_REPO: specify the GitHub repository in the "[HOST/]OWNER/REPO" format for commands
%[1]sGH_REPO%[1]s: specify the GitHub repository in the %[1]s[HOST/]OWNER/REPO%[1]s format for commands
that otherwise operate on a local repository.
GH_EDITOR, GIT_EDITOR, VISUAL, EDITOR (in order of precedence): the editor tool to use
%[1]sGH_EDITOR%[1]s, %[1]sGIT_EDITOR%[1]s, %[1]sVISUAL%[1]s, %[1]sEDITOR%[1]s (in order of precedence): the editor tool to use
for authoring text.
GH_BROWSER, BROWSER (in order of precedence): the web browser to use for opening links.
%[1]sGH_BROWSER%[1]s, %[1]sBROWSER%[1]s (in order of precedence): the web browser to use for opening links.
GH_DEBUG: set to a truthy value to enable verbose output on standard error. Set to "api"
%[1]sGH_DEBUG%[1]s: set to a truthy value to enable verbose output on standard error. Set to %[1]sapi%[1]s
to additionally log details of HTTP traffic.
DEBUG (deprecated): set to "1", "true", or "yes" to enable verbose output on standard
%[1]sDEBUG%[1]s (deprecated): set to %[1]s1%[1]s, %[1]strue%[1]s, or %[1]syes%[1]s to enable verbose output on standard
error.
GH_PAGER, PAGER (in order of precedence): a terminal paging program to send standard output
to, e.g. "less".
%[1]sGH_PAGER%[1]s, %[1]sPAGER%[1]s (in order of precedence): a terminal paging program to send standard output
to, e.g. %[1]sless%[1]s.
GLAMOUR_STYLE: the style to use for rendering Markdown. See
%[1]sGLAMOUR_STYLE%[1]s: the style to use for rendering Markdown. See
<https://github.com/charmbracelet/glamour#styles>
NO_COLOR: set to any value to avoid printing ANSI escape sequences for color output.
%[1]sNO_COLOR%[1]s: set to any value to avoid printing ANSI escape sequences for color output.
CLICOLOR: set to "0" to disable printing ANSI colors in output.
%[1]sCLICOLOR%[1]s: set to %[1]s0%[1]s to disable printing ANSI colors in output.
CLICOLOR_FORCE: set to a value other than "0" to keep ANSI colors in output
%[1]sCLICOLOR_FORCE%[1]s: set to a value other than %[1]s0%[1]s to keep ANSI colors in output
even when the output is piped.
GH_FORCE_TTY: set to any value to force terminal-style output even when the output is
%[1]sGH_FORCE_TTY%[1]s: set to any value to force terminal-style output even when the output is
redirected. When the value is a number, it is interpreted as the number of columns
available in the viewport. When the value is a percentage, it will be applied against
the number of columns available in the current viewport.
GH_NO_UPDATE_NOTIFIER: set to any value to disable update notifications. By default, gh
%[1]sGH_NO_UPDATE_NOTIFIER%[1]s: set to any value to disable update notifications. By default, gh
checks for new releases once every 24 hours and displays an upgrade notice on standard
error if a newer version was found.
GH_CONFIG_DIR: the directory where gh will store configuration files. If not specified,
%[1]sGH_CONFIG_DIR%[1]s: the directory where gh will store configuration files. If not specified,
the default value will be one of the following paths (in order of precedence):
- "$XDG_CONFIG_HOME/gh" (if $XDG_CONFIG_HOME is set),
- "$AppData/GitHub CLI" (on Windows if $AppData is set), or
- "$HOME/.config/gh".
- %[1]s$XDG_CONFIG_HOME/gh%[1]s (if %[1]s$XDG_CONFIG_HOME%[1]s is set),
- %[1]s$AppData/GitHub CLI%[1]s (on Windows if %[1]s$AppData%[1]s is set), or
- %[1]s$HOME/.config/gh%[1]s.
GH_PROMPT_DISABLED: set to any value to disable interactive prompting in the terminal.
%[1]sGH_PROMPT_DISABLED%[1]s: set to any value to disable interactive prompting in the terminal.
GH_PATH: set the path to the gh executable, useful for when gh can not properly determine
%[1]sGH_PATH%[1]s: set the path to the gh executable, useful for when gh can not properly determine
its own path such as in the cygwin terminal.
`),
`, "`"),
},
{
name: "reference",
@ -122,10 +122,10 @@ var HelpTopics = []helpTopic{
The %[1]s--jq%[1]s flag requires a string argument in jq query syntax, and will only print
those JSON values which match the query. jq queries can be used to select elements from an
array, fields from an object, create a new array, and more. The jq utility does not need
array, fields from an object, create a new array, and more. The %[1]sjq%[1]s utility does not need
to be installed on the system to use this formatting directive. When connected to a terminal,
the output is automatically pretty-printed. To learn about jq query syntax, see:
<https://stedolan.github.io/jq/manual/v1.6/>
<https://jqlang.github.io/jq/manual/>
The %[1]s--template%[1]s flag requires a string argument in Go template syntax, and will only print
those JSON values which match the query.
@ -138,7 +138,7 @@ var HelpTopics = []helpTopic{
- %[1]stablerow <fields>...%[1]s: aligns fields in output vertically as a table
- %[1]stablerender%[1]s: renders fields added by tablerow in place
- %[1]stimeago <time>%[1]s: renders a timestamp as relative to now
- %[1]stimefmt <format> <time>%[1]s: formats a timestamp using Go's Time.Format function
- %[1]stimefmt <format> <time>%[1]s: formats a timestamp using Go's %[1]sTime.Format%[1]s function
- %[1]struncate <length> <input>%[1]s: ensures input fits within length
- %[1]shyperlink <url> <text>%[1]s: renders a terminal hyperlink

View file

@ -43,7 +43,7 @@ func NewCmdCheck(f *cmdutil.Factory, runF func(*CheckOptions) error) *cobra.Comm
cmd := &cobra.Command{
Use: "check [<branch>]",
Short: "View rules that would apply to a given branch",
Long: heredoc.Doc(`
Long: heredoc.Docf(`
View information about GitHub rules that apply to a given branch.
The provided branch name does not need to exist; rules will be displayed that would apply
@ -51,9 +51,9 @@ func NewCmdCheck(f *cmdutil.Factory, runF func(*CheckOptions) error) *cobra.Comm
If no branch name is provided, then the current branch will be used.
The --default flag can be used to view rules that apply to the default branch of the
The %[1]s--default%[1]s flag can be used to view rules that apply to the default branch of the
repository.
`),
`, "`"),
Example: heredoc.Doc(`
# View all rules that apply to the current branch
$ gh ruleset check

View file

@ -40,18 +40,18 @@ func NewCmdList(f *cmdutil.Factory, runF func(*ListOptions) error) *cobra.Comman
cmd := &cobra.Command{
Use: "list",
Short: "List rulesets for a repository or organization",
Long: heredoc.Doc(`
Long: heredoc.Docf(`
List GitHub rulesets for a repository or organization.
If no options are provided, the current repository's rulesets are listed. You can query a different
repository's rulesets by using the --repo flag. You can also use the --org flag to list rulesets
repository's rulesets by using the %[1]s--repo%[1]s flag. You can also use the %[1]s--org%[1]s flag to list rulesets
configured for the provided organization.
Use the --parents flag to control whether rulesets configured at higher levels that also apply to the provided
repository or organization should be returned. The default is true.
Use the %[1]s--parents%[1]s flag to control whether rulesets configured at higher levels that also apply to the provided
repository or organization should be returned. The default is %[1]strue%[1]s.
Your access token must have the admin:org scope to use the --org flag, which can be granted by running "gh auth refresh -s admin:org".
`),
Your access token must have the %[1]sadmin:org%[1]s scope to use the %[1]s--org%[1]s flag, which can be granted by running %[1]sgh auth refresh -s admin:org%[1]s.
`, "`"),
Example: heredoc.Doc(`
# List rulesets in the current repository
$ gh ruleset list

View file

@ -44,16 +44,16 @@ func NewCmdView(f *cmdutil.Factory, runF func(*ViewOptions) error) *cobra.Comman
cmd := &cobra.Command{
Use: "view [<ruleset-id>]",
Short: "View information about a ruleset",
Long: heredoc.Doc(`
Long: heredoc.Docf(`
View information about a GitHub ruleset.
If no ID is provided, an interactive prompt will be used to choose
the ruleset to view.
Use the --parents flag to control whether rulesets configured at higher
Use the %[1]s--parents%[1]s flag to control whether rulesets configured at higher
levels that also apply to the provided repository or organization should
be returned. The default is true.
`),
be returned. The default is %[1]strue%[1]s.
`, "`"),
Example: heredoc.Doc(`
# Interactively choose a ruleset to view from all rulesets that apply to the current repository
$ gh ruleset view

View file

@ -44,13 +44,14 @@ func NewCmdRerun(f *cmdutil.Factory, runF func(*RerunOptions) error) *cobra.Comm
Long: heredoc.Docf(`
Rerun an entire run, only failed jobs, or a specific job from a run.
Note that due for historical reasons, the %[1]s--job%[1]s flag may not take what you expect.
Note that due to historical reasons, the %[1]s--job%[1]s flag may not take what you expect.
Specifically, when navigating to a job in the browser, the URL looks like this:
%[1]shttps://github.com/<org>/<repo>/actions/runs/<run-id>/jobs/<number>%[1]s.
%[1]shttps://github.com/<owner>/<repo>/actions/runs/<run-id>/jobs/<number>%[1]s.
However, this %[1]snumber%[1]s should not be used with the %[1]s--job%[1]s flag and will result in the
However, this %[1]s<number>%[1]s should not be used with the %[1]s--job%[1]s flag and will result in the
API returning %[1]s404 NOT FOUND%[1]s. Instead, you can get the correct job IDs using the following command:
%[1]sgh run view <run-id> --json jobs --jq '.jobs[] | {name, databaseId}'%[1]s.
gh run view <run-id> --json jobs --jq '.jobs[] | {name, databaseId}'
`, "`"),
Args: cobra.MaximumNArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {

View file

@ -40,7 +40,7 @@ func NewCmdCode(f *cmdutil.Factory, runF func(*CodeOptions) error) *cobra.Comman
<https://docs.github.com/search-github/searching-on-github/searching-code>
Note that these search results are powered by what is now a legacy GitHub code search engine.
The results might not match what is seen on GitHub.com, and new features like regex search
The results might not match what is seen on github.com, and new features like regex search
are not yet available via the GitHub API.
`),
Example: heredoc.Doc(`

View file

@ -39,9 +39,9 @@ func NewCmdDelete(f *cmdutil.Factory, runF func(*DeleteOptions) error) *cobra.Co
Short: "Delete secrets",
Long: heredoc.Doc(`
Delete a secret on one of the following levels:
- repository (default): available to Actions runs or Dependabot in a repository
- environment: available to Actions runs for a deployment environment in a repository
- organization: available to Actions runs, Dependabot, or Codespaces within an organization
- repository (default): available to GitHub Actions runs or Dependabot in a repository
- environment: available to GitHub Actions runs for a deployment environment in a repository
- organization: available to GitHub Actions runs, Dependabot, or Codespaces within an organization
- user: available to Codespaces for your user
`),
Args: cobra.ExactArgs(1),

View file

@ -52,9 +52,9 @@ func NewCmdList(f *cmdutil.Factory, runF func(*ListOptions) error) *cobra.Comman
Short: "List secrets",
Long: heredoc.Doc(`
List secrets on one of the following levels:
- repository (default): available to Actions runs or Dependabot in a repository
- environment: available to Actions runs for a deployment environment in a repository
- organization: available to Actions runs, Dependabot, or Codespaces within an organization
- repository (default): available to GitHub Actions runs or Dependabot in a repository
- environment: available to GitHub Actions runs for a deployment environment in a repository
- organization: available to GitHub Actions runs, Dependabot, or Codespaces within an organization
- user: available to Codespaces for your user
`),
Aliases: []string{"ls"},

View file

@ -13,12 +13,12 @@ func NewCmdSecret(f *cmdutil.Factory) *cobra.Command {
cmd := &cobra.Command{
Use: "secret <command>",
Short: "Manage GitHub secrets",
Long: heredoc.Doc(`
Long: heredoc.Docf(`
Secrets can be set at the repository, or organization level for use in
GitHub Actions or Dependabot. User, organization, and repository secrets can be set for
use in GitHub Codespaces. Environment secrets can be set for use in
GitHub Actions. Run "gh help secret set" to learn how to get started.
`),
GitHub Actions. Run %[1]sgh help secret set%[1]s to learn how to get started.
`, "`"),
}
cmdutil.EnableRepoOverride(cmd, f)

View file

@ -60,9 +60,9 @@ func NewCmdSet(f *cmdutil.Factory, runF func(*SetOptions) error) *cobra.Command
Short: "Create or update secrets",
Long: heredoc.Doc(`
Set a value for a secret on one of the following levels:
- repository (default): available to Actions runs or Dependabot in a repository
- environment: available to Actions runs for a deployment environment in a repository
- organization: available to Actions runs, Dependabot, or Codespaces within an organization
- repository (default): available to GitHub Actions runs or Dependabot in a repository
- environment: available to GitHub Actions runs for a deployment environment in a repository
- organization: available to GitHub Actions runs, Dependabot, or Codespaces within an organization
- user: available to Codespaces for your user
Organization and user secrets can optionally be restricted to only be available to

View file

@ -37,9 +37,9 @@ func NewCmdDelete(f *cmdutil.Factory, runF func(*DeleteOptions) error) *cobra.Co
Short: "Delete variables",
Long: heredoc.Doc(`
Delete a variable on one of the following levels:
- repository (default): available to Actions runs or Dependabot in a repository
- environment: available to Actions runs for a deployment environment in a repository
- organization: available to Actions runs or Dependabot within an organization
- repository (default): available to GitHub Actions runs or Dependabot in a repository
- environment: available to GitHub Actions runs for a deployment environment in a repository
- organization: available to GitHub Actions runs or Dependabot within an organization
`),
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
@ -126,7 +126,7 @@ func removeRun(opts *DeleteOptions) error {
if envName != "" {
fmt.Fprintf(opts.IO.Out, "%s Deleted variable %s from %s environment on %s\n", cs.SuccessIconWithColor(cs.Red), opts.VariableName, envName, target)
} else {
fmt.Fprintf(opts.IO.Out, "%s Deleted Actions variable %s from %s\n", cs.SuccessIconWithColor(cs.Red), opts.VariableName, target)
fmt.Fprintf(opts.IO.Out, "%s Deleted variable %s from %s\n", cs.SuccessIconWithColor(cs.Red), opts.VariableName, target)
}
}

View file

@ -41,9 +41,9 @@ func NewCmdList(f *cmdutil.Factory, runF func(*ListOptions) error) *cobra.Comman
Short: "List variables",
Long: heredoc.Doc(`
List variables on one of the following levels:
- repository (default): available to Actions runs or Dependabot in a repository
- environment: available to Actions runs for a deployment environment in a repository
- organization: available to Actions runs or Dependabot within an organization
- repository (default): available to GitHub Actions runs or Dependabot in a repository
- environment: available to GitHub Actions runs for a deployment environment in a repository
- organization: available to GitHub Actions runs or Dependabot within an organization
`),
Aliases: []string{"ls"},
Args: cobra.NoArgs,

View file

@ -53,9 +53,9 @@ func NewCmdSet(f *cmdutil.Factory, runF func(*SetOptions) error) *cobra.Command
Short: "Create or update variables",
Long: heredoc.Doc(`
Set a value for a variable on one of the following levels:
- repository (default): available to Actions runs or Dependabot in a repository
- environment: available to Actions runs for a deployment environment in a repository
- organization: available to Actions runs or Dependabot within an organization
- repository (default): available to GitHub Actions runs or Dependabot in a repository
- environment: available to GitHub Actions runs for a deployment environment in a repository
- organization: available to GitHub Actions runs or Dependabot within an organization
Organization variable can optionally be restricted to only be available to
specific repositories.
@ -219,7 +219,7 @@ func setRun(opts *SetOptions) error {
if envName != "" {
target += " environment " + envName
}
fmt.Fprintf(opts.IO.Out, "%s %s Actions variable %s for %s\n", cs.SuccessIcon(), result.Operation, result.Key, target)
fmt.Fprintf(opts.IO.Out, "%s %s variable %s for %s\n", cs.SuccessIcon(), result.Operation, result.Key, target)
}
return err

View file

@ -13,10 +13,10 @@ func NewCmdVariable(f *cmdutil.Factory) *cobra.Command {
cmd := &cobra.Command{
Use: "variable <command>",
Short: "Manage GitHub Actions variables",
Long: heredoc.Doc(`
Long: heredoc.Docf(`
Variables can be set at the repository, environment or organization level for use in
GitHub Actions or Dependabot. Run "gh help variable set" to learn how to get started.
`),
GitHub Actions or Dependabot. Run %[1]sgh help variable set%[1]s to learn how to get started.
`, "`"),
}
cmdutil.EnableRepoOverride(cmd, f)

View file

@ -53,18 +53,18 @@ func NewCmdRun(f *cmdutil.Factory, runF func(*RunOptions) error) *cobra.Command
cmd := &cobra.Command{
Use: "run [<workflow-id> | <workflow-name>]",
Short: "Run a workflow by creating a workflow_dispatch event",
Long: heredoc.Doc(`
Create a workflow_dispatch event for a given workflow.
Long: heredoc.Docf(`
Create a %[1]sworkflow_dispatch%[1]s event for a given workflow.
This command will trigger GitHub Actions to run a given workflow file. The given workflow file must
support a workflow_dispatch 'on' trigger in order to be run in this way.
support an %[1]son.workflow_dispatch%[1]s trigger in order to be run in this way.
If the workflow file supports inputs, they can be specified in a few ways:
- Interactively
- via -f or -F flags
- As JSON, via STDIN
`),
- Via %[1]s-f/--raw-field%[1]s or %[1]s-F/--field%[1]s flags
- As JSON, via standard input
`, "`"),
Example: heredoc.Doc(`
# Have gh prompt you for what workflow you'd like to run and interactively collect inputs
$ gh workflow run
@ -129,7 +129,7 @@ func NewCmdRun(f *cmdutil.Factory, runF func(*RunOptions) error) *cobra.Command
},
}
cmd.Flags().StringVarP(&opts.Ref, "ref", "r", "", "The branch or tag name which contains the version of the workflow file you'd like to run")
cmd.Flags().StringArrayVarP(&opts.MagicFields, "field", "F", nil, "Add a string parameter in `key=value` format, respecting @ syntax")
cmd.Flags().StringArrayVarP(&opts.MagicFields, "field", "F", nil, "Add a string parameter in `key=value` format, respecting @ syntax (see \"gh help api\").")
cmd.Flags().StringArrayVarP(&opts.RawFields, "raw-field", "f", nil, "Add a string parameter in `key=value` format")
cmd.Flags().BoolVar(&opts.JSON, "json", false, "Read workflow inputs as JSON via STDIN")