惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

博客园 - 叶小钗
D
Darknet – Hacking Tools, Hacker News & Cyber Security
S
SegmentFault 最新的问题
博客园 - 三生石上(FineUI控件)
雷峰网
雷峰网
WordPress大学
WordPress大学
有赞技术团队
有赞技术团队
博客园 - 【当耐特】
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
V
V2EX
V
Visual Studio Blog
酷 壳 – CoolShell
酷 壳 – CoolShell
博客园 - 聂微东
P
Proofpoint News Feed
Last Week in AI
Last Week in AI
U
Unit 42
W
WeLiveSecurity
博客园 - Franky
Recent Announcements
Recent Announcements
Hacker News - Newest:
Hacker News - Newest: "LLM"
Attack and Defense Labs
Attack and Defense Labs
月光博客
月光博客
The Cloudflare Blog
Spread Privacy
Spread Privacy
腾讯CDC
P
Privacy International News Feed
N
News and Events Feed by Topic
AWS News Blog
AWS News Blog
NISL@THU
NISL@THU
T
Troy Hunt's Blog
小众软件
小众软件
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
Microsoft Security Blog
Microsoft Security Blog
L
Lohrmann on Cybersecurity
Webroot Blog
Webroot Blog
Y
Y Combinator Blog
量子位
P
Palo Alto Networks Blog
N
News and Events Feed by Topic
V
Vulnerabilities – Threatpost
K
Kaspersky official blog
IT之家
IT之家
T
Threat Research - Cisco Blogs
Cloudbric
Cloudbric
云风的 BLOG
云风的 BLOG
C
Check Point Blog
Blog — PlanetScale
Blog — PlanetScale
爱范儿
爱范儿
G
Google Developers Blog
S
Secure Thoughts

szhshp 的第三边境研究所

