This version of GitHub Enterprise was discontinued on 2021-09-23. No patch releases will be made, even for critical security issues. For better performance, improved security, and new features, upgrade to the latest version of GitHub Enterprise. For help with the upgrade, contact GitHub Enterprise support.

Creating GitHub CLI extensions

Learn how to share new GitHub CLI commands with other users by creating custom extensions for GitHub CLI.

About GitHub CLI extensions

GitHub CLI extensions are custom GitHub CLI commands that anyone can create and use. For more information about how to use GitHub CLI extensions, see "Using GitHub CLI extensions."

You need a repository for each extension that you create. The repository name must start with gh-. The rest of the repository name is the name of the extension. At the root of the repository, there must be an executable file with the same name as the repository. This file will be executed when the extension is invoked.

Note: We recommend that the executable file is a bash script because bash is a widely available interpreter. You may use non-bash scripts, but the user must have the necessary interpreter installed in order to use the extension.

Creating an extension with gh extension create

You can use the gh extension create command to create a project for your extension, including a bash script that contains some starter code.

  1. Set up a new extension by using the gh extension create subcommand. Replace EXTENSION-NAME with the name of your extension.

    gh extension create EXTENSION-NAME
  2. Follow the printed instructions to finalize and optionally publish your extension.

Creating an extension manually

  1. Create a local directory called gh-EXTENSION-NAME for your extension. Replace EXTENSION-NAME with the name of your extension. For example, gh-whoami.

  2. In the directory that you created, add an executable file with the same name as the directory.

    Note: Make sure that your file is executable. On Unix, you can execute chmod +x file_name in the command line to make file_name executable. On Windows, you can run git init -b main, git add file_name, then git update-index --chmod=+x file_name.

  3. Write your script in the executable file. For example:

    #!/usr/bin/env bash
    set -e
    exec gh api user --jq '"You are @\(.login) (\(.name))."'
    
  4. From your directory, install the extension as a local extension.

    gh extension install .
    
  5. Verify that your extension works. Replace EXTENSION-NAME with the name of your extension. For example, whoami.

    gh EXTENSION-NAME
  6. From your directory, create a repository to publish your extension. Replace EXTENSION-NAME with the name of your extension.

    git init -b main
    gh repo create gh-EXTENSION-NAME --confirm
    git add . && git commit -m "initial commit" && git push --set-upstream origin main
  7. Optionally, to help other users discover your extension, add the repository topic gh-extension. This will make the extension appear on the gh-extension topic page. For more information about how to add a repository topic, see "Classifying your repository with topics."

Tips for writing GitHub CLI extensions

Handling arguments and flags

All command line arguments following a gh my-extension-name command will be passed to the extension script. In a bash script, you can reference arguments with $1, $2, etc. You can use arguments to take user input or to modify the behavior of the script.

For example, this script handles multiple flags. When the script is called with the -h or --help flag, the script prints help text instead of continuing execution. When the script is called with the --name flag, the script sets the next value after the flag to name_arg. When the script is called with the --verbose flag, the script prints a different greeting.

#!/usr/bin/env bash
set -e

verbose=""
name_arg=""
while [ $# -gt 0 ]; do
  case "$1" in
  --verbose)
    verbose=1
    ;;
  --name)
    name_arg="$2"
    shift
    ;;
  -h|--help)
    echo "Add help text here."
    exit 0
    ;;
  esac
  shift
done

if [ -z "$name_arg" ]
then
  echo "You haven't told us your name."
elif [ -z "$verbose" ]
then
  echo "Hi $name_arg"
else
  echo "Hello and welcome, $name_arg"
fi

Calling core commands in non-interactive mode

Some GitHub CLI core commands will prompt the user for input. When scripting with those commands, a prompt is often undesirable. To avoid prompting, supply the necessary information explicitly via arguments.

For example, to create an issue programmatically, specify the title and body:

gh issue create --title "My Title" --body "Issue description"

Fetching data programatically

Many core commands support the --json flag for fetching data programatically. For example, to return a JSON object listing the number, title, and mergeability status of pull requests:

gh pr list --json number,title,mergeStateStatus

If there is not a core command to fetch specific data from GitHub, you can use the gh api command to access the GitHub API. For example, to fetch information about the current user:

gh api user

All commands that output JSON data also have options to filter that data into something more immediately usable by scripts. For example, to get the current user's name:

gh api user --jq '.name'

For more information, see gh help formatting.

Next steps

To see more examples of GitHub CLI extensions, look at repositories with the gh-extension topic.