1. 背景:当你打开 GitHub 发现 Actions 和 Pages 在降级
很多开发者都有过类似经历:早上刚到工位,准备推送代码触发 CI/CD 流水线,结果发现 GitHub Actions 一直卡在queued状态;或者刚更新完文档,打开 GitHub Pages 站点却看到 502 或者空白页。这时候去 status.github.com 一看,才会发现官方已经挂出了公告:GitHub Actions and Pages are experiencing degraded availability。
这不是某个人的网络问题,也不一定是你配置写错了,而很有可能是 GitHub 平台自身的服务出现了降级。这里有两个关键点需要区分:degraded availability(服务降级)和major outage(重大故障)。服务降级意味着系统还在运行,部分功能可用但响应速度变慢,或者部分请求失败,而不是完全不可用。对于依赖 GitHub Actions 做自动构建、用 GitHub Pages 托管静态站点的团队来说,这种降级直接影响交付效率和线上访问体验。
围绕这个主题,本文会做几件事:先讲清楚 GitHub Actions 与 GitHub Pages 在 CI/CD 和静态托管中的定位,再结合实际案例演示一套完整可复用的 Pages 部署工作流,然后重点分析服务降级时常见的现象、原因和排查思路,最后给出工程化的规避方案。无论你是刚接触 GitHub 自动化流程的新手,还是已经用它承载业务发布的开发者,这篇文章都能帮你建立一套应对“平台不稳定的”的完整思路。
2. 环境准备:搭建一套可复现的 GitHub Actions + Pages 实验环境
在展开实战之前,先说明本文对应的运行环境和版本范围。GitHub Actions 和 GitHub Pages 都是 GitHub 官方提供的 SaaS 服务,它们不像本地软件那样有固定的版本号,而是在 GitHub 云端持续更新的。因此,下面的环境说明主要针对本地操作端和仓库配置方式。
本地环境建议:
- 操作系统:Windows / macOS / Linux 均可,命令以 bash 为主
- Git 版本:2.30 以上
- 仓库托管:GitHub 上的一个公开仓库(私有仓库也可以,但 Pages 部署权限有限制)
- 示例项目:一个最简单的 HTML 静态站点,也可以是 Vue、React 构建产物
- 浏览器:Chrome / Edge / Firefox 最新版,用于确认 Pages 访问效果
这里需要特别说明:由于 Actions 和 Pages 的云端行为由 GitHub 动态调整,你不需要关心服务端版本,但需要关注 GitHub 官方文档中标注的actions/upload-pages-artifact、actions/deploy-pages等 Action 的版本。这些 Action 是通过版本号(例如v3、v3.0.1)引用的,建议在 workflow 里固定主版本,而不是直接使用main分支的最新代码,这样可以避免上游变更带来的意外。
接下来,在 GitHub 上创建一个新仓库,名字可以取为actions-pages-demo。创建时可以添加一个 README,也可以什么都不加,后面我们会用命令推送代码。
仓库创建完成后,在本地初始化项目结构:
mkdir actions-pages-demo cd actions-pages-demo git init git branch -M main在项目根目录创建一个index.html,内容如下:
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>GitHub Pages Demo</title> <style> body { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; max-width: 800px; margin: 0 auto; padding: 48px 16px; color: #24292f; } .status-card { border: 1px solid #d0d7de; border-radius: 6px; padding: 24px; background: #f6f8fa; } .degraded { color: #9a6700; background: #fff8c5; border-color: #d4a72c; display: inline-block; padding: 4px 12px; border-radius: 999px; font-weight: 600; } </style> </head> <body> <h1>GitHub Actions 与 GitHub Pages 演示站点</h1> <p>当前页面由 GitHub Pages 托管,通过 GitHub Actions 自动发布。</p> <div class="status-card"> <span class="degraded">degraded availability</span> <p>服务可用性状态监控与部署流程演示。</p> </div> </body> </html>这个页面只是一个演示,主要用来验证后续 Actions 工作流是否能把代码发布到 Pages。现在把代码推送到 GitHub 仓库:
git add . git commit -m "init static site" git remote add origin https://github.com/<你的用户名>/actions-pages-demo.git git push -u origin main到这里,本地环境就准备好了。接下来要理解 Actions 和 Pages 各自承担什么职责,才能明白降级到底影响了哪些环节。
3. 核心概念拆解:Actions 和 Pages 到底承担什么角色
3.1 GitHub Actions:事件驱动的自动化执行引擎
GitHub Actions 是 GitHub 提供的一种 CI/CD(持续集成与持续部署)服务。你可能听过 Jenkins、GitLab CI/CD 等工具,Actions 和它们解决的问题类似,但最大的优势是它直接内嵌在 GitHub 仓库中,不需要单独部署。你只要在仓库里放一个.github/workflows目录,里面写上 YAML 格式的 workflow 文件,GitHub 就会根据你定义的事件(比如push、pull_request、schedule)自动执行任务。
一次 Actions 的运行可以拆成三个层级:
- Workflow:整个自动化流程,对应一个 YAML 文件
- Job:一个 workflow 中可以包含多个 job,job 之间可以并行或依赖执行
- Step:每个 job 中的最小执行步骤,可以运行命令,也可以引用现成的 Action
举个例子,下面的 workflow 定义了:当代码推送到main分支时,在 Ubuntu 环境中执行一次npm install和npm run build。这是典型的 CI 流程。
name: CI on: push: branches: [ main ] jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version: 20 - run: npm install - run: npm run buildActions 解决的问题,是把过去需要人工执行的构建、测试、部署流程自动化。当服务出现degraded availability时,最直观的感受就是 job 长时间不开始执行,或者执行后一直卡在某个步骤。因为 Actions 的调度和执行依赖 GitHub 的后端集群,一旦集群部分节点异常,排队中的任务就会积压。
3.2 GitHub Pages:面向静态站点的托管服务
GitHub Pages 是 GitHub 提供的静态站点托管服务。它可以把仓库中的一个分支、一个目录或一份 workflow 产物,发布成一个可以公开访问的网站,域名格式是https://<用户名>.github.io/<仓库名>/。
底层来看,Pages 本身并不执行动态代码,它只负责把静态文件(HTML、CSS、JavaScript、图片等)通过 CDN 对外提供访问。所以 Pages 的可用性问题,通常不是“站点代码坏了”,而是托管服务本身的负载均衡、CDN 回源、存储服务出现了性能下降。
Pages 支持三种发布方式,这也是本文实战部分要对比的内容:
- 从分支发布:直接指定分支下的根目录或
/docs目录 - 从 GitHub Actions 发布:由 workflow 构建产物上传后发布
- 自定义 GitHub Actions 工作流:完全由用户控制构建和部署步骤
从分支发布最简单,但缺少构建过程,适合纯 HTML 站点。从 Actions 发布是当前更推荐的方式,因为页面可以经过构建再发布,并且在 Actions 服务异常时,构建和发布会同时受影响,你需要理解这个依赖链。
3.3 “降级”到底影响什么
结合 GitHub 官方的状态定义,degraded availability表示服务还在处理请求,但性能明显低于正常水平。放在 Actions 上,可能的表现是:
- 工作流的
queued时间从几秒变成几分钟 - 部分 job 被暂时拒绝创建
- API 请求出现 5xx 错误或超时
放在 Pages 上,可能的表现是:
- 站点第一次访问需要更久的 DNS 解析和 TLS 握手
- CDN 边缘节点返回 502 或 404
- 仓库设置里的 Pages 配置页面加载缓慢
理解了这些表现,下一步就可以用实际的 workflow 把整个发布过程串起来,并且在其中加入一些应对不稳定服务的策略。
4. 完整实战:用 GitHub Actions 自动部署静态站点到 GitHub Pages
这一节的目标是构建一个最完整也最贴近真实项目的 Pages 发布流程。我们会使用actions/deploy-pages这个官方 Action 来发布站点,同时加入构建产物缓存、并发控制和失败重试等实用配置。
4.1 创建部署工作流文件
在项目根目录创建.github/workflows/pages.yml文件。先创建目录:
mkdir -p .github/workflows然后写入以下内容:
# 文件路径:.github/workflows/pages.yml name: Deploy static content to Pages on: push: branches: ["main"] workflow_dispatch: permissions: contents: read pages: write id-token: write concurrency: group: "pages" cancel-in-progress: false jobs: deploy: environment: name: github-pages url: ${{ steps.deployment.outputs.page_url }} runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v4 - name: Setup Pages uses: actions/configure-pages@v5 - name: Upload artifact uses: actions/upload-pages-artifact@v3 with: path: "." - name: Deploy to GitHub Pages id: deployment uses: actions/deploy-pages@v4逐个解释这段配置的含义。
permissions部分非常重要。GitHub 为了安全,默认情况下 workflow 的GITHUB_TOKEN权限是受限的。要部署到 Pages,必须显式声明:
contents: read:允许读取仓库代码pages: write:允许写入 Pages 服务id-token: write:用于生成 OIDC 身份令牌,部署 Pages 时需要验证身份
concurrency用于控制并发。group: "pages"表示所有推送到 main 分支触发的部署任务属于同一组,cancel-in-progress: false表示如果上一个部署还在进行中,新任务不会直接取消旧任务,而是排队等待。这个配置在团队多人协作时能避免发布冲突。
deployjob 里的四步,覆盖了“拉代码、配置 Pages、上传构建产物、发布”四个环节。actions/upload-pages-artifact@v3默认会从当前工作目录打包文件,并把CNAME文件纳入保留列表。如果你在仓库根目录放了自定义域名文件,这里会自动保留。
4.2 配置 Pages 的发布来源
写完 workflow 后,还需要在仓库设置中把 Pages 的发布来源改为 “GitHub Actions”。不修改这个设置,Pages 不会接受 workflow 的部署结果。
操作步骤:
- 打开仓库页面,点击
Settings - 左侧菜单找到
Pages - 在
Build and deployment区域,把Source从 “Deploy from a branch” 切换为 “GitHub Actions”
完成这一步后,GitHub 会提示没有最近部署记录,这是正常的。之后只要推送代码到 main 分支,workflow 就会开始执行,部署完成后这里会显示访问地址。
4.3 创建仓库环境配置
首次运行包含environment: github-pages的 workflow 时,GitHub 会创建一个名为github-pages的环境。你可以在Settings -> Environments中查看它。默认情况下这个环境没有保护规则,任何拥有仓库写权限的用户都能通过 workflow 部署。如果团队比较大,建议在这里添加Required reviewers保护,让关键分支的发布需要审核。
这一步不是必须的,但它能帮你理解 Pages 发布和 Actions 环境的关系。
4.4 运行与验证
把 workflow 推送到 GitHub 仓库:
git add .github/workflows/pages.yml git commit -m "feat: add pages deploy workflow" git push origin main推送完成后,打开仓库的Actions标签页,会看到一个名为Deploy static content to Pages的工作流正在运行。点击进去可以看到刚才定义的deployjob。job 的执行过程会显示四个步骤,每一步都有实时日志。
如果一切正常,最终步骤Deploy to GitHub Pages会输出一个page_url,类似:
https://<你的用户名>.github.io/actions-pages-demo/打开这个地址,你应该能看到之前写的 HTML 页面。如果看到了,说明你的 Actions 和 Pages 部署链路是完整的。
4.5 验证输出与状态码
有时候页面能打开,但 HTTP 状态码不理想。推荐用curl验证:
curl -I https://<你的用户名>.github.io/actions-pages-demo/正常响应应该类似:
HTTP/2 200 server: GitHub.com content-type: text/html; charset=utf-8如果返回200,说明发布成功。如果返回404,可能的场景是:仓库名和 Pages 的 URL 不匹配,或者自定义域名没有正确配置。如果返回502,则需要确认 GitHub 状态页面是否出现了 Pages 服务降级。
5. 服务降级时的高频问题与排查思路
5.1 Workflow 一直处于 queued 状态
这是 Actions 服务降级时最典型的表现。当你推动代码后,workflow 长时间停留在queued,既不开始执行,也不报错。
可能的原因:
- GitHub Actions 的后端调度队列繁忙
- 你的仓库是免费版本,而当前恰好处于平台的资源高峰期
- 并发任务数达到账户级或组织级限制
排查步骤:
- 到
https://www.githubstatus.com/查看 Actions 的当前状态 - 在 Workflow 运行页面点击
View workflow file,确认触发分支没有问题 - 打开
Actions -> Jobs -> queued,看是否有排队等待的提示 - 检查仓库设置中是否有并发限制配置
如果确认是平台侧问题,可以做的事情有限。你可以暂时把runs-on从ubuntu-latest改为ubuntu-22.04,有时特定镜像池的负载不同,能缓解排队问题。更稳妥的办法是在 workflow 中加入重试机制,比如使用retry步骤或第三方 Action 处理临时失败。
5.2 Pages 站点返回 502 或空白页
Pages 服务降级时,比较常见的现象是站点返回 502 网关错误,或者首次访问时空白、刷新后恢复正常。
排查思路:
- 先确认是 CDN 问题还是源站问题,可以用
curl查看响应头中是否包含server: GitHub.com - 在浏览器无痕窗口中打开站点,排除本地缓存干扰
- 检查仓库的
Actions标签页,确认最近的部署是否成功 - 检查
.nojekyll文件是否需要添加
这里补充一个容易忽略的坑:如果你的页面里有带下划线开头的目录或文件,GitHub Pages 默认会使用 Jekyll 构建流程,可能把它们忽略掉,导致页面引用资源 404。解决办法是在站点根目录添加一个空的.nojekyll文件,让 Pages 跳过 Jekyll 处理。
touch .nojekyll git add .nojekyll git commit -m "skip jekyll" git push origin main5.3 deploy-pages 步骤报错
deploy-pages步骤报错时,日志经常会提示Failed to create deployment或Invalid upload。这类错误有时和 Pages 服务本身有关,有时是配置问题。
常见的配置问题包括:
permissions缺少pages: writeenvironment: github-pages配错名称- 仓库未开启 Pages 或发布源未设置为 GitHub Actions
upload-pages-artifact上传的目录不存在
排查时可以按顺序检查:
- 在仓库
Settings -> Pages中确认 Source 是 GitHub Actions - 对比官方文档确认 workflow 中 permissions 字段
- 查看失败的 job 中
Setup Pages步骤的日志
5.4 常见问题速查表
| 问题现象 | 常见原因 | 解决思路 |
|---|---|---|
| Workflow 长时间 queued | Actions 调度高峰或平台降级 | 检查 GitHub 状态页;调整镜像版本或等待恢复 |
| Pages 返回 502 | Pages 服务降级或 CDN 回源异常 | 无痕访问;对照状态页确认时间点 |
| Pages 404 | 仓库名/分支/路径不匹配 | 核对站点 URL 与仓库名 |
| 部署成功但页面没更新 | CDN 缓存 | 等几分钟后强制刷新 |
| deploy-pages 报权限错误 | permissions 配置缺失 | 补上pages: write和id-token: write |
6. 最佳实践:如何让发布流程扛得住平台降级
6.1 设计可重试的部署流程
在 CI/CD 流程中,偶然的失败是常态,所以 workflow 应该具备重试能力。GitHub Actions 本身没有内置自动重试步骤的开关,但你可以通过两种方式实现:
一种是在命令行前加上重试逻辑,例如:
- name: Build site run: | for i in 1 2 3; do npm run build && break || sleep 5 done另一种是使用社区提供的重试 Action。考虑到安全性和可维护性,更推荐前者,因为不引入第三方依赖,行为透明可控。
6.2 日志与状态监控
服务降级最忌讳的是没有数据,你只能靠“感觉”判断。建议在 workflow 中加入一个简单的状态上报步骤,把部署结果推送到钉钉、飞书或 Slack。这里以一个发送到钉钉群机器人的示例来说明思路:
- name: Notify if: always() run: | curl -X POST "${{ secrets.DINGTALK_WEBHOOK }}" \ -H 'Content-Type: application/json' \ -d '{"msgtype": "text", "text": {"content": "部署完成,状态: ${{ job.status }}"}}'这里使用了if: always(),确保即使部署失败也会发送通知。job.status是 Actions 内置的变量,取值是success、failure或cancelled。
6.3 使用环境隔离与分支策略
在生产场景中,不建议直接在 main 分支上做完整部署。更稳妥的做法是:
dev分支:触发构建验证,不部署main分支:触发预览环境部署release分支:触发生产环境部署
对于 Pages 这样的静态托管服务,虽然多数场景是文档或展示站点,但这个习惯可以帮助你在 Actions 异常时不至于把坏版本发布出去。
6.4 关注官方状态页与公告
GitHub 官方状态页是https://www.githubstatus.com/,它提供 Actions、Pages、API 等服务的实时状态和事件历史。在遇到可疑问题时,先看状态页再排查自己代码,能节省很多时间。
另外,GitHub 官方博客也会发布详细的事后分析报告(post-incident report),通常会在故障解决后 5 到 7 天内发布。如果你所在团队高度依赖 GitHub 服务,建议订阅这些报告,了解降级的根因和后续改进措施。
6.5 提前规划降级预案
工程上有一个原则:没有预案的故障处理,永远是救火。针对 Actions 和 Pages 的降级,至少应准备:
- 构建机器的备用方案:本地构建命令需要保留,必要时本地构建后手动上传
- 静态站点的备用托管:可以考虑把构建产物同时上传到对象存储作为备份
- 发布账号的权限备份:确保除当前负责人外,还有其他成员拥有发布权限
这样即使 Actions 长时间不可用,你也可以通过手动方式完成发布,而不是等到恢复。
7. 总结与后续学习方向
本文围绕 GitHub Actions 和 GitHub Pages 服务降级问题展开,先梳理了两个服务在自动化部署链路中的定位,随后用一个完整的 Pages 部署 workflow 演示了从配置到发布的全过程。这个案例虽然不是高深技术,但它是理解 CI/CD 平台稳定性的好切入点:一次部署失败,原因可能既不是你代码的问题,也不是 Actions 用错了,而是平台的某个环节正在经历服务降级。
从工程角度,要真正降低平台不稳定带来的影响,重要的不是把配置背熟,而是掌握三件事:第一,能快速定位问题在哪个层面,是本机、仓库、还是平台;第二,能用一个最小可用的 workflow 快速复用,而不是每次从零开始;第三,有意识地设计重试、通知和备份方案,把“如果平台挂了怎么办”作为流程的一部分,而不是事后补救。
对 GitHub Actions 的深入学习,接下来可以关注几个方向:workflow 的缓存策略与依赖管理、矩阵构建(matrix strategy)在多个操作系统和语言版本下的并行测试、以及 GitHub 自托管的 runner 与 OIDC 联邦认证。这些内容都能让你在同一个平台上做更多自动化的事情。但不管依赖多深,始终记住一点:任何 CI/CD 服务都不是 100% 可用的,你的流程设计和代码质量,才是真正决定交付是否稳定的关键。
希望这份完整实操方案对你的项目和排错有所帮助。如果你在配置过程中遇到其他奇怪的报错,欢迎在评论区带着工作流代码和日志一起交流,我会尽量帮忙定位。