监听github,自动编译octopress博客
Page content
为了方便在任何地方修改blog,我将blog源码存放于github上,挂在一个web hook,这样一旦blog有更新, VPS上就会执行脚本重新生成新的blog,看起来还是非常方便的。
1. 添加github钩子
首先需要将octopress的代码(我比较懒,全部的代码)放到github上。 在github的项目设置的Service Hooks中添加一个WebHook URLs的钩子, 例如:
http://imxylz.com/blog-update
下载github代码,例如存放于/data目录下:
git clone git@github.com:adyliu/imxylz.com.git /data/imxylz.com
2. 设置nginx
nginx增加一个location配置
location /blog-update {
proxy_pass http://127.0.0.1:1111;
}
3. 增加web钩子
这里使用python 开启一个web服务,拦截任何HTTP请求都执行我们的编译脚本。
[root@www imxylz.com]# cat hook.py
#!/usr/bin/env python3
#-*- coding:utf-8 -*-
# start a python service and watch the nginx request dog
from http.server import HTTPServer,CGIHTTPRequestHandler
from threading import Thread,RLock
import subprocess
import logging
import sys
import os.path
_PWD=os.path.abspath(os.path.dirname(__file__))
def execute_cmd(args,cwd=None,timeout=30):
if isinstance(args,str): args = [args]
try:
with subprocess.Popen(args,stdout=subprocess.PIPE,cwd=cwd) as proc:
try:
output,unused_err = proc.communicate(timeout=timeout)
except:
proc.kill()
raise
retcode = proc.poll()
if retcode:
raise subprocess.CalledProcessError(retcode, proc.args, output=output)
return output.decode('utf-8','ignore') if output else ''
except Exception as ex:
logging.error('EXECUTE_CMD_ERROR: %s',' '.join(str(x) for x in args))
raise ex
class HttpHandler(CGIHTTPRequestHandler):
_lock = RLock()
_counter = 0
_building = False
def build(self):
with HttpHandler._lock:
if HttpHandler._counter == 0 or HttpHandler._building:
return
HttpHandler._counter = 0
HttpHandler._building = True
logging.info("BUILDING NOW...")
try:
resp = execute_cmd(os.path.join(_PWD,'build.sh'),cwd=_PWD,timeout=600)
logging.info(resp)
finally:
HttpHandler._building = False
self.build()
def do_GET(self):
self.do_POST()
def do_POST(self):
self.send_response(200,'OK')
self.end_headers()
self.wfile.write(b'OK')
self.wfile.flush()
with HttpHandler._lock:
HttpHandler._counter += 1
Thread(target=self.build).start()
if __name__ == '__main__':
logging.basicConfig(format='%(asctime)s %(levelname)s: %(message)s',level=logging.INFO)
port = int(sys.argv[1]) if len(sys.argv) > 1 else 1111
logging.info('starting the server at 127.0.0.1:%s',port)
httpd = HTTPServer(('127.0.0.1',port),HttpHandler)
httpd.serve_forever()
4. 生成blog脚本
为了方便扩展,这里使用一个build.sh脚本来编译octopress。
#!/bin/bash
echo "build at `date`"
git pull
rake generate
5. 启动hook
最后启动hook来监听github变更:
nohup python3 hook.py >> /tmp/hook.log 2>&1 &
需要注意的是,build.sh/hook.py 需要放在octopress的根目录下面,另外rake环境也需要准备好,如果不能可以在build.sh里面设置环境变量。
如果要测试可以发送http请求即可。
curl http://127.0.0.1:1111/
此时我只需要将本地blog源码修改后push到github上,VPS机器就会执行脚本重新发布blog了。