Fail a GitHub Actions job when a vendor page changes
Fail a GitHub Actions job when a vendor page changes
当供应商页面发生变更时,使 GitHub Actions 任务失败
A scheduled workflow can fail when a vendor pricing page, docs page, or changelog changes its text. The job below reads the latest event from a SignalWatch monitor and exits 1 if that event is a content change from the last six hours. This is for public, server-rendered pages. It does not render JavaScript, log in, or take a screenshot. If the price only exists after a client-side render, the monitor will not see it.
当供应商的定价页面、文档页面或更新日志中的文本发生变化时,定时工作流(Scheduled workflow)可以触发失败。以下任务会读取 SignalWatch 监控器的最新事件,如果该事件是过去六小时内的内容变更,则会以退出码 1 终止。此方案适用于公开的、服务器端渲染的页面。它不会渲染 JavaScript、登录或截屏。如果价格仅在客户端渲染后才显示,监控器将无法检测到。
The workflow Save this as .github/workflows/upstream-drift.yml. It uses GNU date, which ubuntu-latest provides.
工作流保存为 .github/workflows/upstream-drift.yml。它使用了 ubuntu-latest 环境中提供的 GNU date 工具。
name: upstream-drift
on:
schedule:
- cron: "0 */6 * * *"
workflow_dispatch:
jobs:
check:
runs-on: ubuntu-latest
steps:
- name: Fail if the vendor page changed in the last 6h
env:
KEY: ${{ secrets.SIGNALWATCH_KEY }}
CHECK_ID: "123"
run: |
latest=$(curl -fsS "https://signalwatch.litework.me/api/v1/checks/$CHECK_ID/events?limit=1" -H "X-API-Key: $KEY")
event=$(echo "$latest" | jq -r '.[0].event // "none"')
when=$(echo "$latest" | jq -r '.[0].created_at // "1970-01-01T00:00:00Z"')
age=$(( $(date +%s) - $(date -d "$when" +%s) ))
if [ "$event" = "changed" ] && [ "$age" -lt 21600 ]; then
echo "::error::Upstream page changed"
echo "$latest" | jq -r '.[0].diff'
exit 1
fi
echo "no recent change ($event, ${age}s ago)"
Add the API key as a repository secret named SIGNALWATCH_KEY. Replace 123 with the monitor id from the dashboard. The events endpoint returns the newest row first. On that API a content change is event: "changed". Webhook deliveries for the same moment use content.changed. diff is a unified text diff. change_ratio is changed characters divided by the longer of the two texts.
将 API 密钥添加为名为 SIGNALWATCH_KEY 的仓库密钥(Repository Secret)。将 123 替换为仪表板中的监控器 ID。事件接口会优先返回最新的一行数据。在该 API 中,内容变更对应的事件为 event: "changed"。同一时刻的 Webhook 推送则使用 content.changed。diff 是统一文本差异格式。change_ratio 是变更字符数除以两个文本中较长者的长度。
Create the monitor: Free covers 3 monitors at a 15 minute interval, no card: https://signalwatch.litework.me/ Two settings matter more than the schedule: A CSS selector, so you hash the price table or the docs section instead of the whole document. An ignore regex, so a line like “updated 3 minutes ago” does not fail the build.
创建监控器:免费版支持 3 个监控器,间隔 15 分钟,无需信用卡:https://signalwatch.litework.me/。有两个设置比调度频率更重要:CSS 选择器(用于仅对价格表或文档部分进行哈希校验,而不是整个文档)以及忽略正则表达式(用于过滤掉“3分钟前更新”这类行,避免导致构建失败)。
There is a public monitor on the Hacker News front page if you want to read real diffs before creating an account: https://signalwatch.litework.me/live.html. Curl, Python, and signature checks, including this workflow, are on the examples page: https://signalwatch.litework.me/examples.html.
如果你想在注册账号前查看真实的差异对比,Hacker News 首页有一个公开的监控器:https://signalwatch.litework.me/live.html。包括此工作流在内的 Curl、Python 和签名检查示例页面位于:https://signalwatch.litework.me/examples.html。
What a failure looks like: The Actions log prints the diff and the job goes red: --- before +++ after @@ -3 +3 @@ -Starter $10/mo +Starter $14/mo
失败时的表现:Actions 日志会打印出差异对比,且任务状态变为红色: --- 修改前 +++ 修改后 @@ -3 +3 @@ -Starter $10/mo +Starter $14/mo
Downtime is a different event (down, then up when the fetch recovers). Those do not fail this job. Extend the if if a failed fetch should fail CI as well.
宕机是另一种事件(先是 down,待抓取恢复后变为 up)。这些事件不会导致此任务失败。如果希望抓取失败也导致 CI 失败,请扩展 if 条件。
Limits: Public http(s) URLs only. Fetches are capped at 2 MB and follow up to 3 redirects. JavaScript is not executed. Email, Slack, Discord, and HMAC-signed JSON are the push path. This workflow is the pull path, for a repo that already lives in Actions and wants upstream drift to turn the badge red.
限制:仅支持公开的 http(s) URL。抓取内容上限为 2 MB,最多跟随 3 次重定向。不执行 JavaScript。电子邮件、Slack、Discord 和 HMAC 签名 JSON 是推送路径。此工作流属于拉取路径,适用于已经在 Actions 中运行且希望通过上游变动使徽章变红的仓库。