开发专栏
使用 GitHub Actions 自动部署 Nuxt 站点到 GitHub Pages
8 个月前
1019
Nuxt.js Vue 快速入门 配置 GitHub 全自动狂潮

通过 GitHub Actions 来避免繁琐的手动生成-复制-发布动作,只需将源代码提交即可自动触发生成静态文件并更新 GitHub Pages。

背景

GitHub Pages 相信大家都不陌生,它是 GitHub 推出的一项静态站点托管服务,能将 GitHub 仓库中的 HTML、CSS 等发布为网站,也可以通过 Jekyll 将 Markdown 创建为静态网站。让没有主机的人,可以把产品的首页、个人博客免费托管在 GitHub Pages 上。GitHub Pages 还提供了二级域名,个人首页为 https://username.github.io,项目首页为 http://username.github.io/repository

GitHub Actions 则是 GitHub 前段时间推出的自动化流程工具,可以用于执行 CI/DI (持续集成和持续部署)作业等。

Nuxt 经常读我博客的朋友一定都很熟悉了,我的博客就是使用 Nuxt 开发的,它是一款基于 Vue.js 的 Web 框架,提供了包括 SSR(服务器端渲染)、静态化等功能。

通常而言,GitHub Pages 可以通过已经编写好的静态 HTML 以及 Markdown 生成,这就意味着如果我们的站点是使用诸如 Vue.js 这样动态化的技术开发的话,GitHub Pages 是无法正确处理 .vue 这样的文件的,必须经过编译(例如执行 npm run build)生成 HTML 和 JavaScript 等文件才可以部署到 GitHub Pages 上。

每次修改网站内容后还得手动 build 并将生成的内容 commit 到相关仓库中,繁琐且不够智能,不过正好可以借助 GitHub Actions 来自动化这个步骤。

改进思路

思路很简单,准备两个仓库,一个用于存放 Nuxt 站点源代码,另一个用于存放生成好的静态文件。当我们修改了源代码的仓库后,触发 GitHub Actions 的构建动作,并将构建生成的静态文件提交到静态文件仓库即可。

本文以自动生成个人首页 huhubun.github.io 这个站点为例,站点源代码仓库为 https://github.com/huhubun/huhubun.github.io-source,静态文件仓库为 https://github.com/huhubun/huhubun.github.io,最终效果可以访问 https://huhubun.com/ 查看。

创建仓库

首先将上述的两个仓库创建好:

  • huhubun.github.io 仓库:用于存放生成的静态文件。因为是个人首页,仓库名称要满足 GitHub Pages 的命名规范 username.github.io
  • huhubun.github.io-source 仓库:用于存放站点的源代码。在站点名称后面增加了 -source 后缀,便于区分。Nuxt 项目的页面代码往这里提交

站点创建好后,将源代码提交。

为静态文件仓库启用 GitHub Pages

默认情况下 GitHub Pages 是不激活的,打开 GitHub 网页,进入静态文件仓库后点击 Settings 进入仓库的设置页面。往下滚动网页找到 GitHub Pages 部分,点击 Source 下拉菜单,将其从 None 修改为 master 即可。

GitHub Pages 配置页面

如果你不想使用 GitHub 的二级域名,可以在这里添加一个自己的域名,具体方式这里不再赘述,可以参考 GitHub 文档 Configuring a custom domain for your GitHub Pages site

创建 access token

为了能让 GitHub Actions 拥有访问仓库和提交代码的权限,我们需要先创建一个 access token。

从 GitHub 右上角头像处的下拉菜单,选择 Settings - Developer settings - Personal access tokens。然后点击右侧的 Generate new token 按钮,进入 New personal access token 界面。在 Note 文本框中输入 token 的用途,并勾选 Select scopes 区域中的 repo 前的复选框。

创建 access token

创建好后及时将页面显示的 token 复制下来,之后不会再显示,如果没复制下来重新创建一个就行。

配置 repository secret

复制好 token 后,通过 GitHub 网站进入用于提交源代码的仓库,依次进入 Settings(注意是仓库的 Settings) - Secrets,点击右侧的 New repository secret 按钮,进入 New secret 界面。在 Name 文本框中输入 DEPLOY_KEY,然后在 Value 文本域中粘贴刚刚复制的 token,接着点击 Add secret 按钮完成添加。

创建 repository secret

编写 GitHub Actions 工作流配置文件

创建工作流文件

创建工作流文件

在本地打开源代码项目,并在根目录下创建 .github 文件夹,然后在 .github 文件夹中创建 workflows 文件夹,然后再在 workflows 文件夹中创建 deploy.yml 文件。GitHub Actions 将按照这个文件里的配置进行工作,下面开始编辑这个文件。

