Mac上的Ruby的 "终极 "版本的好处之一是可以进入GitHub的私有仓库。作为一个开发者--尤其是一个喜欢自动化的开发者--我很想尝试完全自动化地邀请新的Ultimate客户进入该仓库。
要做到这一点,需要实现一个自定义的结账,捕捉客户的GitHub用户名,这样我就可以把它传递给Paddle结账流程。不幸的是,Paddle不支持在其结账中添加自定义字段。
从那里,我只需要在我现有的接收Paddle webhook的小型Rails应用中添加几行代码。我目前正在使用它来自动添加/更新我ConvertKit账户中的客户,这样我就可以根据他们购买的产品轻松地对他们进行细分,计算他们的终身价值,自动填充他们的升级优惠券的字段,以及其他有用的东西。
从Paddle有效载荷中提取GitHub用户名后,我将使用octokitgem将客户作为只读合作者添加到 repo中。就像这样:
client = Octokit::Client.new(access_token: github_token)
client.add_collaborator(repo, username, permission: 'pull')
鉴于我每周只收到几份Ultimate订单,我想我应该练习一下打火石的艺术,暂时手动邀请每个用户。然而,这并不意味着我每次都要以缓慢的方式进行。
当一个客户给我发电子邮件要求访问时,我所要做的只是从他们发给我的电子邮件中复制他们的用户名,然后我按下⌃-⌥-⌘-A ,就完成了! 这种自动化使用键盘大师、GitHub API和1Password CLI。
下面是键盘大师的宏的样子:
虽然你可以直接在键盘大师中运行脚本,但我选择从iTerm的项目文件夹中运行脚本,因为那里已经安装了octokit gem。下面是add_collab.rb 文件的样子。
require 'octokit'
def repo
"rubyonmac/rom-ultimate"
end
def github_token
`op item get "add_collab GH token" --fields label=notesPlain`
end
def client
@client ||= Octokit::Client.new(access_token: github_token)
end
customer_github_username = ARGV[0]
puts "adding collaborator #{customer_github_username}"
response = client.add_collaborator(repo, customer_github_username, permission: 'pull')
puts "response: #{response}"
而这里是Gemfile:
source "https://rubygems.org"
ruby File.read(".ruby-version").strip
gem "octokit"
如果你读过我以前的自动化指南,你会记得它带有许多方便的标记,这些标记是数据的占位符,否则就需要复杂的代码来获取。在这种情况下,我使用%SystemClipboard% 令牌来传递用户名(我从客户的电子邮件中复制的),作为Ruby脚本的一个参数。当你向Ruby脚本传递一个参数时,你可以通过ARGV[0] 。
出于安全考虑,我需要向Octokit gem提供一个与我的账户相关的有效的GitHub令牌,以便能够进行这个特定的GitHub API调用。我创建这个令牌的方法是添加一个新的个人访问令牌,并给它适当的作用域:admin:org 和repo 。我还设置它在30天后失效。
因为我在家里使用两台Mac,所以我把所有的项目都放在GitHub上,这样我可以很容易地在两台电脑上获得最新的代码。即使在我的私人仓库里,我也会把包含秘密的文件(如GitHub令牌)gitignore,以增加安全性,也是出于习惯。
在过去,这需要将秘密文件(如.envrc 如果使用direnv)从一台电脑复制到另一台电脑,然后在每次更新时在两台电脑上更新。它还需要记住在外部驱动器上备份gitignored文件,如果我有一天更换了我的Mac。
但现在我发现了1Password CLI,我可以摆脱.envrc ,我不需要担心来回复制文件或备份任何东西。我可以从我的1Password账户中获取令牌,这在两台计算机上都是自动可用的。我的电脑上不再有任何秘密以纯文本形式存储(除了1Password),而且如果我想的话,我可以安全地将这个 repo 公开。
因此,代替通常的ENV['GITHUB_TOKEN'] ,我可以用这个命令获取令牌:
`op item get "add_collab GH token" --fields label=notesPlain`
在Ruby中,你可以通过在命令周围加上反斜线来运行shell命令。你可能也熟悉system命令,但它并不返回命令的输出。如果命令成功,它返回true (退出状态为0)。因为我想得到命令的实际输出,所以我需要反记号。
正如你可能从op 命令中猜到的那样,令牌被存储在1Password中名为 "add_collab GH token "的安全笔记中。我通过阅读item get的文档弄清了完整的命令,然后一开始只运行这个命令:
op item get "add_collab GH token"
它的返回结果是这样的:
ID: some_unique_id
Title: add_collab GH token
Vault: Personal
Created: 4 days ago
Updated: 4 days ago by Moncef Belyamani
Favorite: false
Version: 1
Category: SECURE_NOTE
Fields:
notesPlain: my_github_token
这就是我如何知道我需要的label 是notesPlain 。 这里又是完整的命令:
op item get "add_collab GH token" --fields label=notesPlain
为了让这个命令更稳健,我会在命令的末尾加上2>&1 ,将stderr 重定向到stdout ,然后将结果存储在一个变量中,只在没有错误的情况下调用GitHub API。就像这样:
def github_token
token = `op item get "add_collab GH token" --fields label=notesPlain 2>&1`
if token.include?("ERROR")
puts "Failed to fetch token from 1Password: #{token}"
nil
else
token
end
end
def client
@client ||= Octokit::Client.new(access_token: github_token)
end
if github_token
puts "adding collaborator #{ARGV[0]}"
response = client.add_collaborator(repo, ARGV[0], permission: 'pull')
puts "response: #{response}"
end
就这样,你就有了。多亏了 Keyboard Maestro、1Password CLI、Octokit gem 和几行 Ruby,与通过 GitHub 网站手动操作相比,我为每个客户节省了大约 30 秒。到目前为止,有49个终极版客户(我在2022年7月底刚刚推出了终极版),到目前为止,大约节省了25分钟的时间