Hexo 实现 Github/Coding 持续集成

文章最初载于 szhshp 的第三边境研究所

转载请注明

开发背景

  1. 为知笔记的搜索太慢了。
  2. 我想要迁移笔记。
  3. 我想要迁移笔记。
  4. 我想要迁移笔记。
  5. 我想要迁移笔记。
  6. 我想要迁移笔记。
  7. 我想要迁移笔记。
  8. 我想要迁移笔记。
  9. 我想要迁移笔记。
  10. 我很需要迁移笔记。
  11. 为知笔记的搜索太慢了。
  12. 希望能有一个免费的笔记托管平台。

Github & Coding 的服务差异

主要配置:

  1. 一个 Source Repo, 用于存放源码
  2. 一个 Release Repo, 用于存放 build 之后的 pages 文件

Pages 服务的限制:

  • Github 的 pages 服务 repo 必须设置为开源, 因此 Source Repo 可以设置为闭源
  • Coding 的 pages 服务 repo 没有任何限制, 所以 两个都可以设置为闭源.

其他 CI/CD 服务的限制:

  • Travis 可以用于 Github, 但是不能用于国内的 Coding
  • https://travis-ci.org 不支持私有仓库, https://travis-ci.com 才支持选择私有仓库 (但是对于私有仓库只有 100 次次数限制)

最终决定:

  1. Github 端使用 Github Actions
  2. Coding 端使用新开放的 持续集成 功能, 类似 Github Actions

Hexo 站点搭建

(略)

Github 操作方法

主要目的:

  1. 创建一个 Github Action
  2. 当我 push 代码的时候自动 build
  3. 由于 hexo 自身就有用 deploy 的功能, 所以只需要在 push 的时候执行以下 hexo deploy 将生成的文件全部部署到 Release Repo
  4. 需要实现从 Source Repo 中提交到 Release Repo 的认证
  • 最大的麻烦就是这一步

认证模式: SSH

生成一对公钥和私钥

公钥放置在 请求操作端: 本机或者远程服务器 (一般放置在 .ssh/rsa_id)

私钥放置在 目标端, 可以放在两个地方:

  • 如果放置在用户级别的私钥处设置 (Github-Setting-SSH and GPG Keys), 那么可以不需要账号密码操作整个用户的所有 repo
  • 如果放置在单个 repo 的 deploy key 中, 那么如果拥有这个私钥, 就可以不需要账号密码操作单个 repo

设置 SSH

我们这里实现单个 repo 的 SSH 访问

首先本地使用 ssh-keygen 可以生成一个私钥, 一个公钥

首先跑到 bash 里面执行 ssh-genkey

如果是 windows 系统, 就可以直接跑到 ${GitDirectory}\usr\bin\ssh-keygen.exe 然后使用 管理员权限 + CMD 执行

最后生成了一个公钥 TESTKEY.PUB , 一个私钥 TESTKEY .

将生成的 私钥全部内容 (不要担心格式) 放置在 Source Repo 的 Serect 里面, 然后取一个名字, 比如我给他取名成 DEPLOY_KEY

然后将 公钥全部内容 放置到 Release Repo 的 Deployed Keys 里面, 并且要赋予读写的权限, 公钥的名字不重要

这个公钥并不是放置在用户的公钥设置里面, 我们仅仅对 Release Repo 进行操作

_config.yml 设置

这一段代码放置在 Source Repo 里面. 下方设置了对应的 Release Repo 的名字以及对应的分支名字.

deploy:
  type: git
  repo: git@github.com:szhielelp/notebook-release.git # 改成你自己的 repo 地址,需要设置 SSH 地址。
  branch: master # 改成你自己的分支名称。

设置完之后本地测试一下

hexo d

因为对应的私钥同时也保存在本地, 所以应该可以部署成功.

创建 Github Action

跑到 Github Action 的页面创建一个新的 action, 然后这个 action 就会被放置在 Repo 的根目录的 .github/workflows/nodejs.yml 文件夹下面

name: Notebook Deployment

on: [push]

jobs:
  build:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        node-version: [10.x]

    steps:

      - name: Deployment Start

        uses: actions/checkout@v1

      - name: Setup Node ${{matrix.node-version}}

        uses: actions/setup-node@v1
        with:
          node-version: ${{matrix.node-version}}

      - name: Setup Git Env

        env:
          DEPLOY_KEY: ${{secrets.DEPLOY_KEY}} # 这里写上刚才在 Secret 里面设置的变量名
        run: |
          mkdir -p ~/.ssh/
          echo "$DEPLOY_KEY" > ~/.ssh/id_rsa # 将私钥的全部内容输出到一个文件里面。
          chmod 600 ~/.ssh/id_rsa # 修改对应私钥文件的权限。
          ssh-keyscan github.com >> ~/.ssh/known_hosts # 将 Github.com 添加到已知文件列表。

          git config --global user.name "你的 Github 用户名" # 设置一下提交的姓名和邮箱。
          git config --global user.email "你的 Github 邮箱"

      - name: Setup Hexo CI

        run: |
          npm i -g hexo-cli # 全局安装需要的库。
          npm i

      - name: Setup other package

        run: |
          npm install

      - name: Deploy

        run: |
          rm -rf .deploy_git
          hexo g && hexo deploy # 开始部署
          rm ~/.ssh/id_rsa

