目录

GitHub Actions

GitHub Actions 提供了直接在 GitHub 仓库中创建软件生命周期工作流(workflow)的功能,极大地方便了持续集成、持续部署的实现。

GitHub 做了一个官方市场,可以搜索到他人提交的 actions。另外,还有一个 awesome actions 的仓库,也可以找到不少 action。

思路

基本思路是在每次 push 到 GitHub 之后触发 Actions 将最新代码 checkout 到GitHub Actions虚拟环境中并开始构建,构建成功后通过 rsync 同步部署到 VPS 或云服务器:

sequenceDiagram;
    Local-->>tsingchan/9ong.git: push
    tsingchan/9ong.git-->>GitHubActions:checkout
    GitHubActions-->>vps:rsync
    

GitHub Actions设置

  • 1、自定义workflow

    点击 Actions 按钮,我们可以看到,我们可以自己去配置自动化所需要的步

    在项目的根目录下,新建 /.github/workflows/main.yml, 此处 yml 的文件名可以随意取名,在push后,github action会自动读取 workflows 文件夹内部 yml 文件

  • Edit new file

    Github 默认的自动化部署步骤,是直接上传到了 Github Actions ,会生成一个网站查看,因我们是实现自己服务器的自动化部署,所以,将下面代码替换为以下代码

    name: publish 9ong
    
    on:
    push:
        branches:
        - master  # master分支提交的时候的触发github actions
        paths-ignore: # 下列文件的变更不触发部署,可以自行添加
        - 'archetypes/**'
        - 'myscript/**'
        - 'todo/**'
        - 'todo-done/**'
        - '.gitignore'
        - 'qiniu-sync.py'
    
    jobs:
    #job 名字,不能带有空格
    build-and-deploy: 
        #vps或云服务器操作系统 cat /proc/version
        runs-on: ubuntu-16.04  
        steps:
        #用第三方action,用于checkout代码到actions的虚拟环境下
        - uses: actions/checkout@v2 
            with:
            # 如果主题作为子模块存在于主仓库中,需要submodules:recursive,也就是递归检出
            #submodules: true 
            # Fetch all history for .GitInfo and .Lastmod 
            fetch-depth: 0    
    
        # 安装hugo # 使用第三方的action,用于安装hugo # 指定安装hugo的版本 # 是否使用hugo的扩展
        - name: Setup Hugo 
            uses: peaceiris/actions-hugo@v2  
            with:
            hugo-version: '0.70.0'  
            extended: true 
    
        # 构建编译静态站点
        - name: Build 
            # 这里直接默认编译生成静态站点,会在当前目录生成public目录
            run: hugo 
    
        # 使用第三方action,用于ssh私钥缓存  secrets.BLOG_DEPLOY_KEY这个变量会在github项目setting->secret中设置,后面介绍
        - uses: webfactory/ssh-agent@v0.4.1 
            with:
            ssh-private-key: |
                ${{ secrets.BLOG_DEPLOY_KEY }}
    
        # 使用 ssh-keyscan 命令扫描我们服务器的公钥并保存到github actions虚拟环境的 ~/.ssh/known_hosts 中,用于工作流的无人值守
        - name: Scan public keys
            run: |
            ssh-keyscan ${{ secrets.BLOG_DEPLOY_HOST }} >> ~/.ssh/known_hosts            
    
        # 部署 通过rsync将虚拟环境下编译好的public目录同步到我们的服务器指定目录下。rsync --delete会删除目的目录中不在源目录中的文件。
        - name: Deploy
            run: |
            rsync -av --delete public jm@${{ secrets.BLOG_DEPLOY_HOST }}:/var/www/html/9ong-html-new
    
    
  • 3、Start commit 提交

  • 4、添加环境变量

    以上github actions workflow中使用到了两个环境变量:secrets.BLOG_DEPLOY_HOST 和 secrets.BLOG_DEPLOY_KEY 。

    这里BLOG_DEPLOY_KEY需要先生成SSH密钥,可以参考下一节生成SSH密钥

    比如:name为BLOG_DEPLOY_HOST,value为47.47.47.47,name和value以自己实际情况为准。

生成SSH密钥

在Deploy部署环节,需要使用 rsync(基于 SSH)连接到 VPS,因此使用 ssh-keygen 命令生成一对密钥(推荐使用 ed25519 算法)。注意此对密钥不能加密码保护(passphrase),以便在工作流中无人值守。此步骤可在任意一台支持 ssh-keygen 命令的设备上完成,但注意密钥不要泄露,因为没有密码保护。

ssh-keygen -t ed25519 -f ~/.ssh/9ong_deploy_key

再将公钥 ~/.ssh/9ong_deploy_key.pub 的内容添加到 VPS 的 ~/.ssh/authorized_keys 中,将私钥 ~/.ssh/9ong_deploy_key 的内容添加到 GitHub 仓库的 Settings -> Secrets 中并命名为 BLOG_DEPLOY_KEY。

就可以在工作流中以环境变量 ${{secrets.BLOG_DEPLOY_KEY}} 的形式使用私钥,而不需要将私钥内容直接贴在工作流中。

环境变量${{secrets.BLOG_DEPLOY_HOST}}同理。

测试效果

自动化部署到腾讯云serverless

静态网站托管 自动化部署 - 最佳实践 - 文档中心 - 腾讯云

问题

  • 在部署环节时长较长,可能同步文件较多,rsync的v选项可以查看,但可能会导致该步骤执行太久,我们自己测试没有查看详情时,几十秒就执行完了。

    rsync -av --delete public jm@${{ secrets.BLOG_DEPLOY_HOST }}:/var/www/html/9ong-html-new
    
  • rsync同步时,如果使用root用户可能会遇到权限问题

    可以尝试换成其他用户,毕竟root会涉及太多安全问题。

参考

GitHub Actions 入门教程 - 阮一峰的网络日志

rsync 用法教程 - 阮一峰的网络日志