利用Coding.net完成hugo的自动发布和部署
2020-11-04 • 预计阅读时间 5 分钟
2020-11-04 • 预计阅读时间 5 分钟
最近由于gitea
升级导致的悲剧。决定把代码迁移到Coding上。上次使用还是在腾讯收购之前……发现还是有挺大的变化的,目前和github的区别主要是强调DevOps
和项目全生命周期的管理。不过对于我这样的免费用户更看中的是提供的一些如无限的仓库,免费的Build
服务器。虽然有一点限制,不过对于个人来说足够了。
编译的服务器配置还是可以的2 核 / 4GB / 100GB 磁盘空间 / Ubuntu
Coding的CI
是基于Jenkinsfile
的持续集成方案。这个还是不错的,想想之前已经用过gitlab
和drone
的方案。每家的时候都有点差别、不过总的来说还是Jenkins
的方案更通用一点。
通过Coding托管blog的代码,在每次提交以后触发自动CI流程。这个时候通过Docker获取较Hugo
的编译镜像。然后挂在源码。完成编译。将编译好的内容打包,通过codingArtifactsGeneric
上传到制品库中。然后利用ssh
将发布物上传到远程的服务器,清空旧文件。并解压。然后重启docker.
其中在部署的同时还会通过首页 | Server酱给微信发个通知……
其中远程登录服务器使用的是ssh私钥的形式。这个需要将ssh的登录私钥上传到coding上,并获得一个credentialsId。通过环境变量传给Jenkinsfile
。
私钥的格式是需要注意的,如果使用较新的系统,由于OpenSSH
的版本大于7.8
会导致Coding
无法识别。区别的办法是通过查看私钥第一行的内容,如果是-----BEGIN OPENSSH PRIVATE KEY-----
则需要修改格式。将私钥转换成经典格式……
方法1:
ssh-keygen -p -f file -m pem -P passphrase -N passphrase
方法2:
通过puttygen
先导入私钥,然后在导出。这个时候一定要选Export OPENSSH key
,另外一个是转换成新格式的……
通过以上两种方法转换后的私钥第一行为:-----BEGIN RSA PRIVATE KEY-----
。Coding在上传私钥的时候也会校验,如果没有这行内容的话,会报私钥格式错误。
以下是完整的Jenkinsfile
pipeline {
agent {
docker {
image 'monachus/hugo'
reuseNode true
}
}
stages {
stage('检出(源码库)') {
steps {
checkout([$class: 'GitSCM', branches: [[name: 'main']],
userRemoteConfigs: [[url: env.GIT_REPO_URL, credentialsId: env.CREDENTIALS_ID]]])
}
}
stage('构建并推到成品库') {
steps {
sh 'git submodule update --init --recursive'
sh 'hugo version'
sh 'export HUGO_ENV=production'
sh 'hugo --minify --gc'
sh 'tar -czf latest.tar.gz -C ./public .'
sh 'ls -al'
codingArtifactsGeneric(files: 'latest.tar.gz', repoName: "${GENERIC_REPO_NAME}", version: "ver.${CI_BUILD_NUMBER}")
sh 'echo 完成编译'
}
}
stage('ssh 部署到 web 端') {
parallel {
stage('通知') {
steps {
sh 'curl "https://sc.ftqq.com/XXXXXXXXXXXX.send?text=blog编译成功@${CI_BUILD_NUMBER}&title=build"'
}
}
stage('ssh 部署到 web 端') {
steps {
echo '部署中...'
script {
def remote = [:]
remote.name = 'blog'
remote.allowAnyHosts = true
remote.host = "${env.REMOTE_HOST}"
remote.user = "${env.REMOTE_USER_NAME}"
remote.port = Integer.parseInt("${env.REMOTE_PORT}")
withCredentials([sshUserPrivateKey(credentialsId: "${env.REMOTE_CERT}", keyFileVariable: 'id_rsa')]) {
remote.identityFile = id_rsa
sshCommand remote: remote, command: "rm -rf /eureka/docker/blog"
sshPut remote: remote, from: 'latest.tar.gz', into: '/eureka/docker'
sshCommand remote: remote, sudo: false, command: "cd /eureka/docker && mkdir blog && tar -zxf latest.tar.gz -C blog && rm -rf latest.tar.gz"
sshCommand remote: remote, sudo: false, command: "docker restart blog"
}
}
echo '部署完成'
}
}
}
}
}
}
注意事项:
REMOTE_HOST
,REMOTE_USER_NAME
,REMOTE_PORT
都是需要你自己定义环境变量的。REMOTE_CERT
为上传的私钥IDDocker
来部署的blog,所以如果只是替换的话。有可能会出现404
的情况。所以最终reboot
解决所有……上传到制品库
的话,建议使用codingArtifactsGeneric
来实现。curl
的方案还是需要密码,所以不是太安全。
通过以上的配置就可以实现自动发布了。不过具体写些什么好像还是个挺复杂的事情……坚持才是最重要的。今天刚好折腾了下公司项目的CI,CI/CD
的最主要作用是减少人的参与,如果你折腾了半天,弄个半吊子的东西,那么跟没有也没什么区别了。行百里者半九十,古人说的还是挺有道理的。做就要做好……