Skip to main content

创建 GitHub CLI 扩展

了解如何通过为 GitHub CLI 创建自定义扩展程序与其他用户共享新的 GitHub CLI 命令。

关于 GitHub CLI 扩展

GitHub CLI 扩展是自定义 GitHub CLI 命令,任何人都可以创建和使用。有关如何使用 GitHub CLI 扩展的详细信息,请参阅“使用 GitHub CLI 扩展”。

对于您创建的每个扩展,都需要一个存储库。 存储库名称必须以 gh- 开头。 存储库名称的其余部分是扩展的名称。 存储库的根目录下必须有一个与存储库同名的可执行文件,或者附加到发行版的一组预编译二进制可执行文件。

注意:当依赖于可执行脚本时,我们建议使用 bash 脚本,因为 bash 是一种广泛使用的解释器。 您可以使用非 bash 脚本,但用户必须安装必要的解译程序才能使用扩展。 如果您不希望依赖安装了解译程序的用户,请考虑使用预编译扩展。

使用 gh extension create 创建解译的扩展

注意:运行不带参数的 gh extension create 将启动交互式向导。

可以使用 gh extension create 命令为扩展创建一个项目,包括包含一些起始代码的 bash 脚本。

  1. 使用 gh extension create 子命令设置新的扩展。 将 EXTENSION-NAME 替换为扩展的名称。

    gh extension create EXTENSION-NAME
    
  2. 按照打印的说明完成扩展并选择性地发布扩展。

使用 gh extension create 采用 Go 创建预编译扩展

可以使用 --precompiled=go 参数为扩展创建基于 Go 的项目,包括 Go 基架、工作流基架和起始代码。

  1. 使用 gh extension create 子命令设置新的扩展。 将 EXTENSION-NAME 替换为扩展的名称并指定 --precompiled=go

    gh extension create --precompiled=go EXTENSION-NAME
    
  2. 按照打印的说明完成扩展并选择性地发布扩展。

使用 gh extension create 创建非 Go 预编译扩展

可以使用 --precompiled=other 参数为非 Go 预编译扩展(包括工作流基架)创建项目。

  1. 使用 gh extension create 子命令设置新的扩展。 将 EXTENSION-NAME 替换为扩展的名称并指定 --precompiled=other

    gh extension create --precompiled=other EXTENSION-NAME
    
  2. 使用所选的编译语言为扩展添加一些初始代码。

  3. script/build.sh 中填写代码以生成扩展,以确保可以自动生成扩展。

  4. 按照打印的说明完成扩展并选择性地发布扩展。

手动创建解译的扩展

  1. 为扩展创建一个名为 gh-EXTENSION-NAME 的本地目录。 将 EXTENSION-NAME 替换为扩展的名称。 例如 gh-whoami

  2. 在您创建的目录中,添加与该目录同名的可执行文件。

    注意: 请确保你的文件是可执行的。 在 Unix 上,可以在命令行中执行 chmod +x file_name 以使 file_name 可执行。 在 Windows 上,可以运行 git init -b maingit add file_name,然后运行 git update-index --chmod=+x file_name

  3. 在可执行文件中编写脚本。 例如:

    #!/usr/bin/env bash
    set -e
    exec gh api user --jq '"You are @\(.login) (\(.name))."'
    
  4. 从目录中,将扩展安装为本地扩展。

    gh extension install .
    
  5. 验证您的扩展是否正常工作。 将 EXTENSION-NAME 替换为扩展的名称。 例如 whoami

    gh EXTENSION-NAME
    
  6. 从目录中,创建一个存储库以发布扩展。 将 EXTENSION-NAME 替换为扩展的名称。

    git init -b main
    git add . && git commit -m "initial commit"
    gh repo create gh-EXTENSION-NAME --source=. --public --push
    
  7. (可选)为了帮助其他用户发现你的扩展,请添加存储库主题 gh-extension。 这将使扩展显示在 gh-extension 主题页上。 有关如何添加存储库主题的详细信息,请参阅“使用主题对仓库分类”。

编写解译型 GitHub CLI 扩展的提示

处理参数和标志

gh my-extension-name 命令之后的所有命令行参数都将传递给扩展脚本。 在 bash 脚本中,可以引用 $1$2 等参数。可以使用参数来接受用户输入或修改脚本的行为。

