使用 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-artifact和download-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.html用header.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 内部使用。它的可能性仅受限于您的想象力!以下是一些我们可以利用它创建的应用示例:
- 一个面向公众的问题看板,没有 GitHub 帐户的客户可以在这里查看项目问题并给出反馈。
- 任何代码仓库的新问题、评论或 PR 的自动更新 RSS 源。
- 一个用于静态网站的评论系统,利用 GitHub 问题评论作为输入方式。
- 一个超棒的90年代留言簿页面。
我有没有说过我做了一个90年代风格的留言簿页面?我内心那个Geocities迷有点兴奋呢。
文章来源:https://dev.to/victoria/publishing-github-event-data-with-github-actions-and-pages-3ig5