在你的仓库中添加自定义 GitHub 徽章

Avatar of Nick Sypteras
Nick Sypteras

DigitalOcean 为你的旅程的每个阶段提供云产品。 立即开始使用 $200 免费试用额度!

如果你花时间查看过 GitHub 上的开源仓库,你可能已经注意到它们大多数在 README 文件中使用徽章。 比如官方的 React 仓库。 README 文件中到处都是 GitHub 徽章,它们可以传达重要的动态信息,比如最新发布的版本以及当前构建是否通过。

Showing the header of React's repo displaying GitHub badges.

像这样的徽章提供了一种很好的方式来突出显示有关仓库的关键信息。 你甚至可以使用自己的自定义资产作为徽章,就像 Next.js 在其仓库中所做的那样。

Showing the Next.js repo header with GitHub badges.

但到目前为止,GitHub 徽章最实用的功能是它们可以自行更新。 在 GitHub 中,徽章可以自动从远程服务器获取更改,而不是将值硬编码到你的 README 中。

让我们讨论如何将动态 GitHub 徽章添加到你自己的项目的 README 文件中。 我们将首先使用名为 badgen.net 的在线生成器来创建一些基本徽章。 然后,我们将通过 Napkin 将我们的徽章连接到我们自己的无服务器函数来使其动态化。 最后,我们将更进一步,使用我们自己的自定义 SVG 文件。

Showing three examples of custom GitHub badges including Apprentice, Intermediate, and wizard skill levels.

首先:徽章是如何工作的?

在我们开始在 GitHub 中构建一些徽章之前,让我们快速了解一下它们是如何实现的。 实际上非常简单:**徽章只是图像**。 README 文件是用 Markdown 编写的,而 Markdown 支持图像,如下所示

!\[alt text\](path or URL to image)

我们可以包含指向图像的 URL 的事实意味着,当页面呈现时,Markdown 页面将从服务器请求图像数据。 所以,**如果我们控制拥有该图像的服务器,我们可以使用我们想要的任何逻辑来更改发送回的图像!**

谢天谢地,我们有几个选项可以部署我们自己的服务器逻辑,而无需“设置服务器”部分。 对于基本用例,我们可以使用 badgen.net 的预定义模板创建我们的 GitHub 徽章图像。 再次,Napkin 允许我们快速地在浏览器中编写无服务器函数,然后将其部署为 GitHub 徽章可以与之通信的端点。

使用 Badgen 创建徽章

让我们从最简单的徽章解决方案开始:通过 badgen.net 使用静态徽章。 Badgen API 使用 URL 模式来动态创建模板徽章。 URL 模式如下

https://badgen.net/badge/:subject/:status/:color?icon=github

badgen.net 上可以找到关于颜色、图标等的完整选项列表。 对于此示例,让我们使用以下值

  • :subject : Hello
  • :status: : World
  • :color: : red
  • :icon: : twitter

我们最终的 URL 看起来像这样

https://badgen.net/badge/hello/world/red?icon=twitter

将 GitHub 徽章添加到 README 文件中

现在我们需要将此徽章嵌入到我们的 GitHub 仓库的 README 文件中。 我们可以使用前面提到的语法在 Markdown 中执行此操作

