Wails 的零依赖 Star History SVG 生成器:基于 GitHub Stargazers 时间戳的每周图表工具
Wails 的零依赖 Star History SVG 生成器基于 GitHub Stargazers 时间戳的每周图表工具【免费下载链接】wailsCreate beautiful applications using Go项目地址: https://gitcode.com/gh_mirrors/wa/wails导读Wails 仓库中内置了一个名为tools/starhistory的 Go 命令行工具它不依赖任何第三方 Go 库仅用标准库就能拉取 GitHub 的带时间戳 Stargazers 数据将其聚合成按周累计的星标历史并渲染出一张完全自包含背景图与 Logo 均以 base64 内嵌的 SVG 折线图输出到 website/static/img/star-history.svg最终展示在仓库根目录 README.md 的 Stargazers over time 板块。读完本文你将掌握该工具的完整数据链路API 抓取 → 周聚合 → 实时计数校准 → SVG 渲染、全部命令行参数与令牌要求以及它的 GitHub Actions 每周自动化与人工发布流程并能用同样的思路为自己的仓库搭建一套零依赖的 Star 历史图表。工具定位与设计动机tools/starhistory/README.md开宗明义地说明了它的角色Wails star history即website/static/img/star-history.svg的无依赖 Go 生成器dependency-free Go generator。这一设计背后有几个明确动机只依赖 Go 标准库go.mod中module github.com/wailsapp/wails/tools/starhistory仅声明go 1.25.0没有任何第三方 require。这样生成的二进制可以在仓库现有的 Go CI 工作流中直接运行无需 Python、Docker 或 Node.js 环境见 main.go 的注释说明。输出自包含 SVG渲染出的 SVG 将 Digital Wales 背景图digital_wales_master.webp和横向 Wails Logowails-logo-horizontal-dark.svg以 base64 Data URI 内嵌README 渲染器无需发起第二次网络请求即可完整显示图表见 render.go 注释。从源码结构看工具由五个文件组成职责清晰入口编排main.go、GitHub API 客户端github.go、周聚合与校准history.go、SVG 渲染render.go以及单元测试starhistory_test.go。GitHub 令牌要求管理员或协作者权限原文档特别强调了一条 GitHub 当前的 API 策略变化GitHub now requires the token to belong to a repository admin or collaborator for the stargazers endpoint.也就是说读取带时间戳的 Stargazersstarred_at字段时使用的令牌必须属于仓库管理员admin或协作者collaborator普通只读令牌无法拿到该数据。这一点在 github.go 的FetchStars注释中同样有明确说明调用时若令牌为空会直接返回错误GitHub token is required to read stargazer timestamps。在 CI 工作流 .github/workflows/generate-star-history.yml 中令牌的注入顺序为env: GITHUB_TOKEN: ${{ secrets.WAILS_REPO_TOKEN || secrets.STAR_HISTORY_TOKEN || github.token }}即优先使用WAILS_REPO_TOKEN其次STAR_HISTORY_TOKEN最后才是github.token。后两者尤其github.token通常不具备管理员/协作者权限仅作为兜底存在。本地运行命令行参数与环境变量原文档给出了从工具目录直接运行的命令GOWORKoff GITHUB_TOKEN$(gh auth token) go run .其中GOWORKoff禁用 Go Workspace 模式。由于该工具是独立 moduletools/starhistory/go.mod而仓库根目录存在Taskfile.yaml等工程配置GOWORKoff确保只按该 module 自身的go.mod构建不受外层 workspace 干扰CI 中的 Render star history 步骤也使用了同样的cd tools/starhistory GOWORKoff go run .。GITHUB_TOKEN$(gh auth token)借用 GitHub CLI 的登录态为工具提供令牌前提是该账号是目标仓库默认wailsapp/wails的管理员或协作者。main.go通过标准库flag包定义的全部参数如下参数默认值说明-repowailsapp/wails目标仓库必须是owner/name形式否则报错见 main.go-backgrounddigital_wales_master.webp要内嵌进 SVG 的背景图相对当前目录-logo../../website/static/img/wails-logo-horizontal-dark.svg要内嵌到图表头部的横向 Wails Logo-out../../website/static/img/star-history.svg输出 SVG 的路径环境变量的读取顺序与 CI 一致见 main.go优先GITHUB_TOKEN其次STAR_HISTORY_TOKEN两者都为空则调用fatal终止并输出GITHUB_TOKEN or STAR_HISTORY_TOKEN must be set。程序的完整执行流程main.go读取背景图与 Logo 文件失败即fatal建立 10 分钟超时的 context调用GitHubClient.FetchStars拉取全部可见 Stargazer 时间戳调用BuildWeeklyHistory聚合为按周累计的历史点调用GitHubClient.FetchStarCount获取当前权威星标总数调用ReconcileCurrentCount校准最新数据点调用RenderSVG生成 SVG 字符串先写入同目录临时文件os.CreateTemp前缀.star-history-*.svg设置0644权限后以os.Rename原子替换目标文件——避免渲染中途留下半成品 SVG。数据获取分页抓取与并发控制GitHubClient.FetchStarsgithub.go是数据链路的起点核心要点如下请求构造向GET /repos/{owner}/{repo}/stargazers?per_page100pageN发请求Accept头设置为application/vnd.github.starjson这是拿到starred_at时间戳的关键媒体类型Authorization使用Bearer tokenUser-Agent为wails-star-history。每页固定 100 条githubPageSize。错误处理非 2xx 状态码会把响应体截断到 300 字符后拼进错误信息方便定位 GitHub 返回的具体原因。分页策略先抓第 1 页若不足一页说明没有更多数据直接返回。否则解析响应头Link中的rellast得到最后一页页码lastPageFromLinkgithub.go。若拿不到LinklastPage 1则逐页顺序抓取直到短页若拿到则用最多 8 个 worker 的有界并发池抓取剩余页面——对星标数巨大的仓库这能显著缩短每周刷新耗时同时避免瞬间产生无节制的 API 请求洪峰。对应的测试 TestFetchStarsPaginatesAndAuthenticates 用httptest模拟 GitHub 接口验证了Authorization: Bearer secret与Accept: application/vnd.github.starjson请求头、跨两页共 101 条数据的聚合结果以及恰好 2 次 HTTP 请求的分页行为TestLastPageFromLink 则验证了从 Link 头解析出page359的能力。历史聚合按 ISO 周累计BuildWeeklyHistoryhistory.go把海量 Star 时间戳压缩成适合绘图的周粒度数据点将每个starred_at转为 UTC计算其所在周周一的零点daysSinceMonday (weekday 6) % 7再用time.Date回退到周一零点以周一次为键计数该周新增的 Star 数按时间升序排序各周做前缀累计得到WeeklyPoint{Date, Count}列表Date是该 ISO 周的周一Count是截至该周的累计星标数。WeeklyPoint结构体定义于 history.go注释明确为某个 ISO 周开始时的累计星标数。测试 TestBuildWeeklyHistoryAccumulatesStarsByWeek 验证了跨周边界的分组1 月 1 日周一与 1 月 7 日同一周合并为计数 2 的第一个点1 月 8 日下一周成为计数 3 的第二个点。实时校准权威计数兜底由于拉取列表与仓库实时总数之间可能存在时间差并发期间的 star/unstar 行为或受权限限制导致列表不完整ReconcileCurrentCounthistory.go会用仓库接口返回的权威stargazers_count校准最新数据点逻辑如下currentCount 0视为无效直接返回原历史历史为空时构造一个当前时刻、当前计数的单一数据点若最后一个周点与今天UTC同属一周直接把该点 Count 覆盖为权威计数不新增虚构的历史点否则在历史末尾追加一个今天、权威计数的新点。对应测试 TestReconcileCurrentCountAddsAuthoritativeCurrentPoint 验证了跨周时追加新点的行为。FetchStarCount本身实现于 github.go请求GET /repos/{owner}/{repo}并解码stargazers_count字段。SVG 渲染自包含图表RenderSVGrender.go用纯字符串拼接生成 1200×640 的 SVG画布布局绘图区左侧距 100、顶部距 135、宽 1020、高 370常量定义见 render.go。内嵌素材背景图以data:image/webp;base64,...内嵌并设置opacity0.24、preserveAspectRatioxMidYMid sliceLogo 以data:image/svgxml;base64,...内嵌于右上角x910, y49, 210×51。这正是自包含、零网络请求的实现方式。视觉层次深色渐变遮罩#veil压在背景上圆角描边边框#ff5364、红色折线主线条宽 4px另有 14px 模糊辉光filterurl(#glow)的衬线、红色到透明的面积渐变#chartFill以及末端白色描边圆点 计数 callout。坐标轴Y 轴 4 条虚线网格刻度值取niceCeiling(maxCount)的友好上限1/2/5 步进的整十倍数见 render.go超过 1000 时缩写为1k、12.5k、50k这种紧凑形式formatAxisCountX 轴均匀取 6 个历史点格式化为Jan 06如Jan 24。元信息title写入Wails star history — N stars页脚左侧为 First star 02 Jan 2006仓库首个星标日期右侧为 Updated 02 Jan 2006 · github.com/wailsapp/wails其中仓库名经xmlEscape转义后再插入 SVG防止特殊字符破坏标记render.go。渲染相关测试覆盖了三类行为内嵌素材与红色主题TestRenderSVGIncludesFadedBackgroundAndRedChart验证 base64 编码后的背景/Logo Data URI、fillurl(#chartFill)、stroke#ff5364、Wails与8 stars等关键子串、紧凑计数格式TestFormatAxisCountUsesCompactThousands覆盖0/999/1k/12.5k/50k五种边界。自动化与发布每周定时 手动确认原文档最后一段描述了工具的自动化闭环对应工作流 .github/workflows/generate-star-history.yml 中的两个 job1.generate-star-history每周自动渲染只读权限触发条件workflow_dispatch手动或 cron17 2 * * 0每周日 UTC 02:17且仅在github.repository wailsapp/wails时执行权限仅contents: readpersist-credentials: false安全上刻意不保留写凭据用actions/setup-gov5配合go-version-file: tools/starhistory/go.mod锁定 Go 版本执行cd tools/starhistory GOWORKoff go run .令牌按上文三级兜底注入生成的 SVG 通过actions/upload-artifactv4以star-history为名上传为工作流工件artifact保留但不自动提交。2.publish-star-history仅手动触发时发布写权限触发条件github.event_name workflow_dispatch——只有人工发起的运行才会进入发布阶段把仓库写入commit push放在显式确认之后权限contents: write下载 artifact 后检查website/static/img/star-history.svg是否有变更无变化则输出changedfalse直接退出有变化则以taliesin-ai身份提交chore: update star history [skip ci]push 时用WAILS_PUSH_TOKEN同样是WAILS_REPO_TOKEN || github.token兜底通过x-access-token方式推回仓库。这与原文档定时工作流每周渲染 SVG 并作为工件保留手动运行的 run 才会把变更后的 SVG 提交入库仓库写入始终需要显式确认的描述完全吻合。使用与定制建议按自己的仓库生成把-repo换成owner/name并确保令牌持有者是该仓库管理员或协作者即可本地生成同款图表。修改观感背景图与 Logo 可通过-background/-logo更换主题色、布局常量chartWidth等集中在 render.go 顶部与svgDefs()内改动直观。接入 CI可仿照generate-star-history的步骤在任意仓库中以只读令牌定时渲染并上传 artifact是否需要自动提交取决于你的发布策略。验证运行go test ./...在tools/starhistory目录下可执行 starhistory_test.go 中的全部单元测试覆盖聚合、校准、分页、Link 解析、SVG 渲染与计数格式六个维度无需联网即可验证核心逻辑。总结tools/starhistory是 Wails 仓库中一个典型的小而完整的工程化范例纯标准库实现零第三方依赖、带时间戳 Stargazers 的分页并发抓取、ISO 周粒度累计、权威计数兜底校准、base64 自包含 SVG 渲染、临时文件原子替换再配以定时渲染为工件 手动触发才提交的 CI 安全策略最终产出 website/static/img/star-history.svg 展示在 README.md 中。无论你是想复用这套方案还是想理解 Go 标准库 GitHub API 的典型数据管道写法它都是一个值得精读的参考实现。【免费下载链接】wailsCreate beautiful applications using Go项目地址: https://gitcode.com/gh_mirrors/wa/wails创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考