banner
My Posts

Github Acitons (二)

Scroll down

Github Actions 自动化部署(二)

这篇文章主要介绍用 Github Actions 自动化部署 Hexo。

1. 前景提要

  • 由于 Hexo 属于轻量级的静态博客,博客环境只能部署在本地,如果换一个电脑写博客的话只能在新电脑上重新配置一套完整的环境,十分麻烦。所以最近一直在想有没有什么简便(tou lan)的方法可以把这些环境打包起来,以便我在任何电脑上都可以直接写文章、发文章,没错,我说的不是 Docker ,而是我们的主角:Github Actions。

  • 说实话这个需求的实现我的第一反应就是:Docker,但是走到哪都得带着打包好的镜像实在不方便,镜像一丢都白搭,而且其实对于 Hexo 这种轻量级的框架,说白了就是安装一个 Node.js,折腾 Docker 有点不划算,它更适合部署类似于 WordPress 的 LNMP 环境,所以我差点整个推倒重来(hia hia)。换个思路,既然博客托管在 Github 上,那么有没有可以实现对仓库代码自动化部署的工具呢?经过一番了解,Travis CI 和 Github Actions 是最多的解决方案。

  • Travis CI 是 linux 平台的开源持续集成构建项目,开源项目免费使用,也是采用yaml格式来编写,使用的人很多,但是相比于同一个生态环境下的 Github Actions 在速度上要慢一些,而且 Travis CI 总是被墙,所以这里直接选择 Github Actions 省心一点。不得不说生态环境真的是很重要,虽然它起步晚,但是与 Github 一结合,把共享的玩法用到 actions 上,对私有项目也可以免费使用,发展速度迅速,对于大部分场景来说完全够用了。

2. 自动化部署 Hexo

  • 现在博客托管到 Github 的仓库是公开的,里面只有经过 Hexo 渲染可以直接发布的内容,所以还要新建一个博客源码仓库来存放博客源码,这里仓库类型设置为private,同时勾选Add a README file来完成仓库的初始化。

    1

  • 在终端输入以下命令生成部署密钥:

    1
    $ ssh-keygen -f github-deploy-key

    一路按回车,此时在当前目录下会生成一个公钥文件github-deploy-key.pub和一个私钥文件github-deploy-key

  • 复制私钥文件github-deploy-key的内容,到存放 博客源码 的仓库 Blog 里,在Settings --> Secrets and variables --> Actions --> New repository secret页面,粘贴到Value里,Name框填写HEXO_DEPLOY_PRI。这里必须要格外注意两个问题,否则后面 action 会报错Fatal: Could not read from remote repository.

    • 私钥文件github-deploy-key的内容是从-----BEGIN OPENSSH PRIVATE KEY-----开始,到-----END OPENSSH PRIVATE KEY-----结束,包括这两句话!一定不要少复制了,之前就是一直连接失败,排查了好久才发现是这个问题 @__@
    • 创建私钥的位置一定要严格按照上面的路径来,不要创建到别的地方去了,这里是部署密钥,不是与 Github 连接的那个账户密钥。
  • 复制公钥文件github-deploy-key.pub的内容,在博客所托管的仓库页面,按Settings --> Deploy keys --> Add deploy key路径添加,在Title里填写HEXO_DEPLOY_PUBKey里粘贴公钥内容(以ssh-rsa开头),最后勾选Allow write access选项添加完成。

  • 接下来把博客源码提交到仓库里面,这里也有几个细节需要注意:

    • node_modules文件夹和public文件夹不需要提交,所以建议把本地博客源码文件夹复制一份,把这两个文件夹删除后再提交。node_modules文件夹在安装完 Node.js 以后会自动生成,这个步骤在 Github Actions 提供的虚拟机里完成,public文件夹也同理,我们只需要提交单纯博客的源码(包括主题和文章相关)即可。
    • 在博客源码文件夹下,要先 pull,才能 push。因为本地仓库和远程仓库实际上是两个独立的仓库,如果是直接 clone 到本地的话就不会有这个问题。

    所以结合以上两点,切换到处理好的博客源码文件夹下执行以下命令:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    $ git init # 使该文件夹可以由 git 管理

    $ git add . # 把文件夹内容添加进去

    $ git commit -m "First Commit" # 把文件提交到仓库

    $ git remote add origin git@github.com:gyn-58/Blog.git # 关联到远程仓库

    $ git pull origin main -allow-unrelated-histories # 合并两个仓库的历史

    $ git push -u origin main # 第一次推送加上 -u 可以关联分支

    现在,博客源码已经提交到了远程 Blog 仓库。

  • 在 Blog 仓库根目录下创建.github/workflows/deploy.yml文件。目录结构如下所示:

    1
    2
    3
    4
    Blog  
    └── .github
    └── workflows
    └── deploy.yml

    然后编写deploy.yml配置文件:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    name: Hexo Auto Deploy

    on:
    # 当 push 到仓库的 main 分支时触发
    push:
    branches: [ "main" ]

    # 手动触发
    workflow_dispatch:

    # 环境变量
    env:
    GIT_USER: gyn-58
    GIT_EMAIL: gyunong@126.com
    DEPLOY_REPO: gyn-58/gyn-58.github.io
    DEPLOY_BRANCH: main

    # 任务
    jobs:

    build:
    name: Build on node ${{ matrix.node_version }} and ${{ matrix.os }}
    runs-on: ubuntu-latest
    # 策略,用于创建作业的构建矩阵
    strategy:
    # 用于访问为当前作业配置的矩阵参数
    matrix:
    os: [ubuntu-latest]
    node_version: [16.x]

    # 步骤
    steps:
    - name: Clone repository
    uses: actions/checkout@v2
    with:
    submodules: true # 可以获取子模块

    - name: Checkout deploy repo
    uses: actions/checkout@v2
    with:
    repository: ${{ env.DEPLOY_REPO }}
    ref: ${{ env.DEPLOY_BRANCH }}
    path: .deploy_git

    - name: Use Node.js ${{ matrix.node_version }}
    uses: actions/setup-node@v1
    with:
    node-version: ${{ matrix.node_version }}

    - name: Configuration environment
    env:
    HEXO_DEPLOY_PRI: ${{secrets.HEXO_DEPLOY_PRI}}
    run: |
    sudo timedatectl set-timezone "Asia/Shanghai"
    mkdir -p ~/.ssh/
    echo "$HEXO_DEPLOY_PRI" > ~/.ssh/id_rsa
    chmod 600 ~/.ssh/id_rsa
    echo 'Host github.com\nUser gyunong@126.com\nHostname ssh.github.com\nPreferredAuthentications publickey\nIdentityFile ~/.ssh/id_rsa\nPort 443' > ~/.ssh/config
    ssh-keyscan github.com >> ~/.ssh/known_hosts
    git config --global user.name $GIT_USER
    git config --global user.email $GIT_EMAIL

    - name: Install dependencies
    run: |
    npm install hexo-cli -g
    # 安装 Hexo 相关依赖
    npm install hexo-deployer-git hexo-asset-image hexo-generator-category --save

    - name: Deploy hexo
    run: |
    hexo clean
    hexo g -d
  • 现在简单编写一篇文章,放到博客源码文件夹内,用上面的步骤 push 到 Blog 仓库,可以看到 Github Actions 成功触发。

    2

  • 这样就通过 Github Actions 实现了对 Hexo 的自动化部署,当我在另外一台电脑上写博客时只需要把存放博客源码的仓库 clone 下来,写好以后再 push 上去就可以直接发布新文章,节省时间的同时也相当于对博客做了备份。