!\[my badge\](https://badgen.net/badge/hello/world/red?icon=twitter)

Badgen 提供了大量不同的选项,所以我鼓励你查看他们的网站并尝试一下! 例如,其中一个模板允许你显示给定 GitHub 仓库被加星的次数。 以下是一个 Next.js 仓库的星级 GitHub 徽章 作为示例

https://badgen.net/github/stars/vercel/next.js

很酷! 但是如果你想让你的徽章显示 Badgen 本身不支持的一些信息怎么办? 幸运的是,Badgen 有一个 URL 模板,用于使用你自己的 HTTPS 端点来获取数据

https://badgen.net/https/url/to/your/endpoint

例如,假设我们希望我们的徽章显示比特币当前的美元价格。 我们只需要一个自定义端点,它以 JSON 格式返回此数据,如下所示

{
  "color": "blue",
  "status": "$39,333.7",
  "subject": "Bitcoin Price USD"
}

假设我们的端点位于 https://some-endpoint.example.com/bitcoin,我们可以使用以下 URL 方案将它的数据传递给 Badgen

https://badgen.net/https/some-endpoint.example.com/bitcoin
GitHub badge. On the left is a gray label with white text. On the right is a blue label with white text showing the price of Bitcoin.
比特币成本的数据直接提供给 GitHub 徽章。

现在更酷了! 但我们仍然需要创建提供 GitHub 徽章数据的端点。 🤔 这就引出了…

Badgen + Napkin

有很多方法可以获得你自己的 HTTPS 端点。 你可以启动一个带有 DigitalOcean 或 AWS EC2 的服务器,或者你可以使用无服务器选项,比如 Google Cloud Functions 或 AWS Lambda; 但是,对于我们的简单用例而言,它们可能都变得有点复杂和乏味。 这就是我建议使用 Napkin 的浏览器内函数编辑器 来编码和部署端点,而无需任何安装或配置。

前往 Napkin 的比特币徽章示例 以查看示例端点。 你可以在编辑器中看到用于检索比特币当前价格并将其作为 JSON 返回的代码。 你可以从编辑器中自己运行代码,也可以直接使用端点。

要使用 Badgen 的端点,请使用上面的相同 URL 方案,只是这次使用 Napkin 端点

https://badgen.net/https/napkin-examples.npkn.net/bitcoin-badge

更多自定义 GitHub 徽章的方法

接下来,让我们 派生此函数 ,以便我们可以在其中添加我们自己的自定义代码。 点击右上角的“派生”按钮来执行此操作。 如果你还没有登录,则会提示你创建一个 Napkin 帐户。

成功派生函数后,我们可以添加任何我们想要的代码,使用任何我们想要的 npm 模块。 让我们添加 Moment.js npm 包 并更新端点响应,以便在我们的 GitHub 徽章中直接显示比特币价格最后更新的时间

import fetch from 'node-fetch'
import moment from 'moment'

const bitcoinPrice = async () => {
  const res = await fetch("<https://blockchain.info/ticker>")
  const json = await res.json()
  const lastPrice = json.USD.last+""

  const [ints, decimals] = lastPrice.split(".")

  return ints.slice(0, -3) + "," + ints.slice(-3) + "." + decimals
}

export default async (req, res) => {
  const btc = await bitcoinPrice()

  res.json({
    icon: 'bitcoin',
    subject: `Bitcoin Price USD (${moment().format('h:mma')})`,
    color: 'blue',
    status: `\\$${btc}`
  })
}
部署函数,更新你的 URL,现在我们将得到这个。

你可能会注意到,当你下次在 GitHub 上加载 README 文件时,徽章需要一些时间才能刷新。 这是因为 GitHub 使用代理机制来提供徽章图像。

GitHub 以这种方式提供徽章图像是为了防止滥用,比如高请求量或 JavaScript 代码注入。 我们无法控制 GitHub 的代理,但幸运的是,它不会过于积极地缓存(否则这将有点违背徽章的初衷)。 就我个人经验而言,TTL 约为 5-10 分钟。

好的,是时候来挑战终极大Boss了。

使用 Napkin 的自定义 SVG 徽章

对于我们的最后一步,让我们使用 Napkin 返回一个全新的 SVG,以便我们可以使用像 Next.js 仓库中所见到的自定义图像。

GitHub 徽章的一个常见用例是显示网站的当前状态。 让我们来做这个。 以下是我们的徽章将支持的两种状态

Badgen 不支持自定义 SVG,所以我们将让我们的徽章直接与我们的 Napkin 端点通信。 让我们为此创建一个名为 site-status-badge 的新 Napkin 函数。

此函数中的代码向 example.com 发出请求。 如果请求状态为 200,它将绿色徽章作为 SVG 文件返回; 否则,它将返回红色徽章。 你可以 查看此函数,但我也会在这里包含代码以供参考

import fetch from 'node-fetch'

const site_url = "<https://example.com>"

// full SVGs at <https://napkin.io/examples/site-status-badge>
const customUpBadge = ''
const customDownBadge = ''

const isSiteUp = async () => {
  const res = await fetch(site_url)
  return res.ok
}

export default async (req, res) => {
  const forceFail = req.path?.endsWith('/400')

  const healthy = await isSiteUp()
  res.set('content-type', 'image/svg+xml')
  if (healthy && !forceFail) {
    res.send(Buffer.from(customUpBadge).toString('base64'))
  } else {
    res.send(Buffer.from(customDownBadge).toString('base64'))
  }
}

example.com 网站永远停机的可能性很低,所以我添加了 forceFail 案例来模拟这种情况。 现在,我们可以在 Napkin 端点 URL 后面添加 /400 来尝试它

!\[status up\](https://napkin-examples.npkn.net/site-status-badge/)
!\[status down\](https://napkin-examples.npkn.net/site-status-badge/400)

非常棒 😎


就这样! 你的 GitHub 徽章培训完成了。 但旅程远未结束。 徽章在很多方面都非常有用。 尽情实验,让你的 README 闪耀吧! ✨