首页 >后端开发 >Golang >发布 CLI 应用程序(使用 Apt 和 YUM)

发布 CLI 应用程序(使用 Apt 和 YUM)

Susan Sarandon
Susan Sarandon原创
2024-10-05 06:10:30885浏览

Publishing CLI Apps (with Apt & YUM)

简介

最近我已经成为 CLI 应用程序的忠实粉丝。也许这是我童年时期终端的诱惑(从 486/33 上的 DOS 和我父亲的旧 Apple IIe 开始)。对于 X 代 Commodore64 时代,我出生得有点晚,但正好赶上了了解 Windows 95 之外的更多内容。那是一个有趣的时代,当时拨号和 56k 调制解调器还是王者。我知道现在大多数博客文章都有一些介绍性的内容,以增加 SEO 的字数,但这确实是为什么我仍然喜欢 CLI,因为现在很多年轻人只知道 GUI 应用程序。没有什么比看到 Z 世代的孩子打开终端更让我高兴的了,即使是为了简单的任务。伙计,等阿尔法一代知道什么是 BBS 吧。他们可能会说“电脑爷爷”? “离开我的草坪”✊✊

像 CoolRetroTerm 这样的项目在我心中肯定有一个温暖的地方,因为它带回了对 CLI 的热爱。我仍然更喜欢在我的旧上网本上用 Micro 写一些博客,真的让你专注于写作。我猜 VSCode ZenMode 和 MarkText 很接近?


flowchart LR
Build_App --> GH_Actions --> ??? --> Profit!!!



包装

无论如何,我离题了......

所以在编写我的小 CLI 应用程序 Stampy 后,我遇到了一个小问题,如何分发它?我至少足够聪明,能够思考并用 GoLang 编写它(就像我想用 Python 构建它一样)以避免 Python 包装的可怕愤怒。一直困扰我的一件事是,人们如何将他们漂亮的 CLI 应用程序发布到 APT 和 YUM 等精美的包管理系统。

通常要构建您的应用程序,您只需执行简单的 go build 即可。和繁荣,即时二进制。尽管这对于本地开发来说非常有用,但对于跨平台编译却没有多大好处。有一些很好的指南可以向您展示如何做到这一点,但是... tl;dr 我的??。所以我做了更多的挖掘,必须有一个不错的工具......当然,有 GoReleaser!

阅读了一些写得很好的文档后,我能够快速进行本地跨平台构建,非常简单。


goreleaser --snapshot --clean



使用 GitHub 版本进行构建也很容易,因为它们有很好的预先编写的 GH 操作!

用户现在只需使用 eget(好)和 Steute(更好)等工具安装我的应用程序即可!

虽然您也可以安装 github.com/xxx,但所有要做的就是克隆存储库,在本地构建它,然后将 bin 放入您的 $GOBIN 文件夹中。与正确的包管理工具并不完全相同,但对于已经安装了 Go 的人来说确实可以工作。恕我直言,对于普通用户来说这并不是一个真正的选择。 ?

不仅如此,GoReleaser 还提供包装!现在您可以轻松制作 DEB 和 RPM。我离害怕的 apt-get install stampy 又近了一步。唯一缺少的是如何创建 APT 存储库。这最后一个关键部分肯定并不容易。我花了一个小时左右的时间研究如何使用 GitHub Pages 自行托管它,虽然这是可行的,但使用像 Packagecloud 这样的免费服务来处理签名和存储库托管要容易得多,而且成本低廉,每次 0 美元月?.

您可以在此处查看整个工作流程的示例

我还将在代码块中包含它的精简版本,供任何偶然发现博客文章本身的人使用。

为了获得高层次的概述,GHA 执行以下操作:

  • 写出 GoReleaser 配置
  • 运行发布器本身
  • 上传下一个作业的 .debs
  • 在链式作业中,我们拉取 .deb 并将其上传到 PackageCloud
  • 完成!

GitHub 操作示例


name: Release

on:
  pull_request:
  push:
    # run only against tags
    tags:
      - "*"

permissions:
  contents: write
  packages: write
  issues: write