例如,此脚本处理多个标志。 使用 -h--help 标志调用脚本时,脚本将打印帮助文本,而不是继续执行。 使用 --name 标志调用脚本时,脚本会将标志后的下一个值设置为 name_arg。 使用 --verbose 标志调用脚本时,脚本将打印不同的问候语。

#!/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

在非交互模式下调用核心命令

某些 GitHub CLI 核心命令将提示用户输入。 使用这些命令编写脚本时,通常需要提示。 为避免提示,请通过参数显式提供必要的信息。

例如,要以编程方式创建问题,请指定标题和正文:

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

以编程方式提取数据

许多核心命令均支持 --json 标志,用于以编程方式提取数据。 例如,要返回其中列出拉取请求数量、标题和可合并性状态的 JSON 对象:

gh pr list --json number,title,mergeStateStatus

如果没有从 GitHub 提取特定数据的核心命令,则可以使用 gh api 命令来访问 GitHub API。 例如,要获取有关当前用户的信息,

gh api user

所有输出 JSON 数据的命令还具有将该数据筛选为脚本可以立即使用的数据的选项。 例如,要获取当前用户的名称:

gh api user --jq '.name'

有关详细信息,请参阅 gh help formatting

手动创建预编译的扩展

  1. 为扩展创建一个名为 gh-EXTENSION-NAME 的本地目录。 将 EXTENSION-NAME 替换为扩展的名称。 例如 gh-whoami

  2. 在您创建的目录中,添加一些源代码。 例如:

    package main
    import (
      "github.com/cli/go-gh"
      "fmt"
    )
    
    func main() {
      args := []string{"api", "user", "--jq", `"You are @\(.login) (\(.name))"` }
      stdOut, _, err := gh.Exec(args...)
      if err != nil {
        fmt.Println(err)
        return
      }
      fmt.Println(stdOut.String())
    }
    
  3. 从目录中,将扩展安装为本地扩展。

    gh extension install .
    
  4. 生成代码。 例如,使用 Go,将 YOUR-USERNAME 替换为你的 GitHub 用户名:

    go mod init github.com/YOUR-USERNAME/gh-whoami
    go mod tidy
    go build
    
  5. 验证您的扩展是否正常工作。 将 EXTENSION-NAME 替换为扩展的名称。 例如 whoami

    gh EXTENSION-NAME
    
  6. 从目录中,创建一个存储库以发布扩展。 将 EXTENSION-NAME 替换为扩展的名称。

    注意: 注意不要将编译步骤生成的二进制文件提交到版本控制中。

     git init -b main
    echo "gh-EXTENSION-NAME" >> .gitignore
    git add main.go go.* .gitignore && git commit -m 'Initial commit'
    gh repo create "gh-EXTENSION-NAME"
    
  7. 创建版本以与他人共享预编译的扩展。 针对要支持的每个平台进行编译,将每个二进制文件作为资产附加到发行版。 附加到发行版的二进制可执行文件必须遵循命名约定,并且具有 OS-ARCHITECTURE[EXTENSION] 的后缀。

    例如,为 Windows 64 位编译的名为 whoami 的扩展将具有名称 gh-whoami-windows-amd64.exe,而为 Linux 32 位编译的同一扩展将具有名称 gh-whoami-linux-386。 若要查看 gh 识别的 OS 和体系结构组合的详尽列表,请参阅此源代码

    注意: 要使扩展在 Windows 上正常运行,其资产文件必须具有 .exe 扩展名。 其他操作系统不需要扩展。

    可以从命令行创建版本。 例如:

    git tag v1.0.0
    git push origin v1.0.0
    GOOS=windows GOARCH=amd64 go build -o gh-EXTENSION-NAME-windows-amd64.exe
    GOOS=linux GOARCH=amd64 go build -o gh-EXTENSION-NAME-linux-amd64
    GOOS=darwin GOARCH=amd64 go build -o gh-EXTENSION-NAME-darwin-amd64
    gh release create v1.0.0 ./*amd64*
    
    
  8. 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 precompiled GitHub CLI extensions

Automating releases

Consider adding the gh-extension-precompile action to a workflow in your project. This action will automatically produce cross-compiled Go binaries for your extension and supplies build scaffolding for non-Go precompiled extensions.

Using GitHub CLI features from Go-based extensions

Consider using go-gh, a Go library that exposes pieces of gh functionality for use in extensions.

Next steps

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