3. 图片

  • 在测试自动化部署的过程中发现如果我想在文章里面添加图片,原来本地环境下的方法是不行的。

  • 本地环境下通过修改 Hexo 配置文件里的post_asset_folder属性,在创建新的 post 时会自动创建一个同名文件夹,里面存放 post 用到的图片,通过相对路径进行引用。

  • 由上面的过程可以发现,Github Action 是在虚拟机环境下重新配置了 Hexo,它的配置文件属性与本地的并不一样,即使我通过命令语句更改它文件内的属性,图片仍无法加载。相对路径引用的方法只适合在本地环境下,环境一变它就很难加载出来,在 Hexo 官网也有网友提到了相关的问题:

3

​ Hexo 应该把 post 放在资源文件夹下,可惜它并没有这样做,所以只能通过图床的方法插入图片了。

  • 图床软件有很多,这里我选择的是 PicGo。本质上来讲它就是一个能快速把图片上传到云端的图形化界面,上传以后自动复制图片的 url ,通过 url 的方式来显示图片。PicGo 里面有腾讯云 COS、阿里云 OSS、Github、七牛云等图床可以选择。

  • 腾讯云 COS 即对象存储(Cloud Object Storage)是由腾讯云推出的无目录层次结构、无数据格式限制,可容纳海量数据且支持 HTTP/HTTPS 协议访问的分布式存储服务。其它图床的意思也是一样,这里直接选择 GitHub。

  • 建立一个专门存放图片的仓库 pictures ,在 Github 上按Settings --> Developer settings --> Personal access tokens路径,点击Generate new token生成 token 并粘贴到 PicGo 的图床设置页面:

4

  • 下次再插入图片时只需要把图片拖拽到 PicGo 的上传窗口,它会自动把图片的 url 复制下来,直接引用即可。
Other Articles