Obsidian结合CI/CD实现自动发布
CI/CD+QuickAdd+JS脚本+bat脚本+sh脚本实现自动发版Hugo文章
需求来源
每次手动执行Hugo的命令,手动把public文件夹上传到自己的服务器可以完成发版需求。
但是,作为一个内容创作者,我更希望的关注于自己的内容,而不是关注整个发版过程。最好能只在一个软件上进行简单的几次点击,就完成自动内容到公网上了。
需求1:只在一个软件中,不用切换软件(Obsidian)。
需求2:只需要简单的1-2次点击就可以完成自动部署到公网。
方案分析
备注:我写内容的软件为Obsidian,这是一个很强大的软件。可以安装主题,可以安装很多插件。功能强大,可扩展性很强。这里不介绍Obsidian这款软件。
手动发版方案步骤:
- 创建一个markdown文件
- 编写内容(Typora或者Obsidian都行)
- 添加上笔记属性(Hugo文章需要)
- 把要发版的文章复制到Hugo的content文件夹的post文件夹中
- 手动执行hugo的构建站点命令,
hugo --gc --minify
- 对public文件夹进行压缩(内容过多会不好传输,所以压缩),并上传到服务器对应位置
- 服务器解压
- 完成部署
优化分析:
-
创建markdown。
优化方案:使用Obsidian的QuickAdd的template完成创建文章,并添加属性,你可以在笔记内容编写完成后回来编辑这些属性。一般我们文章写好后,再去确定打上什么标签,配上什么图片。
-
编写内容。这个步骤少不了,无法进行简化。
-
复制要发版的文章到Hugo中(一般不是把所有的内容都进行发版的,所以我们一般只复制指定的文章到Hugo中)。
优化方案:使用Sync to Hugo。Sync to Hugo可以自动添加基本属性,这些基本属性的值他会自己判断,并且Sync to Hugo会把你选择的文章复制到指定位置。这样,我们就可以做到,在一个自己的工作区创作,然后如果需要把某篇文章发布博客,我们就选择那个文章,点击Sync to Hugo,推送到对应的博客位置,等待发版上线。
-
手动执行构建,并把构建的内容添加到服务器。
优化方案:
- 创建git仓库,这里我使用的腾讯的coding。你使用gitee、gitHub、阿里云效都是可以的。
- 在windows编写bat脚本。脚本的功能为:完成hugo的构建、上传构建好的文件到git仓库。
- 在服务器编写shell脚本。shell脚本的功能为:删除老的public文件夹,并且拉取git上的已经被windows构建好的public文件夹到linux
- 使用coding,并在coding的持续集成中创建构建计划,并且编写Jenkinsfile去使用SSH调用服务器已经编写好的sh脚本
-
完成部署
**新方案的步骤:**编写文章+3次点击即可。
- 点击QuickAdd的命令完成创建文件
- 编写内容
- 点击Sync to Hugo按钮
- 点击QuickAdd的部署命令
- 完成部署
整个流程都没有离开Obsidian。做到在一个软件中完成发版博客的效果。
成果展示
步骤一:使用QuickAdd创建文章并编写内容。
步骤二:写文章
步骤三:自己添加修改一下文章的属性,比如图片、标签、描述等信息,可以让博客美观一点。
步骤四:使用Sync to Hugo,把文章推送到Hugo的content文件夹内指定目录。
步骤五:使用QuickAdd,执行发版脚本。
效果展示:
具体搭建过程
绑定Git仓库和public文件夹
创建远程Git仓库
初始化本地仓库
这里我之前把public删除了,所以这里可以重新生成一下。
使用hugo --gc --minify命令即可。
进入public,使用git bash:
执行初始化仓库命令:
git init
创建SSH密钥对
获取SSH密钥。
首先,你需要检查是否已经存在可用的SSH密钥。在命令行中输入以下命令:
ls ~\.ssh
该命令会列出SSH目录中的所有文件。如果已经存在一个名为id_rsa.pub或id_dsa.pub的文件,那么说明已经存在可用的SSH密钥。
这里我看到没有这两个文件,只有一个known_hosts文件。
解释一下known_hosts文件:
known_hosts
是 SSH 客户端用来存储远程服务器公钥指纹的文件,主要用于**防止中间人攻击(Man-in-the-Middle Attack)**的。当你第一次通过 SSH 连接到一个新服务器时,客户端会提示你验证服务器的公钥指纹(类似这样):The authenticity of host 'github.com (20.205.243.166)' can't be established. ECDSA key fingerprint is SHA256:p2QAMXNIC1TJYWeIOttrVc98/R1BUFWu3/LiyKgUfQM. Are you sure you want to continue connecting (yes/no)?
如果你输入
yes
,SSH 会将该服务器的公钥指纹保存到known_hosts
文件中。下次连接同一服务器时,客户端会比对指纹:
- 匹配 → 直接连接(不提示警告)。
- 不匹配 → 发出警告(可能遭遇中间人攻击或服务器密钥变更)。
因为没有找到现有的SSH密钥,所以我们使用以下命令生成新的SSH密钥:
ssh-keygen -t rsa -C "xxx@qq.com"
-C "xxx@qq.com"
是为公钥添加一个注释(Comment),通常用邮箱标识密钥所有者。注释仅用于备注,不影响密钥功能。运行命令
ssh-keygen -t rsa -C "xxx@qq.com"
会在本地生成一对 SSH 密钥(公钥和私钥),用于安全的远程登录(如 GitHub、GitLab、服务器 SSH 连接等)。
在生成SSH密钥的过程中,会提示你输入密钥的保存位置和密码。可以选择使用默认的保存位置(通常是~/.ssh/id_rsa)并且可以选择是否设置密码来保护密钥。
上面内容是询问你生成的 私钥(id_rsa
)和公钥(id_rsa.pub
) 要保存在哪个文件路径。
我们直接按回车就会使用默认路径来保存我们的私钥和公钥(推荐大多数情况)。
回车后,私钥和公钥将会保存为如下路径中。
- 私钥:
C:\Users\13780\.ssh\id_rsa
。私钥(id_rsa
)一般保存在你的本地计算机(默认路径~/.ssh/id_rsa
),必须严格保密,相当于你的“密码”。 - 公钥:
C:\Users\13780\.ssh\id_rsa.pub
。公钥(id_rsa.pub
)可以自由分发(默认路径~/.ssh/id_rsa.pub
),一般我们会上传到目标服务(如 GitHub、服务器等)。
然后会让你输入密码,这个是可选的。作用是为私钥设置额外密码保护(提高安全性,但每次使用密钥需输入密码)。若不需要密码保护,直接按两次回车跳过就行。这里我们不用密码,因为私钥已经很安全了,保护再保护,麻烦,我们只要私钥不丢就行。
我们再检查是否已经存在可用的SSH密钥。
ls ~\.ssh
然后复制私钥。
-
进入 .ssh 目录(默认存储路径)
cd ~/.ssh
在命令行中,
~
(波浪符号)是一个特殊的快捷符号,代表当前用户的家目录(Home Directory)。不用操作系统的home目录不同,但是~
都是表示家目录。 -
查看文件列表:
ls
-
查看公钥内容:
cat id_rsa.pub
-
复制公钥
公钥为:
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDHT……
添加本地公钥到Coding
注意:在个人账户设置中添加公钥,就是在全局添加公钥。这里你也可以去Git仓库项目里面去添加部署公钥,这样就是添加项目的公钥了,即,对应私钥只是打开这个项目的锁的钥匙。
绑定本地仓库与远程仓库
git remote add origin git@e.coding.net:g-dvea9576/hugo-blog/hugo-blog.git
将本地的分支版本上传到远程仓库
依次输入下面命令:
git add .
git commit -m "初次提交"
git push -u origin master
-
添加所有文件到暂存区:git add .
-
提交更改到本地仓库:git commit -m “初次提交:同步Obsidian笔记”
-
推送到远程仓库(Gitee):git push -u origin master
-u
设置默认推送目标(后续可直接用git push
)。
编写bat脚本
我们随便在一个地方创建一个bat脚本都行。
脚本名:update_blog.bat
@echo off
:: Windows 批处理脚本 - Hugo 构建并推送博客到 Git
:: 版本: 2025-05-18-稳定版setlocal EnableDelayedExpansion
set "EXIT_CODE=0"
set "SUCCESS_MSG=OPERATION_SUCCESS"
set "ERROR_MSG=OPERATION_FAILED":: 1. 进入博客目录
cd /d D:\Obsidian-Test\Obsidian-Hugo\my-blog || (echo !ERROR_MSG!echo 错误:无法进入博客目录exit /b 1
):: 2. 清理 public 目录
if exist public (cd public || (echo !ERROR_MSG!echo 错误:无法进入public目录exit /b 1)echo 正在删除文件...for /f "delims=" %%F in ('dir /b /a-d 2^>nul') do (del /f /q "%%F" >nul 2>&1)echo 正在删除子目录...for /d %%D in (*) do (if /i not "%%D"==".git" (rmdir /s /q "%%D" 2>nul))cd ..echo public目录清理完成
):: 3. 执行 Hugo 构建
echo 正在构建 Hugo 站点...
hugo --gc --minify || (echo !ERROR_MSG!echo 错误:Hugo 构建失败!exit /b 1
):: 4. 进入 public 目录
cd public || (echo !ERROR_MSG!echo 错误:无法进入public目录exit /b 1
):: 5. Git 操作
echo 正在提交并推送 Git 变更...
git add . || (echo !ERROR_MSG!echo 错误:git add 失败exit /b 1
)git commit -m "自动更新: %date% %time%" || (echo 警告:git commit 失败(可能是无变更)
)git push origin master || (echo !ERROR_MSG!echo 错误:git push 失败exit /b 1
):: 6. 完成
echo !SUCCESS_MSG!
echo 操作完成!
exit /b 0
注意上面代码中有一个地方是关键的:
for /d %%D in (*) do (if /i not "%%D"==".git" ( :: 检查目录名是否不是 ".git"rmdir /s /q "%%D" 2>nul :: 如果不是,则删除该目录) )
for /d %%D in (*)
:遍历public
下的所有子目录。if /i not "%%D"==".git"
:排除.git
目录(/i
表示不区分大小写)。rmdir /s /q "%%D"
:强制删除其他子目录(/s
递归删除,/q
静默模式)。因此,
.git
目录会被保留,而其他文件和子目录会被清理。
写好后,我们可以双击执行一下。看看能不能进行成功进行构建,并推送。
下面这个结果就是成功推送的输出了:
添加服务器公钥到Coding
因为服务器需要拉代码,所以也需要把服务器的公钥给Coding。
检查是否已有 SSH 密钥:
ls -al ~/.ssh
如果没有就使用
ssh-keygen -t ed25519 -C "xxx@qq.com"
-t ed25519
:指定密钥类型(也可用-t rsa -b 4096
生成 RSA 密钥)。-C "注释"
:可选注释,一般填写邮箱或用途。
通过结果,我们可以知道服务器上已经存在 Ed25519 算法的 SSH 密钥对(id_ed25519
是私钥,id_ed25519.pub
是公钥)
cat ~/.ssh/id_ed25519.pub
复制公钥,然后我们在Git仓库上添加公钥:
测试是否配置成功:
ssh -T git@e.coding.net
直接输入 yes
并回车(注意是 yes
,不是 y
),之后会将该服务器的公钥指纹保存到 ~/.ssh/known_hosts
文件,下次连接就不会再提示了。
看到上面提示,就说明是成功的。
注意:Coding中的公钥有两中,分别是项目内的部署公钥(Deploy Key) 和 个人账户中的SSH公钥(SSH Key)。
部署公钥(Deploy Key):为 单个项目 提供的只读或读写权限密钥,通常用于服务器自动化部署(如 CI/CD、生产服务器拉取代码)。绑定到项目,而非个人账户。
个人账户公钥(SSH Key):绑定到 你的个人账户,拥有账户下所有权限(包括访问所有有权限的项目)。对全局有效,可访问账户下所有项目(需项目权限)。权限与账户角色一致。
编写sh脚本
我们在这个站点目录下面创建一个script文件夹,专门用来放脚本:
创建脚本名:update_project.sh
#!/bin/bash# 配置变量(根据实际情况修改)
GIT_REPO="git@e.coding.net:g-dvea9576/hugo-blog/hugo-blog.git" # Git仓库地址
GIT_BRANCH="master" # 分支(默认master)
TARGET_DIR="/www/wwwroot/blog.yimengtut.online/public" # 代码存放目录# 1. 清理旧目录
if [ -d "$TARGET_DIR" ]; thenecho "删除旧目录: $TARGET_DIR"sudo rm -rf "$TARGET_DIR"
fi# 2. 创建目录并设置权限
echo "创建目录: $TARGET_DIR"
sudo mkdir -p "$TARGET_DIR"
# 将目录所有者设为当前用户(避免后续sudo)
sudo chown -R $(whoami):$(whoami) "$TARGET_DIR"# 3. 拉取代码
echo "正在从 $GIT_REPO 拉取代码到 $TARGET_DIR..."
git clone --branch "$GIT_BRANCH" "$GIT_REPO" "$TARGET_DIR"# 4. 检查是否成功
if [ $? -eq 0 ]; thenecho "代码拉取成功!"ls -l "$TARGET_DIR"
elseecho "错误:代码拉取失败!"# 提示可能的SSH问题echo "请检查:"echo "1. SSH公钥是否已添加到Coding.net账户;"echo "2. 是否可通过以下命令手动克隆:"echo " git clone $GIT_REPO"exit 1
fi
测试:
注意:这里还需要设置一下执行权限。
sudo chmod +x update_project.sh
看到上面信息,说明执行成功。
添加服务器访问凭证
我们将会使用jenkinsfile让Git代码更新时自动去调用服务器的脚本。所以我们需要添加服务器的访问凭证(不是所有人都能访问你的服务器的,只能让有服务器访问凭证的才能访问,这里我们使用SSH Keys的方式来去访问。使用密码或者SSH Keys等方式都是可以的,他们都是访问凭证中的一种)。
自动创建密钥对:由系统自动生成一个密钥对。
- 公钥会被保存到Linux边缘实例的
~/.ssh/authorized_keys
文件中。 - 私钥会以.pem格式自动下载到您的本地计算机。请注意,火山引擎不会保存您的私钥。因此请您务必妥善保管私钥文件、勿将私钥文件分享给其他人。
创建后,会自动下载.pem格式的文件到本地计算机。这个就是私钥,要好好保管。
我们先绑定实例:
火山引擎的服务器绑定好密钥后需要重启服务器才行,并且要注意,和阿里云一样,服务器绑定密钥后,密码登录将会自动失效。
重启好,我们测试一下:
然后去Coding添加凭证:
编写jenkinsfile
在项目中创建构建计划:
如果想使用密码发起SSH使用“通过账号密码发起的 SSH 连接”即可,这里我们使用“通过私钥发起的 SSH 连接”来操作。
确定。确定后,他会自动构建。
但是我这里会失败,因为这里我正好使用的Ubuntu 24.04。这个版本的系统需要去服务器里面额外设置一下,其他的版本系统不会出现这个问题(这里的报错也困惑了我好一会,“明明直接使用凭证可以访问火山引擎服务器的,但是为什么在Coding中无法访问到?”,最终在腾讯云文档中找到了解决方案):
构建失败的解决方案:
编辑sshd_config文件。
vim /etc/ssh/sshd_config
添加PubkeyAcceptedKeyTypes=+ssh-rsa
到文件中,然后执行systemctl restart ssh
重启SSH。
ssh-rsa
使用 SHA-1 作为哈希算法,而 SHA-1 已被证明存在 碰撞攻击 漏洞。所以从 OpenSSH 8.8(2021年发布) 开始,官方默认禁用了ssh-rsa
公钥签名算法。Ubuntu 24.04 搭载的 OpenSSH 版本是比较新的,因此也继承了这一变更。而Jenkins ssh的插件比较旧,所以还是使用SHA-1的哈希算法,所以会出现上面的问题。
上面步骤中的做法,设置
PubkeyAcceptedKeyTypes=+ssh-rsa
,是一种临时兼容性的配置,他的效果是:添加后,可以允许 OpenSSH 继续接受ssh-rsa
密钥,所以能解决上面的这个问题,做到让Jenkins ssh插件能成功链接服务器。疑惑:我们服务器生成的访问密钥是ed25519的。然后我要使用腾讯的Coding中的Jenkins ssh的插件,这个插件比较旧需要允许服务器的 OpenSSH 继续接受 ssh-rsa 密钥才行。然后我在服务器设置了
PubkeyAcceptedKeyTypes=+ssh-rsa
,就可以链接了。但是问题来了,为什么一个是ed25519,一个是ssh-rsa?解答:旧版本的 Jenkins SSH 插件在 SSH 握手时会优先尝试 ssh-rsa(基于 SHA-1 的签名算法)。如果服务器未声明支持 ssh-rsa,插件可能因其过时逻辑而中止连接,即使你配置了 ed25519 私钥。服务器通过设置 PubkeyAcceptedKeyTypes=+ssh-rsa,可以做到在默认支持 ed25519 的基础上额外声明支持 ssh-rsa,从而满足插件的握手要求。握手成功,然后Jenkins 底层 SSH 客户端库(支持 ed25519)会使用你提供的 ed25519 密钥进行认证。
上面这个密钥不匹配的解决方案有如下几种:
- 推荐:升级 Jenkins SSH 插件
- 推荐:如果无法升级插件,可以生成 RSA 密钥(SHA-2),他兼容旧插件
- 临时:继续使用
PubkeyAcceptedKeyTypes=+ssh-rsa
,但ssh-rsa
(SHA-1)不安全,仅作为过渡。这里说的通过私钥连接,相当于是登录服务器哈。
完成上面步骤后,就可以构建成功了:
目前这里我们还是使用默认的模板来构建的。
我们可以看到他执行的命令行内容和结果:
这里分析一下模板的执行的效果。
模板内容如下:
def remoteConfig = [:]
remoteConfig.name = "my-remote-server"
remoteConfig.host = "${REMOTE_HOST}"
remoteConfig.allowAnyHosts = true
remoteConfig.port = 22node {// 使用当前项目下的凭据管理中的 SSH 私钥 凭据withCredentials([sshUserPrivateKey(credentialsId: "${REMOTE_CRED}",keyFileVariable: "privateKeyFilePath")]) {// SSH 登录用户名remoteConfig.user = "${REMOTE_USER_NAME}"// SSH 私钥文件地址remoteConfig.identityFile = privateKeyFilePathstage("通过 SSH 执行命令") {// 本地创建一个 test.sh 脚本,用来发送到远端执行writeFile(file: 'test.sh', text: 'ls')sshCommand(remote: remoteConfig, command: 'for i in {1..5}; do echo -n \"Loop \$i \"; date ; sleep 1; done')sshScript(remote: remoteConfig, script: 'test.sh')sshPut(remote: remoteConfig, from: 'test.sh', into: '.')sshGet(remote: remoteConfig, from: 'test.sh', into: 'test_new.sh', override: true)sshRemove(remote: remoteConfig, path: 'test.sh')}}
}
模板做的事情如下:
- 在Jenkins工作区生成
test.sh
(内容为ls
),注意,不是在我们服务器创建文件哈。 - 在远程服务器运行循环打印日志的命令,就是为了验证SSH连接和命令执行能力。
- 将本地的
test.sh
中的内容发送到远程执行(实际执行ls
),其实就是为了测试脚本远程执行功能。 - 将
test.sh
上传到远程服务器,就是模拟部署文件,测试文件传输功能。 - 从远程下载文件到本地并重命名,其实就是为了验证文件获取能力。
- 删除远程的
test.sh
。不改变我们服务器原本的内容。
全部都成功后,就验证了自动构建的功能是完整支持的。
下面我们进行编写自己的jenkinsfile:
def remoteConfig = [:]
remoteConfig.name = "my-remote-server"
remoteConfig.host = "${REMOTE_HOST}" // 通过变量传入远程服务器IP
remoteConfig.allowAnyHosts = true // 跳过主机验证(生产环境建议关闭)
remoteConfig.port = 22 // SSH端口node {withCredentials([sshUserPrivateKey(credentialsId: "${REMOTE_CRED}", // Jenkins中配置的SSH私钥凭据IDkeyFileVariable: "privateKeyFilePath")]) {remoteConfig.user = "${REMOTE_USER_NAME}" // SSH用户名(如root)remoteConfig.identityFile = privateKeyFilePathstage("执行远程脚本") {// 1. 直接执行远程服务器上的脚本sshCommand(remote: remoteConfig,command: "cd /www/wwwroot/blog.yimengtut.online/script && chmod +x update_project.sh && ./update_project.sh")// 2. (可选)捕获脚本输出def scriptOutput = sshCommand(remote: remoteConfig,command: "cd /www/wwwroot/blog.yimengtut.online/script && ./update_project.sh",returnStdout: true)echo "脚本输出:${scriptOutput}"}}
}
执行测试:
看到能成功拉取代码!jenkinsfile配置完成。
测试使用bat脚本运行整套流程
完成前面的步骤后,现在我们就已经可以做到:只要执行bat脚本,就可以直接把Hugo下的文章自动构建,并部署到服务器上了。
测试。
目前的效果如图:
修改博客内容:
双击执行bat脚本:
看看网站:
OK。目前的效果是:只要修改了post中的内容,点击一下bat脚本就可以更新到hugo网站了。
使用sync to hugo插件
但是我们每次都去hugo博客中操作比较不舒服。
一般情况下,我们会在一个工作区内写文章,只是把部分要发版的文章进行发版,那难道我们要手动复制到hugo文件夹内吗?
不,这样可太麻烦了。
所以我们来使用Obsidian来进行优化。(注意,优化前的方案还需要手动添加文章的属性才行,因为Hugo是需要知道文章标题等信息的,所以你也是需要手动设置的。但是使用sync to hugo后,文章标题,发布时间等信息就会自动给我们添加上,所以也会省去我们手动添加基本属性的麻烦事)
优化后的效果是:在Obsidian中写文章,然后如果看到有要推送文章,我们只要选择这个文件,然后点击Obsidian中的一个按钮就完成拷贝并添加基本属性了。
我们使用sync to hugo插件来完成这个步骤(这里我对这个插件进行了一点改造,如果需要可私信)。
注意:hugo路径是指Hugo站点目录。简单的说,你看public在哪个文件夹下,你就选择哪个文件夹。
sync to hugo插件使用效果展示:
-
选择要推送的文章,进行推送:
注意:这里我使用了OSS作为图床(如果需要教程,可以看我其他文章或者自行百度)。
-
看看Hugo的post文件夹中是否出现我们推送的文章:
并且也可以看到,他自动给你添加加入了基本的属性:
-
接下来,如果你想进行发版,就可以直接去执行bat脚本,完成发版了:
创建QuickAdd宏,并编写js脚本
上面的操作已经足够简单了,只要写文章,然后点击sync to hugo按钮,然后点击bat脚本即可。
但是我还有一个需求,就是在一个软件中操作,不想去任何其他地方操作。
解决方案就是在Obsidian中使用QuickAdd插件,然后编写宏,调用js脚本,js脚本调用bat脚本实现发版。这样,我们就不用去找bat脚本去点击了。
编写js脚本
我们先编写脚本:
这个js脚本可以在Obsidian工作区的任何一个地方创建。脚本的内容如下。
脚本名:deploy.js
const { exec } = require("child_process");
const path = require("path");async function runUpdateBlog() {new Notice(`🚀 开始推送博客内容...!`, 5000);const batPath = path.join("D:", "Obsidian-Test", "Obsidian-Hugo", "bin", "update_blog.bat");const workingDir = path.join("D:", "Obsidian-Test", "Obsidian-Hugo", "bin");console.log("🚀 开始推送博客内容...");return new Promise((resolve, reject) => {const child = exec(`cmd /c "${batPath}"`, { cwd: workingDir,windowsHide: true,maxBuffer: 1024 * 1024 * 5}, (error, stdout, stderr) => {const output = stdout.toString();if (output.includes("OPERATION_SUCCESS")) {console.log("✅ 博客内容推送完成!");console.log(output);new Notice(`✅ 博客内容推送完成!`, 5000);resolve(output);} else if (output.includes("OPERATION_FAILED")) {console.error("❌ 博客更新失败:");console.log("完整输出:", output);reject(new Error("部署失败"));} else {console.error("⚠️ 无法确定操作状态");console.log("输出:", output);reject(new Error("未知状态"));}});const timeout = setTimeout(() => {if (!child.killed) {child.kill();console.error("⏰ 操作已超过30秒,进程已被终止");new Notice(`⏰ 操作已超过30秒,进程已被终止!`, 5000);reject(new Error("Process timeout"));}}, 30000);child.on("exit", () => clearTimeout(timeout));});
}module.exports = async () => {try {await runUpdateBlog();} catch (error) {console.error("执行失败:", error.message);throw error;}
};
使用QuickAdd
安装QuickAdd插件,然后创建宏。
好了。
测试:
修改文章内容。
先同步:
再点击ctrl+p,选择我们的“Hugo发版”命令:
看到结果已经更新了。
OK,目前已经达到了在一个软件中进行创作、并且可以选择指定内容进行发布博客、并且只要点击一个按钮就自动发版到公网去的效果了。
个人站点链接
我的博客链接:Luca的博客