下载安卓APP箭头
箭头给我发消息

客服QQ:3315713922

云原生小技巧 : 如何自动化发布 CLI 工具?

作者:匿名     来源: 云计算点击数:269发布时间: 2023-12-06 16:24:07

标签: CLI工具

  在自动化构建的世界中,编写一个稳定且跨平台兼容的构建脚本是关键。Golang 提供了强大的跨平台构建能力,而 go build 命令是实现这一目标的核心。

  在云原生时代,CLI 工具已成为开发者日常工作中不可或缺的一部分。然而,将开发好的 CLI 工具分享给大家使用,如果仅依赖手动发布,不仅效率低,且易出错,特别是在处理多架构和多平台兼容性时尤为明显。

  那么,我们如何才能实现 CLI 工具的自动化发布呢?本文旨在探讨这一问题,并提出一套实用的解决方案。

  在接下来的分享中,我将主要以 Golang 举例。需要指出的是,我们将讨论的自动化构建和发布的原则是通用的,适用于所有编程语言。因此,无论大家使用哪种语言编写工具,这些实践都将具有重要的参考价值。

  编写构建脚本

  在自动化构建的世界中,编写一个稳定且跨平台兼容的构建脚本是关键。Golang 提供了强大的跨平台构建能力,而 go build 命令是实现这一目标的核心。例如:

  复制

  1.  CGO_ENABLED=0 GOOS=darwin GOARCH=amd64 go build -o fooctl-darwin-amd64 -v

  这个命令示例突显了 Golang 在生成特定平台和架构二进制文件方面的灵活性。在构建脚本中,我们需要进一步扩展这种灵活性,以支持多平台构建需求。

  1.参数化和默认值设置:

  OUTPUT_DIR 和 BINARY_NAME 的设定允许用户自定义输出目录和二进制文件的名称,加强了脚本的通用性。

  BUILDPATH 变量用于指定构建路径,是脚本运行的必需参数,保证了构建过程的稳定性。

  2.跨平台和架构支持:

  通过设置 BUILD_GOOS 和 BUILD_GOARCH 变量,脚本能够灵活地处理不同操作系统和架构的构建需求,增加了适用性。

  这些变量的默认值通过 go env 获取,但也可以通过参数覆盖,提供了灵活性。

  3.动态输出路径:

  OUT 变量根据是否为发布版(IS_RELEASE),动态调整输出文件的命名和路径。这样的设计使得脚本能够根据不同的使用场景(如开发测试或正式发布)输出不同格式的文件名。

  4.特殊情况处理:

  对 Windows 平台的特殊处理(.exe 扩展名)是必要的,因为 Windows 系统下的可执行文件通常需要这个扩展名。

  gobuild.sh 脚本

  下面的 gobuild.sh 脚本是对上述原则的实践,将跨平台构建的复杂性转化为简单的命令行操作:

  复制

  1.  OUTPUT_DIR=${4:-"bin"}

  2.  BINARY_NAME=$(basename ${1})

  3.  BUILDPATH=./${1:?"path to build"}

      4.

  5.  BUILD_GOOS=${GOOS:-$(go env GOOS)}

  6.  BUILD_GOARCH=${GOARCH:-$(go env GOARCH)}

  7.  GOBINARY=${GOBINARY:-go}      

  8.   LDFLAGS=$(version::ldflags)

      9.

  10.  if [ $# -ge 2 ] && [ -n $2 ]; then

  11.  BUILD_GOOS=$2

  12.  fi

      13.

  14.  if [ $# -ge 3 ] && [ -n $3 ]; then

  15.  BUILD_GOARCH=$3

  16.  fi

      17.

  18.  OUT=${OUTPUT_DIR}/${1:?"output path"}

  19.  if [ "${IS_RELEASE:-0}" == "1" ]; then

  20.  OUT="${OUTPUT_DIR}/${BINARY_NAME}-${BUILD_GOOS}-${BUILD_GOARCH}"

  21.  if [ "${BUILD_GOOS}" == "windows" ]; then

  22.  OUT="${OUTPUT_DIR}/${BINARY_NAME}-${BUILD_GOOS}-${BUILD_GOARCH}.exe"

  23.  fi

  24.  fi

      25.

  26.  CGO_ENABLED=0 GOOS=${BUILD_GOOS} GOARCH=${BUILD_GOARCH}${GOBINARY} build \\

  27.  -ldflags="${LDFLAGS}" \\

  28.  -o "${OUT}" \\

  29.  "${BUILDPATH}"

  这个脚本不仅适应了多平台和多架构的需要,还提供了足够的灵活性和可配置性,以适应不同的构建场景。

  配合 Makefile 实现全自动化构建

  进一步的,结合 Makefile 可以将构建过程自动化,提升效率:

  复制

  1.  .PHONY: build-binaries

      2.

  3.  BUILD_SCRIPT_PATH := ./hack/gobuild/gobuild.sh

  4.  # 列出了需要构建的所有二进制文件,可管理多个项目的构建过程

  5.  BINARIES := cmd/fooctl cmd/barctl

      6.

  7.  # 通过 ALLPLATFORMS 变量,我们定义了一系列目标平台和架构组合

  8.  ALLPLATFORMS := linux/amd64 linux/arm64 darwin/amd64 darwin/arm64 windows/amd64 windows/arm64

      9.

  10.  # 构建所有组合

  11.  build-binaries: $(foreach bin,$(BINARIES),$(foreach plat,$(ALLPLATFORMS),build-$(bin)-$(plat)))

      12.

  13.  # 构建规则模板

  14.  # 这个模板可以生成特定于每个二进制文件和平台组合的构建规则。

  15.  define BUILD_template

  16.  build-$(1)-$(2):

  17.  IS_RELEASE=1 $$(BUILD_SCRIPT_PATH) $(1) $$(subst /, ,$$(word 1,$$(subst -, ,$(2)))) $$(subst /, ,$$(word 2,$$(subst -, ,$(2))))

  18.  endef

      19.

  20.  # 生成构建规则

  21.  # 我们自动为每个二进制文件和平台组合生成了具体的构建规则。

  22.  $(foreach bin,$(BINARIES),$(foreach plat,$(ALLPLATFORMS),$(eval $(call BUILD_template,$(bin),$(plat)))))

  通过这个 Makefile,即使同时构建 fooctl 和 barctl 这两个 CLI Tool 也变得异常简单。一条简单的命令 make build-binaries 就能触发整个构建流程,大大减少了人工干预,确保了构建过程的一致性和可靠性。

  小结

  通过上述详细的构建脚本和 Makefile 配置,我们可以看到,现代软件开发中自动化构建的强大功能和必要性。这种方法不仅提升了构建效率,也增强了软件的质量和稳定性。在云原生时代,自动化构建已成为提高开发团队效率和产品可靠性的关键策略。

  Release CLI tool on GitLab CI/CD

  在构建脚本准备完毕后,接下来我们就可以将其集成到 CI 系统了,下面我以 GitLab CI/CD 为例。

  在 GitLab CI/CD 的核心,是一系列定义明确的作业(Jobs),它们在代码提交时自动执行。对于完整的持续集成来说,这些作业通常包括构建(build)、测试(test)、代码审查(lint)等步骤。但在本文中,我们将重点关注自动发布流程。

  触发自动发布的条件

  自动发布流程是基于 Git 标签创建的。当开发者推送一个新标签到仓库时,GitLab CI/CD 会捕捉到这一事件,并启动预定义的发布流程。

  复制

  1.  rules:

  2.  - if: $CI_COMMIT_TAG

  这个条件确保只有在创建新标签时,才会启动后续的构建、上传和发布作业。

  Release Jobs

  步骤一:构建二进制文件,在 build-binaries 阶段,CI 会构建针对不同平台和架构的 CLI 工具二进制文件,确保构建过程的一致性和可重复性。

  步骤二:上传构建产物,待构建完成后,upload 阶段负责将二进制文件上传到 GitLab 的包管理器或其他存储位置。这为后续的发布提供了必要的资源。

  步骤三: 发布到 GitLab,最后,在 release 阶段,CI 使用 release-cli 工具自动创建发布,并将构建的二进制文件作为发布的资产。

  Create releases from .gitlab-ci.yml

  下面的 .gitlab-ci.yml 脚本是对上述发布流程的实践:

  复制

  1.  stages:

  2.  ...

  3.  - build-binaries

  4.  - upload

  5.  - release

      6.

  7.  build-binaries:

  8.  stage: build-binaries

  9.  image: golang:1.21.1

  10.  rules:

  11.  - if: $CI_COMMIT_TAG

  12.  script:

  13.  - echo "Building binaries for all platforms and architectures..."

  14.  - make build-binaries

  15.  artifacts:

  16.  paths:

  17.  - bin

      18.

  19.  upload:

  20.  stage: upload

  21.  image: curlimages/curl:latest

  22.  rules:

  23.  - if: $CI_COMMIT_TAG

  24.  script:

  25.  - echo "Uploading binaries..."

  26.  - >

  27.  for binary in ./bin/*; do

  28.  curl --header "JOB-TOKEN: $CI_JOB_TOKEN" \\

  29.  --upload-file $binary \\

  30.  "${PACKAGE_REGISTRY_URL}/$(basename $binary)";

  31.  done

      32.

  33.  release:

  34.  stage: release

  35.  image: registry.gitlab.com/gitlab-org/release-cli:latest

  36.  rules:

  37.  - if: $CI_COMMIT_TAG

  38.  script:

  39.  - echo "Creating a release for $CI_COMMIT_TAG"

  40.  - |

  41.  ASSET_LINKS=""

  42.  for binary in ./bin/*; do

  43.  LINK="{\\"name\\":\\"$(basename $binary)\\", \\"url\\":\\"${PACKAGE_REGISTRY_URL}/$(basename $binary)\\"}"

  44.  ASSET_LINKS="${ASSET_LINKS},${LINK}"

  45.  done

  46.  ASSET_LINKS="[${ASSET_LINKS:1}]"

  47.  - >

  48.  release-cli create \\

  49.  --name "Release $CI_COMMIT_TAG" \\

  50.  --tag-name $CI_COMMIT_TAG \\

  51.  --description "Created using the release-cli: $CI_COMMIT_REF_NAME-$CI_JOB_ID" \\

  52.  --ref $CI_COMMIT_SHA \\

  53.  --assets-link "$ASSET_LINKS"

  以上示例将会构建 CLI 工具二进制文件,并将其上传到 Gitlab Release 页面。用户从 Gitlab Release 页面查找并下载适合其平台的二进制包即可。

  

图片

  有关详细的 GitLab CI 流程,可以参考项目:https://gitlab.com/lqshow/clireleaseautomator

  小结

  这个流程大大简化了 CLI 工具的发布过程,使得开发者能够专注于代码开发,而不是后续的构建和发布环节。自动化这些步骤意味着每次发布都是快速、一致且无误的,从而提高了软件的整体质量和可靠性。

  Release CLI tool use GoReleaser

  不难发现,上述整个流程相对来说还是比较繁琐的,准备脚本的过程也比较复杂,现在我将介绍一个让这个过程不那么痛苦的工具 GoReleaser[1]。

  它是一个变革性的工具,特别是对于以 Golang 编写的项目。相比于传统的手动配置和脚本编写,GoReleaser 提供了一种更高效和简洁的自动化发布方法。

  GoReleaser 的优势

  GoReleaser 的设计理念是“一次配置,处处运行”,它通过一个单一的配置文件,即可控制整个发布流程。这个配置文件定义了如何构建二进制文件、如何打包它们、如何处理版本信息以及如何发布到各种平台。具体来说,GoReleaser 的优势包括:

  简化的构建过程:通过预定义的模板,GoReleaser 能够自动构建针对不同平台和架构的二进制文件,无需编写复杂的脚本。

  灵活的打包和发布:支持多种格式的打包选项,以及与主要代码托管平台的无缝集成。

  高度可配置:从构建选项到发布设置,GoReleaser 允许高度定制化,以满足不同项目的需求。

  配置和使用 GoReleaser

  使用 GoReleaser 的第一步是在项目的根目录下创建 .goreleaser.yml 配置文件。通过 goreleaser init 命令可快速生成初始配置。这个文件涵盖了构建、打包和发布的全过程。

  在配置好 .goreleaser.yml 之后,我们需要调整 .gitignore 加上 dist,因为 goreleaser 会默认把编译编译好的文件输出到 dist 目录中。

  接下来我们看个例子:

  复制

  1.  # .goreleaser.yml 示例

  2.  builds:

  3.  - id: fooctl

  4.  binary: fooctl

  5.  main: ./cmd/fooctl

  6.  ldflags:

  7.  - -s -w

  8.  - -X gitlab.com/lqshow/clireleaseautomator-with-goreleaser/version.gitVersinotallow={{.Version}}

  9.  - -X gitlab.com/lqshow/clireleaseautomator-with-goreleaser/version.gitCommit={{.ShortCommit}}

  10.  goos:

  11.  - linux

  12.  - darwin

  13.  - windows

  14.  goarch:

  15.  - amd64

  16.  - arm64

  17.  - id: barctl

  18.  binary: barctl

  19.  main: ./cmd/barctl

  20.  ldflags:

  21.  - -s -w

  22.  - -X gitlab.com/lqshow/clireleaseautomator-with-goreleaser/version.gitVersinotallow={{.Version}}

  23.  - -X gitlab.com/lqshow/clireleaseautomator-with-goreleaser/version.gitCommit={{.ShortCommit}}

  24.  goos:

  25.  - linux

  26.  - darwin

  27.  - windows

  28.  goarch:

  29.  - amd64

  30.  - arm64

  这个简单清晰的配置文件,事实上包含了我之前介绍的两个模块,相当于省去了写 shell 脚本和 Makefile 文件,使整个过程更加灵活和高效。

  GitLab CI 中的 GoReleaser 集成

  在 .gitlab-ci.yml 文件中,我们只需要定义一个简单的 release 作业,对了,别忘了还需要在 CI/CD 里配置一个 GTILAB_TOKEN 变量:

  复制

  1.  stages:

  2.  - release

      3.

  4.  release:

  5.  stage: release

  6.  image:

  7.  name: goreleaser/goreleaser

  8.  entrypoint: ['']

  9.  only:

  10.  - tags

  11.  variables:

  12.  GIT_DEPTH: 0

  13.  GITLAB_TOKEN: $GITLAB_TOKEN

  14.  script:

  15.  - goreleaserrelease--clean

  只要查看运行日志,其实我们就会发现,GoReleaser 自动执行后,它包含了构建、上传和发布的整个流程。

  具体详情:https://gitlab.com/lqshow/clireleaseautomator-with-goreleaser/-/jobs/5669211977

  来源: Cloud Native 101

    >>>>>>点击进入计算专题

赞(8)
踩(0)
分享到:
华为认证网络工程师 HCIE直播课视频教程