{"meta":{"title":"创建 GitHub CLI 扩展","intro":"了解如何通过为 GitHub CLI 创建自定义扩展程序与其他用户共享新的 GitHub CLI 命令。","product":"GitHub CLI","breadcrumbs":[{"href":"/zh/github-cli","title":"GitHub CLI"},{"href":"/zh/github-cli/github-cli","title":"GitHub CLI"},{"href":"/zh/github-cli/github-cli/creating-github-cli-extensions","title":"创建 GitHub CLI 扩展"}],"documentType":"article"},"body":"# 创建 GitHub CLI 扩展\n\n了解如何通过为 GitHub CLI 创建自定义扩展程序与其他用户共享新的 GitHub CLI 命令。\n\n## 关于 GitHub CLI 扩展\n\nGitHub CLI 扩展是自定义 GitHub CLI 命令，任何人都可以创建和使用。有关如何使用 GitHub CLI 扩展的详细信息，请参阅“[使用 GitHub 命令行工具 (CLI) 扩展](/zh/github-cli/github-cli/using-github-cli-extensions)”。\n\n对于您创建的每个扩展，都需要一个存储库。 存储库名称必须以 `gh-` 开头。 存储库名称的其余部分是扩展的名称。 存储库的根目录下必须有一个与存储库同名的可执行文件，或者附加到发行版的一组预编译二进制可执行文件。\n\n> \\[!NOTE]\n> 当依赖于可执行脚本时，我们建议使用 bash 脚本，因为 bash 是一种广泛使用的解释器。 您可以使用非 bash 脚本，但用户必须安装必要的解译程序才能使用扩展。 如果您不希望依赖安装了解译程序的用户，请考虑使用预编译扩展。\n\n## 使用 `gh extension create` 创建解译的扩展\n\n> \\[!NOTE]\n> 运行不带参数的 `gh extension create` 将启动交互式向导。\n\n可以使用 `gh extension create` 命令为扩展创建一个项目，其中包括一个包含一些初始代码的 bash 脚本。\n\n1. 使用 `gh extension create` 子命令设置新的扩展。 将 `EXTENSION-NAME` 替换为扩展的名称。\n\n   ```shell\n   gh extension create EXTENSION-NAME\n   ```\n\n2. 按照打印出的说明完成扩展，并可选择发布您的扩展。\n\n## 使用 Go 创建预编译扩展 `gh extension create`\n\n可以使用 `--precompiled=go` 参数为扩展创建基于 Go 的project，包括 Go 基架、工作流基架和初学者代码。\n\n1. 使用 `gh extension create` 子命令设置新的扩展。 将 `EXTENSION-NAME` 替换为扩展的名称并指定 `--precompiled=go`。\n\n   ```shell\n   gh extension create --precompiled=go EXTENSION-NAME\n   ```\n\n2. 按照打印出的说明完成扩展，并可选择发布您的扩展。\n\n## 使用 `gh extension create` 创建非 Go 预编译扩展\n\n可以使用 `--precompiled=other` 参数为非 Go 预编译扩展（包括工作流基架）创建项目。\n\n1. 使用 `gh extension create` 子命令设置新的扩展。 将 `EXTENSION-NAME` 替换为扩展的名称并指定 `--precompiled=other`。\n\n   ```shell\n   gh extension create --precompiled=other EXTENSION-NAME\n   ```\n\n2. 使用所选的编译语言为扩展添加一些初始代码。\n\n3. 在 `script/build.sh` 中填写代码以生成扩展，以确保可以自动生成扩展。\n\n4. 按照打印出的说明完成扩展，并可选择发布您的扩展。\n\n## 手动创建解释型扩展\n\n1. 为扩展创建一个名为 `gh-EXTENSION-NAME` 的本地目录。 将 `EXTENSION-NAME` 替换为扩展的名称。 例如 `gh-whoami`。\n\n2. 在您创建的目录中，添加与该目录同名的可执行文件。\n\n   > \\[!NOTE]\n   > 确保文件是可执行文件。 在 Unix 上，可以在命令行中执行 `chmod +x file_name` 以使 `file_name` 可执行。 在 Windows 上，可以运行 `git init -b main`、`git add file_name`，然后运行 `git update-index --chmod=+x file_name`。\n\n3. 在可执行文件中编写脚本。 例如：\n\n   ```bash\n   #!/usr/bin/env bash\n   set -e\n   exec gh api user --jq '\"You are @\\(.login) (\\(.name)).\"'\n   ```\n\n4. 从目录中，将扩展安装为本地扩展。\n\n   ```shell\n   gh extension install .\n   ```\n\n5. 验证您的扩展是否正常工作。 将 `EXTENSION-NAME` 替换为扩展的名称。 例如 `whoami`。\n\n   ```shell\n   gh EXTENSION-NAME\n   ```\n\n6. 从目录中，创建一个存储库以发布扩展。 将 `EXTENSION-NAME` 替换为扩展的名称。\n\n   ```shell\n   git init -b main\n   git add . && git commit -m \"initial commit\"\n   gh repo create gh-EXTENSION-NAME --source=. --public --push\n   ```\n\n7. （可选）为了帮助其他用户发现你的扩展，请添加存储库主题 `gh-extension`。 这会使扩展显示在 [`gh-extension` 主题页上](https://github.com/topics/gh-extension)。 有关如何添加存储库主题的详细信息，请参阅“[使用主题对仓库分类](/zh/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/classifying-your-repository-with-topics)”。\n\n## 编写解译型 GitHub CLI 扩展的提示\n\n### 处理参数和标志\n\n```\n          `gh my-extension-name` 命令之后的所有命令行参数都将传递给扩展脚本。 在 bash 脚本中，可以引用 `$1`、`$2` 等参数。可以使用参数来接受用户输入或修改脚本的行为。\n```\n\n例如，此脚本处理多个标志。 使用 `-h` 或 `--help` 标志调用脚本时，脚本将打印帮助文本，而不是继续执行。 使用 `--name` 标志调用脚本时，脚本会将标志后的下一个值设置为 `name_arg`。 使用 `--verbose` 标志调用脚本时，脚本将打印不同的问候语。\n\n```bash\n#!/usr/bin/env bash\nset -e\n\nverbose=\"\"\nname_arg=\"\"\nwhile [ $# -gt 0 ]; do\n  case \"$1\" in\n  --verbose)\n    verbose=1\n    ;;\n  --name)\n    name_arg=\"$2\"\n    shift\n    ;;\n  -h|--help)\n    echo \"Add help text here.\"\n    exit 0\n    ;;\n  esac\n  shift\ndone\n\nif [ -z \"$name_arg\" ]\nthen\n  echo \"You haven't told us your name.\"\nelif [ -z \"$verbose\" ]\nthen\n  echo \"Hi $name_arg\"\nelse\n  echo \"Hello and welcome, $name_arg\"\nfi\n```\n\n### 在非交互模式下调用核心命令\n\n某些 GitHub CLI 核心命令将提示用户输入。 使用这些命令编写脚本时，通常不需要提示。 为避免提示，请通过参数显式提供必要的信息。\n\n例如，要以编程方式创建问题，请指定标题和正文：\n\n```shell\ngh issue create --title \"My Title\" --body \"Issue description\"\n```\n\n### 以编程方式提取数据\n\n许多核心命令均支持 `--json` 标志，用于以编程方式提取数据。 例如，要返回其中列出拉取请求数量、标题和可合并性状态的 JSON 对象：\n\n```shell\ngh pr list --json number,title,mergeStateStatus\n```\n\n如果没有核心命令从GitHub提取特定数据，可以使用 [`gh api`](https://cli.github.com/manual/gh_api) 命令来访问GitHub API。 例如，要获取有关当前用户的信息，\n\n```shell\ngh api user\n```\n\n所有输出 JSON 数据的命令还具有将该数据筛选为脚本可以立即使用的数据的选项。 例如，要获取当前用户的名称：\n\n```shell\ngh api user --jq '.name'\n```\n\n有关详细信息，请参阅 [`gh help formatting`](https://cli.github.com/manual/gh_help_formatting)。\n\n## 手动创建预编译的扩展\n\n1. 为扩展创建一个名为 `gh-EXTENSION-NAME` 的本地目录。 将 `EXTENSION-NAME` 替换为扩展的名称。 例如 `gh-whoami`。\n\n2. 在您创建的目录中，添加一些源代码。 例如：\n\n   ```golang\n   package main\n   import (\n     \"github.com/cli/go-gh\"\n     \"fmt\"\n   )\n\n   func main() {\n     args := []string{\"api\", \"user\", \"--jq\", `\"You are @\\(.login) (\\(.name))\"` }\n     stdOut, _, err := gh.Exec(args...)\n     if err != nil {\n       fmt.Println(err)\n       return\n     }\n     fmt.Println(stdOut.String())\n   }\n   ```\n\n3. 从目录中，将扩展安装为本地扩展。\n\n   ```shell\n   gh extension install .\n   ```\n\n4. 生成代码。 例如，使用 Go，将 `YOUR-USERNAME` 替换为GitHub用户名：\n\n   ```shell\n   go mod init github.com/YOUR-USERNAME/gh-whoami\n   go mod tidy\n   go build\n   ```\n\n5. 验证您的扩展是否正常工作。 将 `EXTENSION-NAME` 替换为扩展的名称。 例如 `whoami`。\n\n   ```shell\n   gh EXTENSION-NAME\n   ```\n\n6. 从目录中，创建一个存储库以发布扩展。 将 `EXTENSION-NAME` 替换为扩展的名称。\n\n   > \\[!NOTE]\n   > 注意不要将编译步骤生成的二进制文件提交到版本控制中。\n\n   ```shell\n    git init -b main\n   echo \"gh-EXTENSION-NAME\" >> .gitignore\n   git add main.go go.* .gitignore && git commit -m 'Initial commit'\n   gh repo create \"gh-EXTENSION-NAME\"\n   ```\n\n7. 创建版本以与他人共享预编译的扩展。 针对要支持的每个平台进行编译，将每个二进制文件作为资产附加到发行版。 附加到发行版的二进制可执行文件必须遵循命名约定，并且具有 OS-ARCHITECTURE\\[EXTENSION] 的后缀。\n\n   例如，为 Windows 64 位编译的名为 `whoami` 的扩展将具有名称 `gh-whoami-windows-amd64.exe`，而为 Linux 32 位编译的同一扩展将具有名称 `gh-whoami-linux-386`。 若要查看由 `gh` 识别的 OS 和体系结构组合的详尽列表，请参阅[此源代码](https://github.com/cli/cli/blob/14f704fd0da58cc01413ee4ba16f13f27e33d15e/pkg/cmd/extension/manager.go#L696)。\n\n   > \\[!NOTE]\n   > 要使扩展在 Windows 上正常运行，其资产文件必须具有 `.exe` 扩展名。 其他操作系统不需要扩展。\n\n   可以从命令行创建发行版。 例如：\n\n   ```shell\n   git tag v1.0.0\n   git push origin v1.0.0\n   GOOS=windows GOARCH=amd64 go build -o gh-EXTENSION-NAME-windows-amd64.exe\n   GOOS=linux GOARCH=amd64 go build -o gh-EXTENSION-NAME-linux-amd64\n   GOOS=darwin GOARCH=amd64 go build -o gh-EXTENSION-NAME-darwin-amd64\n   gh release create v1.0.0 ./*amd64*\n\n   ```\n\n8. 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](https://github.com/topics/gh-extension). For more information about how to add a repository topic, see [Classifying your repository with topics](/zh/github/administering-a-repository/managing-repository-settings/classifying-your-repository-with-topics).\n\n## Tips for writing precompiled GitHub CLI extensions\n\n### Automating releases\n\nConsider adding the [gh-extension-precompile](https://github.com/cli/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.\n\n### Using GitHub CLI features from Go-based extensions\n\nConsider using [go-gh](https://github.com/cli/go-gh), a Go library that exposes pieces of `gh` functionality for use in extensions.\n\n## Next steps\n\nTo see more examples of GitHub CLI extensions, look at [repositories with the `gh-extension` topic](https://github.com/topics/gh-extension)."}