跳至主要内容

创建 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 main`、`git 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] 后缀。

    例如,名为 `whoami` 并针对 Windows 64 位编译的扩展将名为 `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. 可选地,为了帮助其他用户发现您的扩展,请添加存储库主题 `gh-extension`。这将使扩展出现在 `gh-extension` 主题页面 上。有关如何添加存储库主题的更多信息,请参阅“使用主题对存储库进行分类”。

编写预编译 GitHub CLI 扩展的技巧

自动化发行版

考虑将 gh-extension-precompile 操作添加到项目中的工作流中。此操作将自动为您的扩展生成交叉编译的 Go 二进制文件,并为非 Go 预编译扩展提供构建脚手架。

从基于 Go 的扩展中使用 GitHub CLI 功能

考虑使用 go-gh,这是一个 Go 库,它公开了 `gh` 功能的部分内容,可在扩展中使用。

后续步骤

要查看更多 GitHub CLI 扩展示例,请查看 具有 `gh-extension` 主题的存储库