構(gòu)建簡單原型展示系統(tǒng),使用git鉤子(hooks)自動(dòng)同步倉庫

技術(shù)棧

Tech Usage
git 構(gòu)建裸倉庫用于存放鉤子/文件倉庫
shell 用于更新項(xiàng)目原型版本及提供給不熟悉git操作的產(chǎn)品同事更新原型
html 用于根據(jù)js配置文件展示項(xiàng)目原型及版本
js 用于存放所有項(xiàng)目的版本配置, 供html及shell腳本解析調(diào)用
nginx HTTP服務(wù)器用于配置web域名訪問及簡單賬戶密碼限制
AxureRP 產(chǎn)品同事用于生成用于原型預(yù)覽的HTML文件

Bare repository(用于存放鉤子澈蟆,相當(dāng)于中央倉庫)

cd /data/bare_repo
git init --bare rp.git
cd rp.git/hooks
vim post-receive
--- contents of post-receive ----
#!/bin/bash

unset GIT_DIR
dep_path="/data/prototype/"

cd "$dep_path"
git add . -A && git stash
git pull origin master

exit 0
--- contents end ----

Local repository(用于存放供web訪問的文件)

cd /data/prototype
git init
git remote add origin /data/bare_repo/rp.git

項(xiàng)目結(jié)構(gòu)(/data/prototype 下)

  • config: 用于存放項(xiàng)目配置
  • rp: 用于存放項(xiàng)目原型 HTML 文件
  • scripts: 存放提供給產(chǎn)品同事執(zhí)行的 shell 腳本,用于更新原型文件或原型版本
  • index.html/version.html: web頁面入口匿沛,用于頁面展示

代碼樣例

  • config/properties.js
var rpVersion = {
  mmb: [0.1, 0.2],
  aitu: [0.1],
  wedis: [0.1, '0.2'],
  kqmp : [0.1, 0.2, 'web'],
  ddysApp: [2.13, 2.14],
  ddysWx: [2.13, 2.14],
  ddysPc: [2.13],
  ddysAdmin: [2.13],
  ddysXbld: [2.13]
}
  • scripts/git_rp_repo_sync.sh
