Skip to content

Instantly share code, notes, and snippets.

@InabaByakko
Created December 18, 2016 09:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save InabaByakko/82786eb4100f0a3edd9a0afeab19eb19 to your computer and use it in GitHub Desktop.
Save InabaByakko/82786eb4100f0a3edd9a0afeab19eb19 to your computer and use it in GitHub Desktop.
http://ja.katzueno.com/2015/01/3390/ から頂いたものをさらに魔改造したデプロイスクリプト
<?php
/*
* GitHub & Bitbucket Deployment Sample Script
* Originally found at
* http://brandonsummers.name/blog/2012/02/10/using-bitbucket-for-automated-deployments/
* http://jonathannicol.com/blog/2013/11/19/automated-git-deployments-from-bitbucket/
*
* We assume you did a 'git clone -mirror' to your local repo directory,
* And then, 'GIT_WORK_TREE=[www directory] git checkout -f [your desired branch]'
*
*/
set_time_limit(0);
/**
* The Full Server Path to git repository and web location.
* Can be either relative or absolute path
*
* @var string
*/
$git_serverpath = '***webサーバー上にgitリポジトリが置かれている場所***';
$www_serverpath = '***webサーバーのディレクトリパス***';
/**
* The Secret Key so that it's a bit more secure to run this script
*
* @var string
*/
$secret_key = '***秘密のパスワード***';
/*
* Webhook Sample
* For BitBucket, use 'POST HOOK'
* For GitHub, use 'Webhooks'
* URL Format
* https://[Basic Auth ID]:[Basic Auth Pass]@example.com/deployments.php?key=EnterYourSecretKeyHere
* (https access & Basic Auth makes it a bit more secure if your server supports it)
*/
/**
* The TimeZone format used for logging.
* @link http://php.net/manual/en/timezones.php
*/
date_default_timezone_set('Asia/Tokyo');
class Deploy {
/**
* A callback function to call after the deploy has finished.
*
* @var callback
*/
public $post_deploy;
/**
* The name of the file that will be used for logging deployments. Set to
* FALSE to disable logging.
*
* @var string
*/
private $_log = 'deployments.log';
/**
* The timestamp format used for logging.
*
* @link http://www.php.net/manual/en/function.date.php
* @var string
*/
private $_date_format = 'Y-m-d H:i:sP';
/**
* The path to git
*
* @var string
*/
private $_git_bin_path = 'git';
/**
* The directory where your website and git repository are located,
* can be relative or absolute path
*
* @var string
*/
private $_git_dir;
private $_www_dir;
/**
* Sets up defaults.
*
* @param string $directory Directory where your website is located
* @param array $data Information about the deployment
*/
public function __construct($git_dir, $www_dir, $options = array())
{
// Determine the directory path
$this->_git_dir = realpath($git_dir).DIRECTORY_SEPARATOR;
$this->_www_dir = realpath($www_dir).DIRECTORY_SEPARATOR;
$available_options = array('log', 'date_format', 'git_bin_path');
foreach ($options as $option => $value)
{
if (in_array($option, $available_options))
{
$this->{'_'.$option} = $value;
}
}
$this->log('Attempting deployment...');
}
/**
* Writes a message to the log file.
*
* @param string $message The message to write
* @param string $type The type of log message (e.g. INFO, DEBUG, ERROR, etc.)
*/
public function log($message, $type = 'INFO')
{
if ($this->_log)
{
// Set the name of the log file
$filename = $this->_log;
if ( ! file_exists($filename))
{
// Create the log file
file_put_contents($filename, '');
// Allow anyone to write to log files
chmod($filename, 0666);
}
// Write the message into the log file
// Format: time --- type: message
file_put_contents($filename, date($this->_date_format).' --- '.$type.': '.$message.PHP_EOL, FILE_APPEND);
}
}
/**
* Executes the necessary commands to deploy the website.
*/
public function execute()
{
while (file_exists('/tmp/sfdeploy.pid')) {
$this->log('Waiting for finish another process...');
sleep(10);
}
touch('/tmp/sfdeploy.pid');
try
{
// Update the local repository
exec('cd ' . $this->_git_dir . ' && ' . $this->_git_bin_path . ' fetch && '. $this->_git_bin_path . ' pull --tags', $output);
$this->log('Fetching changes... '.implode(' ', $output));
exec('cd ' . $this->_git_dir . ' && ' . $this->_git_bin_path . ' tag', $tags);
rsort($tags);
exec('cd ' . $this->_git_dir . ' && ' . $this->_git_bin_path . ' checkout refs/tags/'.$tags[0]);
// Checking out to web directory
$updated = $this->upload_ftp($this->_www_dir, $tags[0]);
$this->log('Checking out changes to www directory... '.implode(' ', $output));
if (is_callable($this->post_deploy) && $updated)
{
call_user_func($this->post_deploy, $tags[0]);
}
$this->log('Deployment successful.');
}
catch (Exception $e)
{
$this->log($e, 'ERROR');
} finally {
unlink('/tmp/sfdeploy.pid');
}
}
public function upload_ftp($dir, $latest_tag) {
$updated = false;
$ftpValue = array(
'ftp_server' => '***FTPサーバー名***',
'ftp_user_name' => '***FTPユーザー名***',
'ftp_user_pass' => '***FTPパスワード***'
);
$connection = ftp_connect($ftpValue['ftp_server']);
$login_result = ftp_login(
$connection,
$ftpValue['ftp_user_name'],
$ftpValue['ftp_user_pass']
);
ftp_pasv($connection, true);
if (ftp_chdir($connection, "***デプロイ先FTPサーバーのドキュメントルートパス***")) {
//echo "Current directory is now: " . ftp_pwd($connection) . "\n";
} else {
ftp_close($connection);
throw new InternalErrorException('Couldn\'t change directory');
}
$ftpResult = ftp_nlist ($connection , '.' );
if (!$ftpResult) {
ftp_close($connection);
throw new InternalErrorException('Something went wrong.');
}
if (!in_array($latest_tag, $ftpResult)) {
ftp_chdir($connection, "***デプロイ先FTPサーバーのドキュメントルートパスの一個下***");
$this->upload_recursive($connection, $dir, 'sandyfox');
ftp_chdir($connection, "***デプロイ先FTPサーバーのドキュメントルートパス***");
ftp_mkdir($connection, $latest_tag);
$this->upload_recursive($connection, $dir, $latest_tag);
$updated = true;
}
ftp_close($connection);
return $updated;
}
private function upload_recursive($connection, $dir, $dst_dir = '.') {
$d = dir($dir);
while($file = $d->read()) { // do this for each file in the directory
if ($file != "." && $file != "..") { // to prevent an infinite loop
if (is_dir($dir."/".$file) && ($dir."/".$file) !== 'uncompress') { // do the following if it is a directory
$fpwd = ftp_pwd($connection);
if (!@ftp_chdir($connection, $dst_dir."/".$file)) {
ftp_mkdir($connection, $dst_dir."/".$file); // create directories that do not yet exist
}else{
ftp_chdir($connection, $fpwd);
}
$this->upload_recursive($connection, $dir."/".$file, $dst_dir."/".$file); // recursive part
} else {
$this->log('Uploading to FTP... '.$dst_dir."/".$file);
$upload = ftp_put($connection, $dst_dir."/".$file, $dir."/".$file, FTP_BINARY); // put the files
}
}
}
}
}
$deploy = new Deploy($git_serverpath, $www_serverpath);
$deploy->post_deploy = function($tagname) use ($deploy) {
global $git_serverpath;
$git_dir = realpath($git_serverpath).DIRECTORY_SEPARATOR;
$git_bin_path = 'git';
exec('cd ' . $git_dir . ' && ' . $git_bin_path . ' tag -n1 | grep '.$tagname, $taginfo);
$taginfo = trim(substr(implode($taginfo), 9));
$POST_DATA = array(
'payload' => json_encode(array(
'text' => "@channel: 新バージョンがデプロイされたよ。\n <http://***開発webサーバーのURL***".$tagname.">\n EXEダウンロード: <https://bitbucket.org/***BitbucketのリポジトリURL***/get/".$tagname.".zip>\n更新内容:".$taginfo,
'link_names' => 1
))
);
$curl=curl_init("https://hooks.slack.com/services/***Slack incoming webhookの投稿URL***");
curl_setopt($curl,CURLOPT_POST, TRUE);
curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($POST_DATA));
curl_setopt($curl,CURLOPT_SSL_VERIFYPEER, FALSE); // オレオレ証明書対策
curl_setopt($curl,CURLOPT_SSL_VERIFYHOST, FALSE); //
curl_setopt($curl,CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($curl,CURLOPT_COOKIEJAR, 'cookie');
curl_setopt($curl,CURLOPT_COOKIEFILE, 'tmp');
curl_setopt($curl,CURLOPT_FOLLOWLOCATION, TRUE); // Locationヘッダを追跡
$output= curl_exec($curl);
$deploy->log('Posting to Slack... ');
};
if ($_GET["key"] === $secret_key || $argv[1] === "--testtest") {
$deploy->execute();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment