在Duro,我和我的团队制作了一个甜蜜的CLI工具,使我们可以快速,轻松地为我们的平台创建微服务。该工具为打字稿,覆盖,与我们共享的库集成以及将服务推向云的特定操作设置标准服务配置。拥有真是太好了。
我们不断调整它,修复小东西并改变我们的配置。我们决定使用GoReleaser帮助我们版本版本并创建二进制文件并将其发布到GitHub。太棒了。
直到我们必须分发它。
修订开始增加,这是一个麻烦,试图确保您拥有该工具的最新版本。本着“完成工作”的精神,我们只是让每个人都下载并在完成后将其删除。这不是一个很好的解决方案,但是,嘿,我们还有更多的事情要担心。
最近,我决定自己向这种工具展示一些爱(与我的Devs同行的咖喱偏爱),以尝试通过Homebrew来管理此工具的版本。我不知道自制酿造的内部工作,所以我决定挖掘。
自制基础知识
Homebrew是一个软件包管理器,允许用户通过简单的接口安装软件包。如果您需要curl
并且没有它,则可以简单地运行brew install curl
,而自制酿酒师会获取它。您甚至可以在需要的情况下指定软件包的特定版本。
自制者如何知道从哪里得到东西?
Homebrew有一个核心包you can browse here的列表,当您输入brew install
时,可以使用这些列表。这些软件包中的每一个都有一个公式,它只是一个Ruby文件,它显示了最新的SHA包装的包装,并允许Homebrew基于操作系统选择正确的二进制文件。这是一个公式的示例:
class Wget < Formula
homepage "https://www.gnu.org/software/wget/"
url "https://ftp.gnu.org/gnu/wget/wget-1.15.tar.gz"
sha256 "52126be8cf1bddd7536886e74c053ad7d0ed2aa89b4b630f76785bac21695fcd"
def install
system "./configure", "--prefix=#{prefix}"
system "make", "install"
end
end
存储在此公式中的存储库称为a tap 。实际上,核心包列表存储在core tap中。这不仅是您可以拥有的点击;您可以创建自己的水龙头。
我如何创建水龙头?做什么?
有关于如何create a tap的标准文档。
简短的版本是,当您输入brew tap <tap_name> <URL>
时,它将转到该URL并在此处克隆存储库并将其保存在$(brew --repository)/Library/Taps
中。然后,当您输入brew install <package>
时,它将首先搜索核心点击,然后搜索您创建的任何其他水龙头。然后,它将查找公式Ruby文件,并从公式中的指定位置获取最新的软件包(或您指定的版本),然后将其放入Homebrew的路径中,以便您可以访问它。
如何创建一个公式?
您可以手工创建一个,但是GoReleaser can do it for you。
这是基本配置:
brews:
-
# Name of the recipe
#
# Default: ProjectName
# Templates: allowed
name: some_app
# Folder inside the repository to put the formula.
folder: Formula
# Your app's description.
#
# Templates: allowed
description: "Put in description here."
# Repository to push the generated files to.
repository:
owner: example
name: some_app
branch: brew-releases/{{ .Version }}
token: "{{ .Env.GITHUB_TOKEN }}"
pull_request:
enabled: true
base:
owner: example
name: some_app
branch: master
# NOTE: make sure the url_template, the token and given repo (github or
# gitlab) owner and name are from the same kind.
# We will probably unify this in the next major version like it is
# done with scoop.
# URL which is determined by the given Token (github, gitlab or gitea).
#
# Default depends on the client.
# Templates: allowed
url_template: "https://github.com/example/some_app/releases/download/{{ .Tag }}/{{ .ArtifactName }}"
# Allows you to set a custom download strategy. Note that you'll need
# to implement the strategy and add it to your tap repository.
# Example: https://docs.brew.sh/Formula-Cookbook#specifying-the-download-strategy-explicitly
download_strategy: GitHubPrivateRepositoryReleaseDownloadStrategy
custom_require: './custom_release_strategy'
# Git author used to commit to the repository.
commit_author:
name: goreleaserbot
email: goreleaserbot@example.com
# The project name and current git tag are used in the format string.
#
# Templates: allowed
commit_msg_template: "Brew formula update for {{ .ProjectName }} version {{ .Tag }}"
在这里,goreleaser将为您生成Ruby公式文件,并尝试将其提交到此存储库中的Formula
文件夹中。就我而言,我们对主要分支进行了保护,因此我们必须指定自动创建PR的部分。
我们还有一个GitHub操作,该操作使用GoReleaser's custom action在我们的存储库中创建新标签时触发释放。现在,我们一个人要做的就是创建一个带有新标签的版本,而GitHub Action将准备使用二进制文件的版本,然后自动创建PR,并使用更新的公式。一旦合并,Homebrew应该照顾更新修订。
然后只是brew tap
和brew install
组合ftw!
听起来还不错!您为什么抱怨这是痛苦?
啊,是的。陷阱。
Homebrew使用几种不同的方法下载/克隆回购,例如CurlDownloadStrategy
(which does exactly what it says)。
他们用来支持一个叫做GitHubPrivateRepositoryReleaseDownloadStrategy
的人。这正是名字所暗示的:它从Github私人存储库中下载。当我自己进行研究时,周围有很多文档,说是利用该策略来获得娱乐和利润。
问题是,GoReleaser然后GoReleaser stopped supporting it。
拧紧?并非如此,感谢社区和开源软件的一些帮助!
This comment在Goreleaser问题中向我展示了我可以从旧版本的Homebrew复制旧代码,并将它们与Goreleaser一起包含在我的配方中。
我认为最终我们将the recommendation made here与包含in this Gist link的代码使用。我们将该代码放入存储库中的同一Formula
文件夹中,并将其命名为custom_release_strategy.rb
。该文件在brews
部分的custom_require
字段中指向,并自动将其包含在公式文件中,因此Homebrew知道如何下载软件包。
希望能帮助任何想建立自己的CLI工具并通过Hommbrew运送它的人!
其他有用的链接:
https://hackernoon.com/building-homebrew-taps-for-private-github-repos
https://dev.to/jhot/homebrew-and-private-github-repositories-1dfh