假设, AI 把我代替的那一刻真的到来 | szhshp 的第三边境研究所 小傻瓜都能懂的 AstrBot QQ 机器人集成 MCP 功能实战指南 | szhshp 的第三边境研究所 《智人之上: 从石器时代到 AI 时代的信息网络简史》阅读笔记 | szhshp 的第三边境研究所 iPadOS 26 无法设置空间场景图片壁纸的解决方法 | szhshp 的第三边境研究所 《一路云海》(终) | szhshp 的第三边境研究所 《一路云海》(四): 如何不按套路旅行 | szhshp 的第三边境研究所 《一路云海》(三): In Ya Mellow Tone | szhshp 的第三边境研究所 《一路云海》(二): 关西世博参观纪实 | szhshp 的第三边境研究所 《一路云海》(一): 新的征程 | szhshp 的第三边境研究所 2025 大阪世博会 [ 3 天前-先到先得 ] 阶段 场馆预约必中独家攻略 | szhshp 的第三边境研究所 Hackathon 随想 | szhshp 的第三边境研究所 一杯双皮奶 | szhshp 的第三边境研究所 Armbian + CasaOS + NAS 配置指南 | szhshp 的第三边境研究所 Docker 构建镜像报错: error getting credentials - err: exit status 1, out: `` | szhshp 的第三边境研究所 Disqus RIP! 论过高的维护成本如何治疗固执的坏习惯 | szhshp 的第三边境研究所 炸弹猫桌游变体规则 | szhshp 的第三边境研究所 《小岛经济学》阅读笔记 | szhshp 的第三边境研究所 《金钱心理学》阅读笔记 | szhshp 的第三边境研究所 为知笔记 RIP: 迁移剩余的笔记 | szhshp 的第三边境研究所 2025 博客第十年展望 - 再见我的过去 | szhshp 的第三边境研究所 我在独立游戏里面致敬的作品 | szhshp 的第三边境研究所 《How to make thing faster》阅读笔记 | szhshp 的第三边境研究所 《The Art of Clean Code》阅读笔记 | szhshp 的第三边境研究所 《Clean Architecture: A Craftsman Guide to Software Structure and Design》阅读笔记 | szhshp 的第三边境研究所 《How AI Works》阅读笔记 | szhshp 的第三边境研究所 游戏策划废案 - Project Uranus | szhshp 的第三边境研究所 游戏策划废案 - Project X | szhshp 的第三边境研究所 人生第一款独立游戏开发复盘 | szhshp 的第三边境研究所 Trap of Life | szhshp 的第三边境研究所 如果我用手搓了个暗物质雏形 | szhshp 的第三边境研究所 《Rust Programming Language》- EX - Cheatsheet | szhshp 的第三边境研究所 新的播放器上线了 | szhshp 的第三边境研究所 Cypress - End-to-End Testing: OKTA Authentication with MFA | szhshp 的第三边境研究所 VSC x VIM - 反正多学几个快捷键没有坏处 | szhshp 的第三边境研究所 两小时 Docker 速成 - Getting Started | szhshp 的第三边境研究所 《The Joy of Javascript》- 5 - Data | szhshp 的第三边境研究所 《The Joy of Javascript》- 4 - Meta Programming | szhshp 的第三边境研究所 《The Joy of Javascript》- 3 - ADT(Algebraic Data Type) | szhshp 的第三边境研究所 Web-Automation Testing | szhshp 的第三边境研究所 《The Joy of Javascript》- 2 - Functor/Monad | szhshp 的第三边境研究所 《The Joy of Javascript》- 1 - Object/Function | szhshp 的第三边境研究所 EvalError: Possible side-effect in debug-evaluate | szhshp 的第三边境研究所 前端 QA 工具链指南 - husky,commitlint,commitizen,eslint,typescript,express | szhshp 的第三边境研究所 效率工具 & 软件推荐 | szhshp 的第三边境研究所 站点开源 Project Titan | szhshp 的第三边境研究所 cmd/powershell-命令速查-Cheatsheet | szhshp 的第三边境研究所 Git-命令速查与相关问题解决-Cheatsheet & Troubleshooting | szhshp 的第三边境研究所 Tailwind.css not included in NextJS Production | szhshp 的第三边境研究所 Github GraphQL API - Data Integration | szhshp 的第三边境研究所 尝试 Windows Terminal + z.lua | szhshp 的第三边境研究所 StrokePlus.net - Powerful Hotkey Boost | szhshp 的第三边境研究所 优雅地 Hack 一台黑苹果 | szhshp 的第三边境研究所 一杯关东煮 | szhshp 的第三边境研究所 Gitee x PicGo 管理图床 | szhshp 的第三边境研究所 Create Your Own Redux (Typescript) | szhshp 的第三边境研究所 Getting Started: Ionic + Capacitor + React + Typescript + Android | szhshp 的第三边境研究所 GraphQL: File Upload & Troubleshooting | szhshp 的第三边境研究所 吉祥航空随心飞刷票工具循环查票工具 | szhshp 的第三边境研究所 NVM Windows Portable Installation | szhshp 的第三边境研究所 NextJS x Typescript - Integration & Troubleshooting | szhshp 的第三边境研究所 全站点升级 - Project Titan | szhshp 的第三边境研究所 AWS-EC2-常见问题解决-Troubleshooting | szhshp 的第三边境研究所 Workbox-Getting Started | szhshp 的第三边境研究所 《时间简史》阅读笔记 | szhshp 的第三边境研究所 《时间的秩序》阅读笔记 | szhshp 的第三边境研究所 ESLint-常见问题解决-Troubleshooting | szhshp 的第三边境研究所 站点索引 | szhshp 的第三边境研究所 BMOB-常见问题解决-Troubleshooting | szhshp 的第三边境研究所 React + Typescript: 开启 HMR/Hot Loader | szhshp 的第三边境研究所 Yarn & NPM | szhshp 的第三边境研究所 ESLint: Typescript + React + TSX 集成 | szhshp 的第三边境研究所 《10101》EP15:过年 2020 | szhshp 的第三边境研究所 Cmder-Usage | szhshp 的第三边境研究所 Redux-DOM not refreshed | szhshp 的第三边境研究所 React Semantic UI-CheatSheet | szhshp 的第三边境研究所 Typescript: Getting Started | szhshp 的第三边境研究所 Flutter-Getting Started | szhshp 的第三边境研究所 Typescript: Access window object with type check | szhshp 的第三边境研究所 VSC Extension Development-Create A Code Formatter Extension | szhshp 的第三边境研究所 OneNote Extension-Main API | szhshp 的第三边境研究所 TortoiseGit Win10 Icon not showing correctly | szhshp 的第三边境研究所 Mongoose: aggregate() 方法实现聚合函数 | szhshp 的第三边境研究所 React In Depth - React 源码解析 - render() & Fiber | szhshp 的第三边境研究所 MongoDB x Mongoose: 实现类似 Join 的功能 | szhshp 的第三边境研究所 Disqus 评论框改造工程-实现 Disqus 代理的 Serverless 服务 | szhshp 的第三边境研究所 GUI, CLI, Terminal, Shell, TTY, Console, Bash | szhshp 的第三边境研究所 Jest Async Best Practise: No Nested Async | szhshp 的第三边境研究所 关系型数据库与非关系型数据库优缺点分析 | szhshp 的第三边境研究所 New Edge & Chromium Error - Package is invalid: 'CRX_VERSION_NUMBER_INVALID' | szhshp 的第三边境研究所 选择 GraphQL 的 N 个理由 | szhshp 的第三边境研究所 StrokePlus - 鼠标手势神器的代码编写技巧 | szhshp 的第三边境研究所 嗨,好久不见 | szhshp 的第三边境研究所 Vue + ElementUI 集成 Vue Router | szhshp 的第三边境研究所 IE8 - Unknown Runtime Error Using innerHTML & Ajax | szhshp 的第三边境研究所 React: Handling Events | szhshp 的第三边境研究所 React-Navigation Integration with Redux | szhshp 的第三边境研究所 React: States is tricky | szhshp 的第三边境研究所 《10101》EP14:小剧场 | szhshp 的第三边境研究所 ColdFusion - Basic - arguments in cffunction | szhshp 的第三边境研究所 ColdFusion - Basic - cfset | szhshp 的第三边境研究所
个人知识库搭建 - Hexo 实现 Github/Coding 持续集成 | szhshp 的第三边境研究所
2020-03-15 · via szhshp 的第三边境研究所

Meta

目录

2020-03-15: 以下两个方法测试通过

最终搭建的知识库链接: https://note.szhshp.org

开发背景

  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:szhshp/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
  3. CI 脚本如上文设置 Coding 操作方法
  4. 这样子以后就不需要了来回跑两个不同的 repo 了

参考文献