发布于 2026-01-06 14 阅读
0

使用 GitHub Actions 和 Pages 发布 GitHub 事件数据

使用 GitHub Actions 和 Pages 发布 GitHub 事件数据

在 GitHub 上工作的团队依靠事件数据进行协作。以问题、拉取请求和评论形式记录的数据对于理解项目至关重要。

随着 GitHub Actions 的正式发布,我们有机会以编程方式访问和保存我们代码库中的 GitHub 事件数据。将数据作为代码库的一部分,不仅可以将其保存在 GitHub 之外,还使我们能够在面向用户的网站上展示这些数据,例如使用 GitHub Pages。

如果你和我一样,你可以把GitHub 问题评论变成一个超棒的 90 年代风格的留言簿页面

无论具体用法如何,基本概念都是一样的。我们可以使用 Actions 来访问、保存和显示 GitHub 事件数据——只需一个工作流文件即可。为了演示这个过程,我将带您了解使我的留言簿功能正常运行的工作流代码

要了解 GitHub Actions 的入门知识,包括工作流的触发方式,请参阅使用 GitHub Actions 实现轻量级、与工具无关的 CI/CD 流程

访问 GitHub 事件数据

Action 工作流运行在一个包含一些默认环境变量的环境中。这里提供了许多便捷的信息,包括事件数据。访问事件数据的最完整方法是使用变量$GITHUB_EVENT_PATH,即包含完整 JSON 事件有效负载的文件路径。

展开后的路径如下所示/home/runner/work/_temp/_github_workflow/event.json,其数据对应于相应的 webhook 事件。您可以在 GitHub REST API事件类型和有效负载文档中找到 webhook 事件数据的相关信息。要使 JSON 数据在工作流环境中可用,您可以使用类似 的工具jq解析事件数据并将其放入环境变量中。

下面,我从问题评论事件中获取评论 ID

ID="$(jq '.comment.id' $GITHUB_EVENT_PATH)"

github.event大多数事件数据也可以通过上下文变量获取,无需解析 JSON。字段使用点号表示法访问,如下例所示,我获取了相同的评论 ID:

ID=${{ github.event.comment.id }}

我希望在留言簿中显示留言者的用户名、日期和时间。我可以像这样获取这些信息:

AUTHOR=${{ github.event.comment.user.login }}
DATE=${{ github.event.comment.created_at }}

Shell 变量虽然便于访问数据,但它们是短暂的。每次运行工作流环境都会重新创建,即使在某个步骤中设置的 shell 变量也不会保留到其他步骤。要持久化捕获的数据,您有两种选择:使用工件或将其提交到代码仓库。

保存事件数据:使用工件

使用工件,您可以在工作流作业之间持久化数据,而无需将其提交到存储库。例如,当您希望在将数据放入更永久的位置之前对其进行转换或合并时,此功能非常有用。在工作流作业之间持久化数据是必要的,原因如下:

工作流中的每个作业都在虚拟环境的一个全新实例中运行。作业完成后,运行程序会终止并删除该虚拟环境实例。使用工件持久化工作流数据

有两种操作可以帮助您使用工件:upload-artifactdownload-artifact。您可以使用这些操作使文件可供同一工作流中的其他作业使用。有关完整示例,请参阅在工作流中的作业之间传递数据

upload-artifact操作action.yml包含对关键字的解释。上传的文件以特定格式保存.zip。同一工作流运行中的另一个作业可以使用此download-artifact操作,以便在后续步骤中使用这些数据。

您也可以在工作流运行页面的存储库的“操作”选项卡下手动下载存档。

在作业之间持久化工作流数据不会对存储库文件进行任何更改,因为生成的工件仅存在于工作流环境中。就我个人而言,由于我习惯在 shell 环境中工作,我认为工件的用途比较有限,但我还是应该提一下。除了在作业之间传递数据之外,它们还可以用于创建.zip格式归档,例如测试输出数据。以我的留言簿示例为例,我只是在一个作业中运行了所有必要的步骤,因此无需在作业之间传递数据。

保存事件数据:将工作流文件推送到存储库

为了将工作流中捕获的数据保存到代码库中,需要将这些数据添加到 Git 代码库并推送。您可以在工作流中通过创建包含数据的新文件,或者使用 shell 命令将数据追加到现有文件来完成此操作。

在工作流程中创建文件

要在工作流中使用存储库文件,请先使用该checkout操作获取副本以供使用:

- uses: actions/checkout@master
  with:
    fetch-depth: 1

为了在我的留言簿上添加评论,我将 shell 变量中捕获的事件数据转换成合适的文件,利用shell 参数扩展中的替换来清理用户输入并将换行符转换为段落。我之前写过一篇关于为什么应该谨慎处理用户输入的文章