#!/bin/bash
# encoding: utf-8
###################################################
# Author:                 gaopq
# Version:                0.01
# Email:                  peiqianggao@gmail.com
# Org:                    DDYS
# Date:                   2017-01-10 18:23:34
# ChangeLog:              add versions page for projects
# ChangeLog:              fixed bugs when this script updated itself and other user execute it before pull and update it.
# Description:            更新原型系統(tǒng)請先在 rp 文件夾下對應(yīng)項(xiàng)目文件夾下創(chuàng)建代表版本的文件夾, 并把原型HTML文件生成到該文件夾下再執(zhí)行本腳本
###################################################
CONF_FILE=$(dirname $0)/../config/properties.js
RP_DIR="$(dirname $0)/../"
TMP_SHELL_NAME=".tmp.sh"
# 獲取所有項(xiàng)目名
get_projects(){
   while read line
   do
       if [[ $line != ${line%:*} ]]
       then
           projs="$projs ${line%:*}"
       fi
   done < $CONF_FILE
   echo $projs
}
# 獲取某個(gè)項(xiàng)目的現(xiàn)有版本號(hào), param: project_name
get_versions(){
    [[ $# -ne 1 ]] && return 1
    proj=$1
    versions=$(grep -w $proj $CONF_FILE | awk -F: '{print $2}')
    echo $versions | sed "s/ //g;s/[]\[,]/ /g;s/'//g;"
}
# 給某個(gè)項(xiàng)目添加一個(gè)版本, params: project_name, new_version
add_version(){
    [[ $# -ne 2 ]] && return 1
    proj=$1
    new_version=$2
    versions_pro=$(get_versions $proj)
    echo $versions_pro | grep -w $new_version > /dev/null
    if [[ $? -eq 0 ]]
    then
        return 1
    else
    # write new_version to file
    # 此處不能使用單引號(hào)
    # sed 's/(^ *$proj.*)(],.*$)/\1, ${new_version}\2/' $CONF_FILE
        sed -i "s/\(^ *$proj.*\)\(],.*$\)/\1, '${new_version}'\2/" $CONF_FILE
        return 0
    fi
}
# 通過 git 上傳文件
rp_git_sync(){
    git add -A :/
    git commit -m "$(date +'%Y-%m-%d %H:%M:%S')[INFO]update project: $1, version: $2, From: $(uname -a)"
    echo -e "\e[1;32m][INFO]Waiting for updating and pushing ...\e[0m"
    git push origin master && echo -e "\e[1;32m$(date +'%Y-%m-%d %H:%M:%S') updated successfully.\e[0m"
}
# 從倉庫更新文件并判斷本shell文件是否在被更新的列表中
git_pull_test_shell_script_if_updated(){
    # shell_name=$(basename $0)
    # if the current running shell is not the $TMP_SHELLL_NAME
    [[ ${0%%$TMP_SHELL_NAME} == $0 ]] && cp -rf $0 $(dirname $0)/${TMP_SHELL_NAME}

    cd $RP_DIR
    git pull origin master
    [[ $? -ne 0 ]] && exec bash scripts/${TMP_SHELL_NAME}
}
# 開始工作
git_pull_test_shell_script_if_updated
echo -e "\e[1;32m\nPlease select project (select one and update all ^_^)\e[0m"
select project in $(get_projects)
do
    # vers=($(get_versions $project))
    # last_ver=${vers[((${#vers[@]}-1))]}
    last_ver=$(ls -t ${RP_DIR}rp/$project | head -1)
    echo "Versions: $(get_versions $project)"
    echo -en "\e[1;32m\nPlease input your version name (defaults: $last_ver): \e[0m"
    read version
    version=${version// /}
    version=${version:-$last_ver}
    add_version $project $version
    rp_git_sync $project $version
    break
done
exit 0
  • Nginx 配置
server {
        listen       80;
        server_name  my_domin_name;
        root /data/prototype/;
        index index.html;
        access_log /data/logs/nginx/my_domain_name.log main;
        location ^~ / {
            try_files $uri $uri/ /index.html?$args;
            # Before this: htpasswd -c $NGINX_PATH/passwd_db/passwd.db username
            auth_basic "Input Password";
            auth_basic_user_file $NGINX_PATH/passwd_db/passwd.db;
        }

        # avoid accessing shell scripts from web 
        location ^~ /scripts {
            deny all;
        }

        location ~* \.(js|css|png|jpg|jpeg|gif|ico|html)$ {
            if (-f $request_filename) {
                root /data/prototype;
                expires 10s;
                }
        }
}

Problems and solutions

  • properties.js 文件中版本號(hào)可用單引號(hào)或雙引號(hào)括起苫耸,便于 js 解析
  • 用戶在執(zhí)行本 shell 是發(fā)現(xiàn)本 shell 文件在遠(yuǎn)程倉庫被修改, git pull 的時(shí)候報(bào)錯(cuò)
    1. 每次執(zhí)行腳本前若發(fā)現(xiàn)執(zhí)行的不是備份版,則備份一次本腳本
    2. 發(fā)現(xiàn) git pull 失敗時(shí)默認(rèn)認(rèn)為是本 shell 在 pull 列表中陷谱,則使用 exec 執(zhí)行備份的腳本
  • 用戶端配置
# server 端先配置一個(gè)可以訪問 /data/bare_repo 和 /data/prototype 的用戶
# client 端使用 ssh-keygen 命令生成公鑰私鑰并配置到 server 上
git init
git remote add rp_user@ip:/data/bare_repo/rp.git
# 首次更新,獲取初始化文件及 shell 腳本
git pull origin master 

# 使用: 
# 在 rp 文件夾下對應(yīng)項(xiàng)目文件夾下創(chuàng)建代表版本的文件夾, 并把原型HTML文件生成到該文件夾下
# 直接將 scripts 下的 git_rp_repo_sync.sh 拖到 git-bash 或 terminal 中執(zhí)行即可
# 可能需要: chmod +r git_rp_repo_sync.sh

效果預(yù)覽

  • web
rp_index.png
rp_versions.png
  • shell 執(zhí)行效果
rp_shell.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末瑟蜈,一起剝皮案震驚了整個(gè)濱河市烟逊,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌铺根,老刑警劉巖宪躯,帶你破解...
    沈念sama閱讀 212,383評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異位迂,居然都是意外死亡访雪,警方通過查閱死者的電腦和手機(jī)详瑞,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,522評論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來臣缀,“玉大人坝橡,你說我怎么就攤上這事「闻悖” “怎么了驳庭?”我有些...
    開封第一講書人閱讀 157,852評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長氯窍。 經(jīng)常有香客問我饲常,道長,這世上最難降的妖魔是什么狼讨? 我笑而不...
    開封第一講書人閱讀 56,621評論 1 284
  • 正文 為了忘掉前任贝淤,我火速辦了婚禮,結(jié)果婚禮上政供,老公的妹妹穿的比我還像新娘播聪。我一直安慰自己,他們只是感情好布隔,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,741評論 6 386
  • 文/花漫 我一把揭開白布离陶。 她就那樣靜靜地躺著,像睡著了一般衅檀。 火紅的嫁衣襯著肌膚如雪招刨。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,929評論 1 290
  • 那天哀军,我揣著相機(jī)與錄音沉眶,去河邊找鬼。 笑死杉适,一個(gè)胖子當(dāng)著我的面吹牛谎倔,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播猿推,決...
    沈念sama閱讀 39,076評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼片习,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了蹬叭?” 一聲冷哼從身側(cè)響起毯侦,我...
    開封第一講書人閱讀 37,803評論 0 268
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎具垫,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體试幽,經(jīng)...
    沈念sama閱讀 44,265評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡筝蚕,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,582評論 2 327
  • 正文 我和宋清朗相戀三年卦碾,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片起宽。...
    茶點(diǎn)故事閱讀 38,716評論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡洲胖,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出坯沪,到底是詐尸還是另有隱情绿映,我是刑警寧澤,帶...
    沈念sama閱讀 34,395評論 4 333
  • 正文 年R本政府宣布腐晾,位于F島的核電站叉弦,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏藻糖。R本人自食惡果不足惜淹冰,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,039評論 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望巨柒。 院中可真熱鬧樱拴,春花似錦、人聲如沸洋满。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,798評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽牺勾。三九已至正罢,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間禽最,已是汗流浹背腺怯。 一陣腳步聲響...
    開封第一講書人閱讀 32,027評論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留川无,地道東北人呛占。 一個(gè)月前我還...
    沈念sama閱讀 46,488評論 2 361
  • 正文 我出身青樓,卻偏偏與公主長得像懦趋,于是被迫代替她去往敵國和親晾虑。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,612評論 2 350

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理仅叫,服務(wù)發(fā)現(xiàn)帜篇,斷路器,智...
    卡卡羅2017閱讀 134,637評論 18 139
  • 林中小路空氣新 小橋流水岸柳青 湖面似鏡倒影美 為何正秋無葉紅
    紅色陽光閱讀 288評論 0 1
  • 源于欲望而終于責(zé)任 多或少 有或無 僅此而已 隨時(shí)間增長的 唯有深刻诫咱。
    我的月亮你的六便士閱讀 96評論 0 0
  • 是否你也會(huì)偶爾想起我笙隙。
    北七海閱讀 62評論 0 1
  • 沉默 有一種煩惱無法述說, 不知該如何說起坎缭。 ...
    文棠心墨閱讀 252評論 1 1