您好,欢迎访问一九零五行业门户网

通过PHP脚本自动部署GIT项目

deploy.php
<?php /** * simple php git deploy script * * automatically deploy the code using php and git. * * @version 1.3.1 * @link https://github.com/476552238li/deploy */ // =========================================[ configuration start ]=== /** * it's preferable to configure the script using `deploy-config.php` file. * * rename `deploy-config.example.php` to `deploy-config.php` and edit the * configuration options there instead of here. that way, you won't have to edit * the configuration again if you download the new version of `deploy.php`. */ if (file_exists(basename(__file__, '.php').'-config.php')) require_once basename(__file__, '.php').'-config.php'; /** * protect the script from unauthorized access by using a secret access token. * if it's not present in the access url as a get variable named `sat` * e.g. deploy.php?sat=bett...s the script is not going to deploy. * * @var string */ if (!defined('secret_access_token')) define('secret_access_token', '6a604a35d5a7c3fd8786f5ee94991a8c'); /** * the address of the remote git repository that contains the code that's being * deployed. * if the repository is private, you'll need to use the ssh address. * * @var string */ if (!defined('remote_repository')) define('remote_repository', 'https://github.com/476552238li/php-sql-parser.git'); /** * the branch that's being deployed. * must be present in the remote repository. * * @var string */ if (!defined('branch')) define('branch', 'master'); /** * the location that the code is going to be deployed to. * don't forget the trailing slash! * * @var string full path including the trailing slash */ if (!defined('target_dir')) define('target_dir', '/var/www/php-sql-parser'); /** * whether to delete the files that are not in the repository but are on the * local (server) machine. * * !!! warning !!! this can lead to a serious loss of data if you're not * careful. all files that are not in the repository are going to be deleted, * except the ones defined in exclude section. * be careful! * * @var boolean */ if (!defined('delete_files')) define('delete_files', false); /** * the directories and files that are to be excluded when updating the code. * normally, these are the directories containing files that are not part of * code base, for example user uploads or server-specific configuration files. * use rsync exclude pattern syntax for each element. * * @var serialized array of strings */ if (!defined('exclude')) define('exclude', serialize(array( '.git', ))); /** * temporary directory we'll use to stage the code before the update. if it * already exists, script assumes that it contains an already cloned copy of the * repository with the correct remote origin and only fetches changes instead of * cloning the entire thing. * * @var string full path including the trailing slash */ if (!defined('tmp_dir')) define('tmp_dir', '/tmp/spgd-'.md5(remote_repository).'/'); /** * whether to remove the tmp_dir after the deployment. * it's useful not to clean up in order to only fetch changes on the next * deployment. */ if (!defined('clean_up')) define('clean_up', true); /** * output the version of the deployed code. * * @var string full path to the file name */ if (!defined('version_file')) define('version_file', tmp_dir.'version'); /** * time limit for each command. * * @var int time in seconds */ if (!defined('time_limit')) define('time_limit', 30); /** * optional * backup the target_dir into backup_dir before deployment. * * @var string full backup directory path e.g. `/tmp/` */ if (!defined('backup_dir')) define('backup_dir', false); /** * optional * whether to invoke composer after the repository is cloned or changes are * fetched. composer needs to be available on the server machine, installed * globaly (as `composer`). see http://getcomposer.org/doc/00-intro.md#globally * * @var boolean whether to use composer or not * @link http://getcomposer.org/ */ if (!defined('use_composer')) define('use_composer', false); /** * optional * the options that the composer is going to use. * * @var string composer options * @link http://getcomposer.org/doc/03-cli.md#install */ if (!defined('composer_options')) define('composer_options', '--no-dev'); /** * optional * the composer_home environment variable is needed only if the script is * executed by a system user that has no home defined, e.g. `www-data`. * * @var string path to the composer_home e.g. `/tmp/composer` * @link https://getcomposer.org/doc/03-cli.md#composer-home */ if (!defined('composer_home')) define('composer_home', false); /** * optional * email address to be notified on deployment failure. * * @var string email address */ if (!defined('email_on_error')) define('email_on_error', false); // ===========================================[ configuration end ]=== // if there's authorization error, set the correct http header. if (!isset($_get['sat']) || $_get['sat'] !== secret_access_token || secret_access_token === '6a604a35d5a7c3fd8786f5ee94991a8c') { header('http/1.0 403 forbidden'); } ob_start(); ?> <!doctype html> <html> <head> <meta charset="utf-8"> <meta name="robots" content="noindex"> <title>simple php git deploy script</title> <style> body { padding: 0 1em; background: #222; color: #fff; } h2, .error { color: #c33; } .prompt { color: #6be234; } .command { color: #729fcf; } .output { color: #999; } </style> </head> <body> <?php if (!isset($_get['sat']) || $_get['sat'] !== secret_access_token) { die('<h2>access denied!</h2>'); } if (secret_access_token === 'betterchangemenoworsuffertheconsequences') { die("<h2>you're suffering the consequences!<br>change the secret_access_token from it's default value!</h2>"); } ?> <pre> checking the environment ... running as <b><?php echo trim(shell_exec('whoami')); ?></b>. <?php // check if the required programs are available $requiredbinaries = array('git', 'rsync'); if (defined('backup_dir') && backup_dir !== false) { $requiredbinaries[] = 'tar'; if (!is_dir(backup_dir) || !is_writable(backup_dir)) { die(sprintf('<div>backup_dir `%s` does not exists or is not writeable.</div>', backup_dir)); } } if (defined('use_composer') && use_composer === true) { $requiredbinaries[] = 'composer --no-ansi'; } foreach ($requiredbinaries as $command) { $path = trim(shell_exec('which '.$command)); if ($path == '') { die(sprintf('<div><b>%s</b> not available. it needs to be installed on the server for this script to work.</div>', $command)); } else { $version = explode("\n", shell_exec($command.' --version')); printf('<b>%s</b> : %s'."\n" , $path , $version[0] ); } } ?> environment ok. deploying <?php echo remote_repository; ?> <?php echo branch."\n"; ?> to <?php echo target_dir; ?> ... <?php // the commands $commands = array(); // ========================================[ pre-deployment steps ]=== if (!is_dir(tmp_dir)) { // clone the repository into the tmp_dir $commands[] = sprintf( 'git clone --depth=1 --branch %s %s %s' , branch , remote_repository , tmp_dir ); } else { // tmp_dir exists and hopefully already contains the correct remote origin // so we'll fetch the changes and reset the contents. $commands[] = sprintf( 'git --git-dir="%s.git" --work-tree="%s" fetch origin %s' , tmp_dir , tmp_dir , branch ); $commands[] = sprintf( 'git --git-dir="%s.git" --work-tree="%s" reset --hard fetch_head' , tmp_dir , tmp_dir ); } // update the submodules $commands[] = sprintf( 'git submodule update --init --recursive' ); // describe the deployed version if (defined('version_file') && version_file !== '') { $commands[] = sprintf( 'git --git-dir="%s.git" --work-tree="%s" describe --always > %s' , tmp_dir , tmp_dir , version_file ); } // backup the target_dir // without the backup_dir for the case when it's inside the target_dir if (defined('backup_dir') && backup_dir !== false) { $commands[] = sprintf( "tar --exclude='%s*' -czf %s/%s-%s-%s.tar.gz %s*" , backup_dir , backup_dir , basename(target_dir) , md5(target_dir) , date('ymdhis') , target_dir // we're backing up this directory into backup_dir ); } // invoke composer if (defined('use_composer') && use_composer === true) { $commands[] = sprintf( 'composer --no-ansi --no-interaction --no-progress --working-dir=%s install %s' , tmp_dir , (defined('composer_options')) ? composer_options : '' ); if (defined('composer_home') && is_dir(composer_home)) { putenv('composer_home='.composer_home); } } // ==================================================[ deployment ]=== // compile exclude parameters $exclude = ''; foreach (unserialize(exclude) as $exc) { $exclude .= ' --exclude='.$exc; } // deployment command $commands[] = sprintf( 'rsync -rltgodzvo %s %s %s %s' , tmp_dir , target_dir , (delete_files) ? '--delete-after' : '' , $exclude ); // =======================================[ post-deployment steps ]=== // remove the tmp_dir (depends on clean_up) if (clean_up) { $commands['cleanup'] = sprintf( 'rm -rf %s' , tmp_dir ); } // =======================================[ run the command steps ]=== $output = ''; foreach ($commands as $command) { set_time_limit(time_limit); // reset the time limit for each command if (file_exists(tmp_dir) && is_dir(tmp_dir)) { chdir(tmp_dir); // ensure that we're in the right directory } $tmp = array(); exec($command.' 2>&1', $tmp, $return_code); // execute the command // output the result printf(' <span>$</span> <span>%s</span> <div>%s</div> ' , htmlentities(trim($command)) , htmlentities(trim(implode("\n", $tmp))) ); $output .= ob_get_contents(); ob_flush(); // try to output everything as it happens // error handling and cleanup if ($return_code !== 0) { printf(' <div> error encountered! stopping the script to prevent possible data loss. check the data in your target dir! </div> ' ); if (clean_up) { $tmp = shell_exec($commands['cleanup']); printf(' cleaning up temporary files ... <span>$</span> <span>%s</span> <div>%s</div> ' , htmlentities(trim($commands['cleanup'])) , htmlentities(trim($tmp)) ); } $error = sprintf( 'deployment error on %s using %s!' , $_server['http_host'] , __file__ ); error_log($error); if (email_on_error) { $output .= ob_get_contents(); $headers = array(); $headers[] = sprintf('from: simple php git deploy script <simple-php-git-deploy@%s>', $_server['http_host']); $headers[] = sprintf('x-mailer: php/%s', phpversion()); mail(email_on_error, $error, strip_tags(trim($output)), implode("\r\n", $headers)); } break; } } ?> done. </pre> </body> </html>
其它类似信息

推荐信息