issue-pages
帮用户把 Issue Pages(用 GitHub Issue 当内容源的静态发布工具)部署成一套自己的站点:fork 仓库、开通 Actions 与 Pages、建 publish 标签、发布第一张页面,并验证最终网址真的能打开。当用户说「帮我部署一套 Issue Pages」「fork 这个仓库跑起来」「把这几个 HTML 发布到我自己的 GitHub Pages」「用 issue 发布网页」时使用。stars0
forks0
watches0
updated2026-10-16 18:43:48
Issue Pages 部署
帮用户把自己的一份 Issue Pages 跑起来。上游仓库默认是 CreateSun/code-js-bin-with-issue,用户要 fork 的是它。
发布内容的唯一来源是 issue
这条是硬规则,任何一步都不能绕开:
- 页面的每一个字节都来自 issue 正文。 构建脚本只读 issue(
scripts/build.mjs调 Issues API),生成dist/后发布。 - 不要在仓库里另建发布通道:
public/、assets/、docs/里放页面 HTML、或让构建去拷贝仓库里的静态文件,都会让"站点上的内容"多出一个来源,代码和 issue 立刻开始分叉,审批门(publish标签)也管不到它。需要新页面就开 issue。 - 单页上限 65536 字符(GitHub 对 issue 正文的硬限制)。发布前先量:
node -e 'console.log(require("fs").readFileSync("body.html","utf8").length)',超了就必须让页面变轻,而不是换通道:- 裁掉装饰性细节(细网格、刻度、齿纹、螺线、小零件的面色带);
- 坐标量化(四舍五入到 1–2 个单位,1× 分辨率看不出);
- 体积还大就把矢量/文本用
gzip + base64内联,页面里用DecompressionStream("gzip")解压后再挂载(bambu-a1-mini这个 issue 就是这么做的,正文 64 KB 装下一张约 34000 个坐标的等距图)。 - 一个页面实在装不下就拆成几个 issue 分别发布,不要拼出第二种发布方式。
- 用户明确要求"把某个仓库文件发布到站点"时,也要走 issue:把内容贴进 issue 正文,而不是加旁路。
先确认三件事
gh auth status显示已登录,且 token 有reposcope(没有就先让用户gh auth login,不要代替用户登录)。- 部署到哪个账号/仓库:默认是当前登录用户 fork 上游仓库;用户已有 fork 时直接用它,不要重复创建。
- 是否要保留发布审批:默认保留(
ISSUE_AUTHOR= 仓库 owner,PUBLISH_LABEL=publish)。用户说「不用审批」就让他把工作流里的PUBLISH_LABEL改成空字符串。
下面的命令把 $OWNER 换成用户的账号名、$REPO 换成 fork 出来的仓库名。
部署步骤
1. Fork 并克隆
gh repo fork CreateSun/code-js-bin-with-issue --clone --default-branch-only
gh 已经 fork 过会报错,此时改成克隆已有的那个 fork。克隆目录里 git remote origin 就是用户的 fork。
2. 打开工作流开关
GitHub 不会在新 fork 上自动运行工作流,必须显式打开:
gh api -X PUT "repos/$OWNER/$REPO/actions/permissions" -f enabled=true
失败(403 等)就告诉用户在仓库 Actions 页点 “I understand my workflows, go ahead and enable them”,不要跳过这步——跳过会表现为「部署一直没跑」。
3. 启用 GitHub Pages(构建源 = GitHub Actions)
gh api -X POST "repos/$OWNER/$REPO/pages" -f build_type=workflow
已存在会返回 409,可以忽略。不要依赖工作流自己开通 Pages:GITHUB_TOKEN 没有创建 Pages 站点的权限,没启用就运行会以 “先打开 …/settings/pages” 的报错失败——这是预期行为,不是配置坏了。
4. 建发布标签
gh label create publish --repo "$OWNER/$REPO" --color 0E8A16 \
--description "打上这个标签才发布到站点(审批通过)"
标签名要和 PUBLISH_LABEL 一致。没有这个标签时所有 issue 都会被跳过,站点会是空的——这是最常见的「部署成功但页面 404」原因。
5. 换成用户自己的信息
src/footer.html:把博客链接和源码链接换成用户自己的,或整段删掉。- 首页标题默认取仓库名,想改就设工作流里的
SITE_NAME。 - 想改站点样式:
src/style.css。
改完提交推送:
git add -A && git commit -m "chore: 改成我自己的站点信息" && git push
推送会触发一次构建,你也可以顺便确认工作流能跑通。
6. 发布第一张页面
把页面源码写进一个文件(HTML 片段、完整 HTML 或纯 JS 都可以),然后:
gh issue create --repo "$OWNER/$REPO" --title hello --body-file /tmp/hello.html --label publish
--title 就是访问路径,用英文小写和连字符。
7. 等部署完成并验证网址真的能打开
gh run list --repo "$OWNER/$REPO" --limit 3
run=$(gh run list --repo "$OWNER/$REPO" --limit 1 --json databaseId --jq '.[0].databaseId')
gh run watch "$run" --repo "$OWNER/$REPO" --exit-status
工作流成功不等于网站可访问。必须再验证一次,直到拿到 200 或超时:
host="$(printf '%s' "$OWNER" | tr '[:upper:]' '[:lower:]')"
url="https://$host.github.io/$REPO/hello/"
for i in $(seq 1 20); do
code=$(curl -s -o /tmp/page.html -w '%{http_code}' "$url")
[ "$code" = "200" ] && break
sleep 10
done
echo "$code $url"
grep -q "页面正文里的某个特征字符串" /tmp/page.html && echo "内容已上线"
首次部署 Pages 可能有几十秒到几分钟的传播延迟,属正常。最后把 url 报给用户。
排查
| 现象 | 原因与处理 |
|---|---|
| 完全没有工作流运行 | fork 的 Actions 没开(步骤 2);或 issue 事件没触发,手动 gh workflow run deploy-pages.yml --repo "$OWNER/$REPO" |
| 运行失败并提示「先打开 …/settings/pages」 | Pages 还没启用,按步骤 3 做完再重跑;如果是在启用 Pages 之前推的代码,这次失败属正常 |
| 构建日志里全是「跳过 #N … 还没有 publish 标签」 | 标签名与 PUBLISH_LABEL 不一致,或 issue 没打标签 |
| 构建日志里「作者 xxx 不在发布名单内」 | ISSUE_AUTHOR 是别人;要放开发布就把它设为空字符串 |
| 构建成功但访问 404 | Pages 没启用 / 构建源不是 GitHub Actions(步骤 3);或路径拼错、大小写不符 |
发布时 gh 报 Body is too long (maximum is 65536 characters) | 页面超过单页上限,按上文压体积,不要在仓库里加旁路 |
| 页面是旧的 | Pages 对 HTML 有 cache-control: max-age=600,强刷一次 |
gh: Not Found / Resource not accessible | token 缺 repo scope 或不是仓库 admin |
不要做的事
- 不要在没 curl 到 200 的情况下告诉用户「已经部署好了」。工作流 success 只说明构建和部署动作完成。
- 不要替用户改仓库名、转让或删除仓库;改名会让全部旧链接失效,要由用户决定。
- 不要把 token、密码写进任何文件或命令参数里让用户看到。
- 只有在用户明确要求时才关闭审批门或放开作者名单——这两项是防止别人往他的域名上发内容的主要手段。
- 不要在仓库里为页面内容另开通道(
public/、资产目录、构建期拷贝静态文件)。内容的唯一来源是 issue;页面太大就压小它,见开头那节。