- name: Turn comment into file
  run: |
    ID=${{ github.event.comment.id }}
    AUTHOR=${{ github.event.comment.user.login }}
    DATE=${{ github.event.comment.created_at }}
    COMMENT=$(echo "${{ github.event.comment.body }}")
    NO_TAGS=${COMMENT//[<>]/\`}
    FOLDER=comments

    printf '%b\n' "<div class=\"comment\"><p>${AUTHOR} says:</p><p>${NO_TAGS//$'\n'/\<\/p\>\<p\>}</p><p>${DATE}</p></div>\r\n" > ${FOLDER}/${ID}.html

通过使用printf并将其输出定向>到一个新文件,事件数据被转换为一个以评论 ID 号命名的 HTML 文件,其中包含捕获的事件数据。格式化后,它看起来像这样:

<div class="comment">
  <p>victoriadrake says:</p>
  <p>This is a comment!</p>
  <p>2019-11-04T00:28:36Z</p>
</div>

处理评论时,如果使用评论 ID 命名文件,会导致具有相同 ID 的新文件覆盖旧文件。这对于留言簿来说非常方便,因为它允许对评论的任何编辑都替换原始评论文件。

如果你使用像 Hugo 这样的静态网站生成器,你可以创建一个 Markdown 格式的文件,把它放到你的content/文件夹里,常规的网站构建过程就会自动完成剩下的工作。就我这个简单的留言簿而言,我多了一个步骤,将各个留言文件合并成一个页面。每次运行时,它会先index.htmlheader.html`<command>` 部分覆盖现有内容,然后按降序>查找并追加所有留言文件的内容,最后追加 ` <command> ` 部分结束页面。>>footer.html

- name: Assemble page
  run: |
    cat header.html > index.html
    find comments/ -name "*.html" | sort -r | xargs -I % cat % >> index.html
    cat footer.html >> index.html

将更改提交到存储库

由于此checkout操作与克隆仓库并不完全相同,因此在撰写本文时,仍有一些问题需要解决。需要几个额外的步骤pull才能checkout成功push切换回master原分支,但这在 shell 中很容易完成。

以下步骤会将工作流所做的更改添加、提交并推送回存储库的master分支。

- name: Push changes to repo
  run: |
    REMOTE=https://${{ secrets.GITHUB_TOKEN }}@github.com/${{ github.repository }}
    git config user.email "${{ github.actor }}@users.noreply.github.com"
    git config user.name "${{ github.actor }}"

    git pull ${REMOTE}
    git checkout master
    git add .
    git status
    git commit -am "Add new comment"
    git push ${REMOTE} master

实际上,远程仓库(也就是我们的代码仓库)是通过github.repository上下文变量指定的。为了让我们的工作流能够向主分支推送代码,我们使用了这个secrets.GITHUB_TOKEN变量。

由于工作流环境是全新的,我们需要配置 Git。在上面的示例中,我使用github.actor上下文变量输入了发起工作流的帐户用户名。电子邮件也使用默认的noreplyGitHub 电子邮件地址进行配置。

显示事件数据

2019 年 11 月 6 日更正:GitHub Actions 需要个人访问令牌才能触发 Pages 站点构建。

如果您使用默认secrets.GITHUB_TOKEN变量且未使用站点生成器来运行 GitHub Pages,则在工作流中向存储库推送更改只会更新存储库文件。GitHub Pages 构建将失败,并显示错误信息:“您的网站构建出现问题:页面构建失败。”

要使 Actions 能够触发 Pages 站点构建,您需要创建一个个人访问令牌。此令牌可以作为密钥存储在存储库设置中,并代替默认变量传递到工作流中。我在这篇文章中secrets.GITHUB_TOKEN详细介绍了Actions 环境和变量

使用个人访问令牌,由操作工作流发起的推送也会更新 Pages 网站。您可以在我的留言簿上留言亲自体验一下!留言创建事件会触发工作流,该工作流大约需要 30 秒到 1 分钟才能运行并更新留言簿页面。

如果发布更改需要构建站点,例如在使用 Hugo 时,Action 也可以完成此操作。但是,为了避免产生意外循环,一个 Action 工作流不会触发另一个。相反,使用 Makefile 处理站点构建过程非常方便,任何工作流都可以运行该 Makefile。只需将运行 Makefile 添加为工作流作业的最后一步,并在必要时添加存储库令牌即可:

- name: Run Makefile
  env:
    TOKEN: ${{ secrets.GITHUB_TOKEN }}
  run: make all

这样可以确保工作流程的最后一步构建并部署更新后的网站。

不再有事件数据视界

GitHub Actions 提供了一种简洁的方式来捕获和利用事件数据,使其不仅限于 GitHub 内部使用。它的可能性仅受限于您的想象力!以下是一些我们可以利用它创建的应用示例:

  1. 一个面向公众的问题看板,没有 GitHub 帐户的客户可以在这里查看项目问题并给出反馈。
  2. 任何代码仓库的新问题、评论或 PR 的自动更新 RSS 源。
  3. 一个用于静态网站的评论系统,利用 GitHub 问题评论作为输入方式。
  4. 一个超棒的90年代留言簿页面。

我有没有说过我做了一个90年代风格的留言簿页面?我内心那个Geocities迷有点兴奋呢。

文章来源:https://dev.to/victoria/publishing-github-event-data-with-github-actions-and-pages-3ig5