用 Go 做了一个 Git WebHook 钩子 实现自动部署
从繁琐中解脱
学过 Go 但我是 Php 开发者,为了活下去,自己的 Go 项目都快夭折了,而且 连 Go 的语法都快忘记了,索性就从现在开始,第 N 次再次开启自己的 Go 项目。第一件事,配置好一个好的开发环境,实现代码
push
后能看到效果,这个时候就要配置 WebHook。
最开始情况
使用 Nginx 监听, 转发到 Go 进程端口:
server{
listen 443 ssl;
server_name *.other.com other.com;
// 略:其它配置 other
location / {
proxy_pass http://127.0.0.1:8080;
}
}
目标
当代码
push
到 Git 服务器,实现自动部署。
实现方式
通过 Go 提供的
os/exec
调用 bash 脚本
bash 文件代码
# 到项目目录,执行 pull
cd /usr/local/www/other/
git pull
# 找到程序进程
arr=($(netstat -ltnp | grep 8080))
pidstr=${arr[6]}
pidid=(${pidstr//\// })
pidid=${pidid[0]}
# 干掉进程,然后重新运行
(kill $pidid|go run main.go&)
1.创建一个新的 Go 程序,用来更新 主项目,Go 代码更新需要重新运行,如果在原有项目做这件事,会进行不下去:
// 在原有项目做会出现的情况:
func Pull () string {
command := "./pull.bash"
cmd := exec.Command("/bin/bash", "-c", command)
// 略 Other Code
// 永远也不可能执行到这里来
// bash 这条命令 (kill $pidid|go run main.go&)
// 会杀掉现在的进程,程序直接结束了,不可能执行后面的 go run main.go &
return "Success"
}
-
我想直接通过现有项目的连接来实现访问更新代码的程序:
// 这里我省略了「更新程序」的代码 因为思路和上面代码一样 func (m *MyController) PostPull() string { http.Get("http://localhost:1414/git/pull") return "Success" // 这里代码是执行不到的,但习惯让我写了! }
-
到 Git 服务平台,添加上钩子。
钩子会报 502 错误,因为我们在部署的时候,杀掉了它的进程。本来有图片,不过上传不了。只要不是 200 状态,我所用的 Git 服务平台是不会触发。
-
解决 502 错误,设置 Nginx 502 返回 200:
server{ listen 443 ssl; server_name *.other.com other.com; // 略 Ohter code location / { proxy_pass http://127.0.0.1:8080; // 拦截 服务器错误 error_page 502 503 504 =200 /dealwith_caixuku; } // 拦截并给它 200 location /dealwith_caixuku{ set $ret_body '{"code": "200","msg": "hello world"}'; return 200 $ret_body; } }
-
至此,收工!
总结
- 使用
exec.Command("/bin/bash", "-c", bash_file_path)
这个脚本开头千万不要加#!/bin/bash
,会报 shell 126 错误。 - 有想法,就去实现,做了才会有果,不做啥也没有,而且……还老了!
- 本人能力有限,希望我走过的路,能给有类似需求的朋友提供参考。
本作品采用《CC 协议》,转载必须注明作者和本文链接
推荐文章: