1.環境php
WEB測試、SVN服務器: 35.35.0.1html
PHP版本: 7web
web測試地址: http://35.35.0.1 shell
web測試環境路徑 /home/wwwroot緩存
svn對外路徑: svn://35.35.0.1bash
svn庫路徑:/home/svn服務器
svn管理腳本: http://35.35.0.1/svn.php /home/wwwroot/svn.phpsession
線上服務器 122.55.11.33svn
web目錄 /home/test函數
vi /home/svn/hooks/post-commit
#!/bin/bash export.utf-8 REPOS="$1" REV="$2" echo `/usr/bin/php -f /home/wwwroot/svn.php` >> /home/svn.log echo "$REPOS" "$REV" >> /home/svn.log
chmod u+x /home/svn/hooks/post-commit
線上服務器安裝rsync,參考博文http://my.oschina.net/u/232595/blog/474674 第一點
測試服務器安裝rsync,參考博文http://my.oschina.net/u/232595/blog/474674 第五點
配置線上服務器rsync(配置文件詳解見http://www.cnblogs.com/lykyl/archive/2013/04/10/rsync.html) vi /etc/rsyncd.conf
pid file = /var/run/rsyncd.pid port = 873 address = 122.55.11.33 uid = www gid = www use chroot = yes max connections = 1 log file = /home/log/rsync.log motd file = /etc/rsyncd.motd log format = %t %a %m %f %b [test] path = /home/test/ list = yes ignore errors auth users = root secrets file = /etc/rsyncd.secrets comment = test read only = false
設置密碼 vi /etc/rsyncd.secrets
用戶名:密碼 root:1111111
修改WEB目錄權限 chmod -R 755 /home/test
編寫腳本 vi /home/wwwroot/svn.php
<?php $users = [ 'admin' => '111111', 'tester' => '222222' ];//管理頁面的帳號密碼 $svn_base_path = '/home/svn/';//svn版本庫目錄 $svn_url = 'svn://35.35.0.1';//svn版本庫訪問地址 $test_web_base_path = '/home/wwwroot/';//測試WEB目錄絕對路徑 $svn = [ 'command_path' => '/usr/bin/', 'user' => 'user',//svn帳號 'password' => 'password'//svn對應密碼 ]; $projects = [//項目 '項目英文名' => [ 'name' => '項目中文名', 'svn_path' => $svn_url.'/項目英文名',//這裏是項目在版本庫的訪問路徑 'test_web_path' => $test_web_base_path.'project_name',//project_name這裏是測試環境項目訪問目錄名 'publish' => [ 'password' => '1111111',//這裏是第八步配置的密碼 'path' => 'root@122.55.11.33::test/project_name/',//project_name這裏是正式環境項目訪問目錄名 'exclude' => [//不被更新的文件或目錄的集合,例如svn文件、附件文件、緩存文件等 '.svn', ] ] ], ]; if(isset($argv)){//控制檯調用 $output = []; $projectNames = []; exec($svn['command_path'].'svnlook changed '.$svn_base_path.' 2>&1', $output); foreach($output as $path){ $name = substr($path, 4, strpos($path, "/") - 4); if(!in_array($name, $projectNames)){ $projectNames[] = $name; update($projects[$name], $svn); } } exit(); } session_start(); ?> <?php if(null == $_SESSION['user']){ if($_SERVER['REQUEST_METHOD'] == "POST"){ $name = $_POST['name']; $password = $_POST['password']; if(!array_key_exists($name, $users)){?> login fail, no user;<script>setTimeout('location.href="svn.php"', 1000);</script> <?}else{ if($users[$name] != $password){?> password error!<script>setTimeout('location.href="svn.php"', 1000);</script> <?}else{ $_SESSION['user'] = $name; show($projects); } }?> <?php }else{?> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>登錄</title> </head> <body> <form method="post" action="svn.php"> <p> 用戶名:<input name="name"/> </p> <p> 密碼:<input name="password"/> </p> <p> <input type="submit" value="登錄"> </p> </form> </body> </html> <?php }?> <?php }else{ if($_SERVER['REQUEST_METHOD'] == "POST"){ switch($_REQUEST['action']){ case 'logout': unset($_SESSION['user']); ?> logout success;<script>setTimeout('location.href="svn.php"', 1000);</script> <?php break; case 'checkout': checkout($projects[$_POST['project']], $svn, $projects); break; case 'publish': publish($projects[$_POST['project']], $projects); break; default: show($projects); break; } }else{ show($projects); } }?> <?php function show($projects){?> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <form action="svn.php" method="post"> <p> 項目: <select name="project"> <?php foreach($projects as $key => $project){?> <option value="<?=$key?>"><?=$project['name']?></option> <?php }?> </select> </p> <?php if($_SESSION['user'] == 'admin'){?> <p> 動做: <select name="action"> <option value="publish">發佈</option> <option value="checkout">遷出</option> </select> </p> <?}else{?> <input type="hidden" name="action" value="push"> <?php }?> <p> <input type="submit" value="發佈"> </p> </form> <form action="svn.php?action=logout" method="post"> <input type="submit" value="登出"/> </form> </body> </html> <?}?> <?php function checkout($project, $svn, $projects) { if (file_exists($project['test_web_path'])) { echo 'project had checkout to path "' . $project['test_web_path'] . '"'; } else { set_time_limit(0); ignore_user_abort(true); mkdir($project['test_web_path']); chmod($project['test_web_path'], 0755); putenv('LANG=C.UTF-8'); exec('cd ' . $project['test_web_path']); print exec($svn['command_path'] . 'svn co --username ' . $svn['user'] . ' --password ' . $svn['password'] . ' ' . $project['svn_path'] . ' ' . $project['test_web_path'] . ' 2>&1'); echo '遷出到測試環境成功'; show($projects); } } function publish($project, $projects) { $command = '/usr/bin/rsync -arpvzP --delete'; if (count($project['publish']['exclude'])) { foreach ($project['publish']['exclude'] as $f) { $command .= ' --exclude' . " '" . $f . "'"; } } $command .= ' ' . $project['test_web_path'] . '/ ' . $project['publish']['path'] . ' 2>&1'; $output = []; exec("RSYNC_PASSWORD=" . $project['publish']['password'] . " \n export RSYNC_PASSWORD \n " . $command, $output); echo '發佈成功'; show($projects); } function update($project, $svn) { print exec($svn['command_path'] . 'svn update --non-interactive --no-auth-cache --force --accept theirs-full --username ' . $svn['user'] . ' --password ' . $svn['password'] . ' ' . $project['test_web_path'] . ' 2>&1'); } ?>
注意:請保證exec函數可用