jobs:
  goreleaser:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4
        with:
          fetch-depth: 0
      - name: Set up Go
        uses: actions/setup-go@v5
        with:
          go-version: stable

      - name: Release config
        run: |
          cat << EOF > /tmp/goreleaser-github.yaml
          project_name: EXAMPLE
          version: 2
          builds:
            - env: [CGO_ENABLED=0]
              goos:
                - linux
              goarch:
                - amd64
          nfpms:
            -
              maintainer: YOU <your@email.com>
              bindir: /usr/local/bin
              description: Copy formatted timestamp to system clipboard
              homepage: https://github.com/USERNAME/REPO
              license: MIT
              formats:
                - deb

          release:
            draft: false # If set to true, will not auto-publish the release.
            replace_existing_draft: true
            replace_existing_artifacts: true
            target_commitish: "{{ .Commit }}"
            prerelease: auto
            make_latest: true
            mode: replace
            include_meta: true
          EOF          

      - name: Run GoReleaser
        uses: goreleaser/goreleaser-action@v6
        with:
          distribution: goreleaser
          # 'latest', 'nightly', or a semver
          version: "~> v2"
          args: release --clean --verbose --config /tmp/goreleaser-github.yaml
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

      - name: Upload .deb artifact x86
        uses: actions/upload-artifact@v3
        with:
          name: deb-package
          path: dist/*amd64.deb

  pkgcld_amd64-deb:
    runs-on: ubuntu-latest
    needs:
      - goreleaser
    strategy:
      max-parallel: 3
      matrix:
        distro:
        - debian/bookworm
        - ubuntu/noble
        - ubuntu/jammy
    steps:
      - name: Download .deb artifact
        uses: actions/download-artifact@v3
        with:
          name: deb-package

      - name: Push package to packagecloud.io
        uses: computology/packagecloud-github-action@v0.6
        with:
          package-name: ./*.deb
          packagecloud-username: USERNAME
          packagecloud-reponame: APP_NAME
          packagecloud-distro: ${{ matrix.distro }}
          packagecloud-token: ${{ secrets.PACKAGECLOUD_TOKEN }}




ℹ️重要

您需要确保程序结构和 go.mod 文件等内容正确设置,否则您将在正确发布应用程序时遇到问题。

旁注:您还可以使用 Homebrew 分发您的应用程序,但我没有打扰,因为涉及 PAT 秘密的额外 GH 操作复杂性以及我已经很好地覆盖了 Apt好吃,还有炖菜…好吃! ?

这让我想到了发布应用程序时的第二件事。 ?文档? ​​以及备受忽视的 Readme.md?!

自述文件格式

我认为任何像样的自述文件都应该具有一些元素,因为它们将帮助您的应用程序从所有几乎没有文档,或者更糟糕的是,糟糕的文档的应用程序中脱颖而出。

我强烈建议您遵循这种格式来制作您自己的自述文件!我是天赋徽章的忠实粉丝,但我觉得有一个 GIF 演示确实可以向人们展示它的含义,就像列出 GUI 应用程序的 屏幕截图 一样。使用 ASCIINEMA 非常简单,而且他们还有一个很好的 GIF 转换器,让一切看起来都恰到好处。

?提示

顺便说一句,我确实让 CodeGPT 给我写了一些 GoLang 单元测试,我知道编写这些测试通常很痛苦。如果您使用 JetBrains 套件,这是一个很棒的插件。

自述文件示例

  • 测试徽章
  • GIF 演示
  • 覆盖徽章
  • 去报告卡
  • 安装
    • 包管理器(ex apt)
    • 二进制安装(例如 eget)
    • 去安装片段
  • 用法
    • 清晰的说明和示例代码片段
  • 设置
    • 保存设置的位置
    • 你使用 INI 文件、JSON、环境变量吗?
  • 如何访问内置帮助
  • 如何从源代码构建应用程序
  • 现有艺术(又名以前的作品/灵感)

包起来

与我开始学习如何发布 Python 应用程序时类似,我很高兴能够说我觉得我可以正确分发我在 GoLang 中编写的任何应用程序。这是我学到的一项巧妙的技能,通过这篇博文,我希望它可以帮助其他人做同样的事情!干杯!

-果冻


?乳齿象 | ?电子邮件 | ?评论 | ☕ 给我买杯咖啡

以上是发布 CLI 应用程序(使用 Apt 和 YUM)的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn