如何使用GitHub Actions实现Next.js全自动部署
今天就给大家分享如何使用GitHub Actions实现Next.js项目的全自动部署,其中涵盖了整体流程、触发条件、权限设置、并发控制等关键内容,欢迎大家交流探讨。
一、遇到的问题及解决方案
之前在项目部署时,我碰到过一个让人头疼的问题。提交代码后满心期待着自动部署能顺利完成,可等了好久,浏览器访问时页面却一直没更新。后来才发现,原来是自动部署居然没进行编译。项目有段时间没更新了,我都把这茬给忘了。为了避免下次再犯同样的错误,我决定把部署流程改成自动编译加自动部署。正好当时改版本号就得发一次版本,操作起来有点繁琐,我就想着干脆把自动更新版本号也加进去。于是,最终确定了“自动编译 + 自动部署 + 自动更新版本号”的方案。下面就详细讲讲这个工作流的配置和流程。配置文件地址在:github.com/infinilabs/…
二、全自动部署整体流程
整个工作流主要分为两个阶段,构建阶段和部署阶段。通过这两个阶段,实现了从代码更新到网站即时上线的全过程自动化。
- 构建阶段:在Ubuntu环境里,先把代码拉取下来,接着自动检测项目用的是哪种包管理工具,然后安装项目依赖,构建Next.js项目,生成静态文件。同时,还增加了更新版本信息的步骤,这样站点数据就能随时显示最新版本。
- 部署阶段:把构建好的静态文件上传成artifact,再借助GitHub Actions自动发布到GitHub Pages。
三、触发条件与权限设置
- 触发条件
在配置文件里设置了两种触发方式,这两种方式能满足不同场景的需求。- Push事件:只要代码推送到
main
分支,部署流程就会自动启动。 - 手动触发:要是遇到特殊情况,比如调试或者应急处理,还能在GitHub Actions页面手动启动部署流程,这个功能对应的是
workflow_dispatch
。
- Push事件:只要代码推送到
- 权限配置
permissions: contents: read pages: write id-token: write
这段代码是用来配置权限的。这里给GITHUB_TOKEN
分配的是最小权限,这样在拉取代码、发布Pages以及进行身份验证时,工作流都能获得必要的权限,同时又保证了安全性。
四、并发控制
为了防止部署过程出现混乱,使用concurrency
进行并发控制。
concurrency: group: "pages" cancel-in-progress: false
这样配置之后,同一时间只会有一个部署任务在运行。要是有多个部署任务排队,也不会出现互相干扰的情况,能保障生产环境稳定运行。
五、构建阶段详细步骤
- Checkout与包管理检测
- Checkout:通过
actions/checkout@v4
这个动作,把仓库里的代码克隆到运行环境,这样后续操作就能基于这些代码展开。 - Detect package manager:这个步骤是检查项目根目录下有没有
yarn.lock
或者package.json
文件。如果有yarn.lock
,就说明用的是Yarn包管理工具;要是有package.json
,大概率用的是NPM。然后根据检测结果输出对应的命令和runner参数。这种自动检测的方式,不管项目用哪种包管理工具,工作流都能适用。
- Checkout:通过
- Node环境与缓存配置
- Setup Node:利用
actions/setup-node@v4
配置指定版本的Node.js,并且根据前面检测到的包管理工具启用缓存。这样在安装依赖的时候,速度会快很多。 - Restore cache:借助
actions/cache@v4
缓存.next/cache
目录,用锁文件和源码哈希作为缓存的key。这么做的好处是,只要源代码或者依赖有变化,缓存就能自动更新,同时还能加快构建速度。
- Setup Node:利用
- 更新版本信息
新增了一个“Update data.json with latest version”的步骤,具体操作如下:- 获取版本数据:使用
curl
从https://release.infinilabs.com/.latest
拉取最新的版本信息,这个信息是以JSON格式返回的。 - 提取版本号:通过
jq
工具分别提取"coco-app"
和"coco-server"
的版本号,然后把这两个版本号存到APP_VERSION
和SERVER_VERSION
这两个变量里。 - 校验版本格式:用正则表达式检查版本号是不是符合
数字.数字.数字-数字
这种格式。要是不符合,就报错并且退出操作,这样能防止把无效数据写入文件。 - 更新data.json:再用
jq
把提取到的版本号写入到public/data.json
里的.app
和.server
字段。为了保证操作的原子性,先写到临时文件,再替换原文件。这样每次构建的时候,data.json
这个文件里的版本信息都是最新的,方便前端展示或者调试。
- 获取版本数据:使用
- 安装依赖与构建
- Install dependencies:根据之前检测到的包管理工具,自动执行相应的安装命令,安装项目所需要的各种依赖。
- Build with Web:运行
next build
命令来完成项目构建。这里用到了前面配置的runner
参数,保证命令能按照当前包管理工具的规范顺利执行。
- 部署前的准备工作
在生成静态文件的./out
目录下,还需要做两个额外操作:- 添加CNAME文件:执行
echo "coco.rs" > ./out/CNAME
命令,这是为自定义域名做准备。添加这个文件后,GitHub Pages就能正确解析自定义域名coco.rs
了。 - 禁用Jekyll:创建一个
.nojekyll
文件,这是告诉GitHub Pages不要用Jekyll去处理静态文件,避免出现文件解析错误。
最后,通过actions/upload-pages-artifact@v3
把构建好的静态文件作为artifact上传,为接下来的部署阶段做好准备。
- 添加CNAME文件:执行
六、部署阶段具体操作
部署阶段设置了一个叫deploy
的job,并且让它依赖于构建阶段(needs: build
),只有构建成功了才会进行部署,主要步骤如下:
使用actions/deploy-pages@v4
这个动作,把之前上传的artifact部署到GitHub Pages。部署成功后,工作流会输出页面URL,并且关联到github-pages
环境。这种把构建和部署分开的方式,流程清晰明了,要是哪个阶段出了问题,单独调试也很方便。
七、总结
利用GitHub Actions把Next.js项目自动化部署到GitHub Pages,好处多多。它不仅帮我们省去了繁琐的手动操作,还实现了持续集成与持续部署(CI/CD)。在这个工作流配置里,我们学会了自动检测项目的包管理工具,配置Node.js环境和缓存机制来提高构建效率,更新版本信息让public/data.json
始终保持最新状态,生成静态导出文件并通过CNAME和.nojekyll
文件进行个性化配置,最后把静态文件自动部署到GitHub Pages上。对于那些只需要静态内容,不依赖后端服务的Next.js项目来说,这种部署方式成本低、效率高,代码一更新,网站就能自动上线。希望这篇文章能帮助大家更好地理解和应用自动部署流程。