持續集成 の 使用 git hook 部署代碼

持續集成的一個環節就是提交代碼后,能即刻部署到測試環境下,以運行各類測試用例。

本文使用 git hook 即可做到代碼的簡易部署。我們以一個網站為例。

解決方案的思路

你的網站代碼在你本地 git 庫里,你把代碼 push 到遠程 git 庫里(你的 Web 服務器),通過 post-receive hook 部署到 document root 網站目錄下。

示例

原創文章請參見 Using Git to manage a web site,作者 menon-sen 2008年的一篇文章,致敬!
本文有改動,以用戶 /home/michael 為例。

The local repository:建庫
$ cd
$ mkdir wph/web
$ cd wph/web
$ git init
Initialized empty Git repository in /home/michael/wph/web.git/
$ echo 'Hello, world!' > index.html
$ git add index.html
$ git commit -q -m "The humble beginnings of my web site."
The remote repository:建庫
$ cd
$ mkdir -p wph/web.git
$ cd wph/web.git
$ git init --bare
Initialized empty Git repository in /home/michael/wph/web.git/
The remote repository:設置 hook
$ cd ~/wph/web.git

# 編輯 hook 腳本
$ cat > hooks/post-receive
#!/bin/sh
GIT_WORK_TREE=/home/app/wph/web git checkout -q -f

$ chmod +x hooks/post-receive
  • 請務必加上執行權限,否則不會執行;

hook 設置好后,執行以下任一命令查看效果:
hooks/post-receive. hooks/post-receivesource hooks/post-receive

  • 請確保 GIT_WORK_TREE 所指向的目錄存在,否則會報告錯誤 “fatal: This operation must be run in a work tree”。
網站目錄權限
  • 網站目錄
    post-receive 腳本中設置的 GIT_WORK_TREE 變量,就是網站目錄:
    $ mkdir -p /home/app/wph/web/
  • 目錄權限
    假設使用 nginx HTTP Server,網站目錄一般都設置為 nginx:nginx。可以把 michael 用戶加到 nginx 組內(修改 /etc/group),網站目錄 chmod 設置為同組可寫。
chown -R nginx:nginx /home/app/wph/web/
chmod -R g+w /home/app/wph/web/

或者
chown -R michael:nginx /home/app/wph/web/,michael 作為 owner,用戶 nginx 屬于 nginx 組,更方便理解。或者直接設置為 michael:michael 也可以。

The local repository:和 remote 關聯
$ cd ~/wph/web
$ git remote add xweb ssh://192.168.99.236/home/michael/wph/web.git
$ git push xweb +master:refs/heads/master

至此,網站目錄下就有了 master 分支的完整的文件副本,但不包含 .git metadata(這個很好,類似于 svn export 了)。以后,你只要 git push xweb,在推送到遠程庫的同時,你的網站目錄就得到了更新。

注:

  1. git remote: Manage set of tracked repositories
  2. 假如你本地庫是從另外一個遠程庫復制來的,簽出在不同的分支下(不在 master 下),則 git push xweb +master:refs/heads/master 時,會報錯,調整一下命令參數即可,比如:git push xweb +v0.3:refs/heads/v0.3
  3. "Error: EPERM: operation not permitted, chmod ..." 錯誤
    這個錯誤有時會發生在 gulp 下生成的新目錄文件身上。網站目錄設置為 michael:nginx 即可;
  4. pull/push from multiple remote locations
git remote set-url origin --add --push <a remote>
git remote set-url origin --add --push <another remote>

這樣你就可以同時推送到多個遠程庫了,而不必一個一個推送。

git push <repository> [<refspec>…?]

  • <refspec>…?

Specify what destination ref to update with what source object. The format of a <refspec> parameter is an optional plus +, followed by the source object <src>, followed by a colon :, followed by the destination ref <dst>.

The <src> is often the name of the branch you would want to push, but it can be any arbitrary "SHA-1 expression", such as master~4 or HEAD.

The <dst> tells which ref on the remote side is updated with this push. The object referenced by <src> is used to update the <dst> reference on the remote side. By having the optional leading +, you can tell Git to update the <dst> ref even if it is not allowed by default.

To force a push to only one branch, use a + in front of the refspec to push (e.g git push origin +master to force a push to the master branch)

  • 示例
git remote add prod-web ssh://192.168.99.236/home/git/wph/web.git
git push prod-web +v0.3:refs/heads/v0.3
- `+v0.3:refs/heads/v0.3`:+<src>:<dst>;省略 `:<dst>`,則表示推送到遠程同名 ref;
- `+`表示強制推送,allow non-fast-forward updates;
- 為了簡單起見,通常 +v0.3:master 即可,即將本地 v0.3 推送到遠程 master(這樣遠程簽出 master 到站點目錄,而不必每次都修改簽出目錄);

post-receive 示例(發布指定分支)

#!/bin/bash

target_branch="production"
working_tree="PATH_TO_DEPLOY"

while read oldrev newrev refname
do
    branch=$(git rev-parse --symbolic --abbrev-ref $refname)
    if [ -n "$branch" ] && [ "$target_branch" == "$branch" ]; then
    
       GIT_WORK_TREE=$working_tree git checkout $target_branch -f
       NOW=$(date +"%Y%m%d%H%M%S")
       git tag release_$NOW $target_branch
    
       echo "   /==============================="
       echo "   | DEPLOYMENT COMPLETED"
       echo "   | Target branch: $target_branch"
       echo "   | Target folder: $working_tree"
       echo "   | Tag name     : release_$NOW"
       echo "   \=============================="
    fi
done

備注


最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 1. 安裝 Github 查看是否安裝git: $ git config --global user.name "...
    Albert_Sun閱讀 13,700評論 9 163
  • 本文作者陳云峰,轉載請注明。 這篇文章記錄個人常用的一些命令,和記不住的一些命令,轉載了并不斷更新。 Git官網 ...
    陳云峰閱讀 2,836評論 0 24
  • Spring Cloud為開發人員提供了快速構建分布式系統中一些常見模式的工具(例如配置管理,服務發現,斷路器,智...
    卡卡羅2017閱讀 134,837評論 18 139
  • 領導是組織的思想,管理是組織的行為;領導是做正確的決策,管理是順著決策正確地做;領導是把梯子搭在成功的墻上,管理是...
    新吶喊閱讀 697評論 2 7
  • 2017.3.12 一,親子話題,如何均衡二胎 二,婚姻家庭,如何讓婚姻更幸福 三,美膚類,氣質優雅女神課程 一,...
    80后女諸葛閱讀 194評論 1 0