Coding 操作方法

主要目的基本相同, 但是选用的一个完全不同的认证方法

SSH 认证模式的问题

理论上按照 github 的模式可以实现, 但是 SSH 模式请求的时候一直报 Permission denied (publickey)

我说尝试过的方法:

  1. 修改权限为 7, Github 上方脚本里面设置的权限为 6
  2. 生成一对完全不同的新的公钥
  3. 使用 ssh-add 将添加公钥到设备
  4. 公钥对于 git.coding.net 无效,应该改成 e.coding.net

最终发现用户级别公钥可以实现本地的部署, 但是无法实现 repo 之间的部署, 一直出现 Permission denied (publickey)

最终决定选用另一种认证方式.

2020-03-23 更新: Alliot 同学实现了 SSH 认证方法, 但是他是最终通过 scp 提交到他自己的服务器。和我的需求不同, 有需要可以查看一下: https://www.iots.vip/post/hexo-coding-ci-scp-server.html

认证模式: Token

  1. 首先创建一个 token

  2. 是在 repo - 开发者选项 - 项目令牌里面生成

    • 这个东西生成一次就无法再看到了, 一定要复制保存
  3. Token 也可以放在两个地方: 一个是用户级的 Token 可以操作所有 Repo, 一个是 Repo 级的 token 只能操作单个 repo

Config.yml 设置

同样的, 在 Source Repo 那边设置:

注意, 下方需要设置的是 HTTPS 的链接, 然后需要将你得到的 token 的账号密码扔进去.

deploy:
  type: git
  repo: https://[token name]:[token password]@e.coding.net/szhshp/szhshp-notebook-release.git
  branch: master

同样现在本地测试一下, 这种模式上并没有使用任何的 SSH 访问, 直接就可以部署成功

创建持续集成任务

因为这个地方没有使用 SSH 访问, 并且 token 已经设置到了上方的链接当中, 直接 push 即可.

pipeline {
  agent any
  stages {
    stage('检出') {
      steps {
        checkout([$class: 'GitSCM', branches: [[name: env.GIT_BUILD_REF]],
        userRemoteConfigs: [[url: env.GIT_REPO_URL, credentialsId: env.CREDENTIALS_ID]]])
      }
    }
    stage('构建') {
      steps {
        echo '构建中。..'
        sh '''

git config --global user.name szhshp
git config --global user.email szhshp@sina.com

npm i -g hexo-cli
npm i

rm -rf .deploy_git
hexo g && hexo deploy
'''
        echo '构建完成。'
      }
    }
  }
  environment {
    HOSTINFO = 'Host coding.net     IdentityFile ~/.ssh/id_rsa.coding     User szhshp'
  }
}

Troubleshoot

版本不同

建议在脚本的前三行写上, 这样调试的时候可以先确定是否是因为版本不同的问题导致的。

node -v
npm -v 
yarn -v

Hint-考虑使用 cnpm 或 yarn

本身在本地调试的时候使用 cnpm 下载一些库 (比较典型的就是 sass 的 loader) 就非常慢, 换到 Coding 服务器用 npm 可能也很慢.

因此在这个时候可以考虑一下在扣钉上使用 cnpm 或者 yarn, 一个 cnpm 的例子:

下面这一段是放到可视化编辑框里面的, 如果直接粘贴到 Jenkin 脚本, 记得将里面的单引号进行转义。

cd clientV2
npm install cnpm -g
cnpm install
cnpm run build
git clone https://{token name}:{token pswd}@e.coding.net/szhshp/notebook/release.git
mv dist/* release/
cd release
git config user.email "szhshp@sina.com"
git config user.name "szhshp"
git add -A
git commit -a -m "Build & Release"
git push

另外也可以考虑换用 yarn

Nice Work !!!

花了我三天, 搞定了累死我了

Coding 单 Repo 多仓库操作方法

Coding 更新后, 一个项目里面可以有多个仓库

实际上就是多个 Repo

在这种情况下完全可以只用一个项目控制 Source RepoRelease Repo

处理方法很简单:

  1. 因为是同一个 Repo, 在 Repo 里面创建一个项目 Token
  2. 将 _config.yml 里面 deploy 一列的 repo 改为 release 仓库对应的 HTTPS 连接, 记得带上 token
deploy:
type: git
repo: https://{token name}:{token pswd}@e.coding.net/szhshp/szhshp-notebook/release.git
branch: master
  1. CI 脚本如上文设置 Coding 操作方法
  2. 这样子以后就不需要了来回跑两个不同的 repo 了

参考文献

posted @ 2020-10-18 14:49  szhielelp  阅读(252)  评论(0编辑  收藏  举报