首先为我们的工作流添加一个名字,例如叫 Deploy huhubun.github.io

name: Deploy huhubun.github.io

我希望在提交代码后就触发工作流,通过 on 命令进行配置:

on: [push]

配置 Node.js 环境

我们的站点使用 Nuxt 开发,和本地运行时一样,需要向 GitHub Actions 的容器提供 Node.js 环境。使用 GitHub 提供的 setup-node 步骤即可:

jobs:
  main:
    runs-on: ubuntu-latest
    steps:
    - name: Setup Node.js
      uses: actions/setup-node@v1
      with:
        node-version: '12'

我们还可以将相关信息打印到 log 中,便于排除问题时使用,例如这里通过 run 执行了输出 node 和 npm 版本的命令:

    - name: Verify Node.js
      run: node --version

    - name: Verify npm
      run: npm -v

Checkout 源代码仓库

接着需要将源代码 checkout 到 GitHub Actions 的容器中,使用现成的 actions/checkout 步骤即可:

    - name: Checkout source
      uses: actions/checkout@v2
      with:
        path: source

因为 checkout 的是当前项目,所以不需要配置任何路径。需要注意的是,path 节点表示将代码 checkout 到 GitHub Actions 容器的 source 文件夹中,如果没有这个文件夹会自动创建。

生成静态文件

源代码到手,接下来就是生成静态文件了,Nuxt 默认使用 generate 命令生成静态文件。不过别忘了,需要先 cdsource 文件夹,以及安装相关依赖:

    - name: Generate
      run: |
        cd ./source
        npm install
        npm run build
        npm run generate

Checkout 站点仓库

接着把站点仓库也 checkout 到容器中:

    - name: Checkout huhubun.github.io site
      uses: actions/checkout@v2
      with:
        repository: huhubun/huhubun.github.io
        path: site
        token: ${{ secrets.DEPLOY_KEY }}

和 checkout 源代码仓库不同的是:

  • 因为不是当前仓库,所以需要指定 repository,格式为 owner/repository-name
  • 设置另一个独立的目录名称,这里使用了 site
  • 需要用到之前创建的 access token。DEPLOY_KEY 就是前面步骤在 Repository Secret 部分设置的名称。通过 ${{ }} 语法可以访问 secrets 对象,并将 DEPLOY_KEY 的值设置给 token 节点。全程不会泄露我们的 access token

更新站点仓库

静态文件生成好了,站点也 checkout 完成,可以把生成好的文件复制到站点文件夹中了。

    - name: Copy generated file to site
      run: cp -r ./source/dist/. ./site

虽然生成静态文件时,我们使用了 cd 命令进入了 source 文件夹,但当这个步骤完成,新的步骤开始后,又会回到默认的工作目录,不会保持在 source 文件夹中。所以使用 cp 命令时可以直接从当前文件夹层级来访问 sourcesite 两个文件夹。

提交更新后的站点

只差最后一步,把站点提交就大功告成,这里直接使用 git 命令来操作:

    - name: Push site
      run: |
        cd ./site
        git config user.name github-actions
        git config user.email github-actions@github.com
        git add .
        current_time=`date '+%Y-%m-%d %H:%m:%S'`
        git commit -m "Update at $current_time"
        git push
  • 首先切换到 site 文件夹中
  • 配置 git 的用户名和 email
  • 别忘了执行 git add . 以及 git commit 添加提交记录。因为使用的是 linux 主机,和 bash 脚本一样,可以创建变量等。这里创建了名为 current_time 的变量用于将更新时间写入的提交记录中
  • 最后 git push 将内容推送到服务器上

到这里工作流文件就编写完成了,完整文件可以参考 https://github.com/huhubun/huhubun.github.io-source/blob/master/.github/workflows/deploy.yml

查看 Actions 的执行状态

保存好文件,并推送到源代码仓库中,就会立即触发 push 事件,执行我们上面编写的工作流。

查看 Actions 的执行状态

我们可以打开 GitHub 网页,进入源代码仓库 - Actions 页面查看执行的情况。当看见可爱的绿色✔出现时,则说明执行完成。

由于 GitHub Pages 更新站点有一定延迟,虽然 Actions 执行完成,静态文件仓库也更新了,但站点可能尚未更新,稍等片刻后再访问我们的站点,就能发现已经有内容了~

以后网页内容如果发生了变化,我们只需要往源代码仓库中提交代码即可,剩下的 GitHub Actions 会自动的帮我们完成,省时省力 get~