What I want to do is, to switch from FTP deployment into GIT. I mean, I want to keep automatically keep synced my Bitbucket private repo and my shared webhosting. I googled and found following script to deploy my webserver (based on this article).
// Set these dependant on your BB credentials
$username = 'username';
$password = 'password';
// Grab the data from BB's POST service and decode
$json = stripslashes($_POST['payload']);
$data = json_decode($json);
// Set some parameters to fetch the correct files
$uri = $data->repository->absolute_url;
$node = $data->commits[0]->node;
$files = $data->commits[0]->files;
// Foreach through the files and curl them over
foreach ($files as $file) {
if ($file->type == "removed") {
unlink($file->file);
} else {
$url = "https://api.bitbucket.org/1.0/repositories"
. $uri . "raw/" .$node ."/" . $file->file;
$path = $file->file;
$dirname = dirname($path);
if (!is_dir($dirname)) {
mkdir($dirname, 0775, true);
}
$fp = fopen($path, 'w');
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_USERPWD, "$username:$password");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_FILE, $fp);
$data = curl_exec($ch);
curl_close($ch);
fclose($fp);
}
}
The problem is, this works on simple changesets like 5-10 file change. But when I push the whole project for the first time (for example with 600-700 files and folders) into my bitbucket private profile, this script doesn't work. (just doesn't, no error on errors.log)
What am I missing?
By the way, Can I do something like that:
As we know, Bitbucket can send POST information into an exact url (given by user) directly after a commit has been made. So when deploy.php receives POST, we can get the entire commit as a zip or tar, clean our current files and unzip the new commit into webserver.
Is that possible? If yes then how? Any other good way?
I found the code below for automated deploying php project. The problem is https://bitbucket.org/$username/$reponame/get/tip.zip
this url doesnt work on bitbucket private git repo: probably related with authentication (I haven't tested this on public repo) What i need is to get the last commit's zip file and unzip inside my project.
<?
// your Bitbucket username
$username = "edifreak";
// your Bitbucket repo name
$reponame = "canvas-game-demo";
// extract to
$dest = "./"; // leave ./ for relative destination
////////////////////////////////////////////////////////
// Let's get stuff done!
// set higher script timeout (for large repo's or slow servers)
set_time_limit(380);
// download the repo zip file
$repofile = file_get_contents("https://bitbucket.org/$username/$reponame/get/tip.zip");
file_put_contents('tip.zip', $repofile);
unset($repofile);
// unzip
$zip = new ZipArchive;
$res = $zip->open('tip.zip');
if ($res === TRUE) {
$zip->extractTo('./');
$zip->close();
} else {
die('ZIP not supported on this server!');
}
// delete unnecessary .hg files
@unlink("$username-$reponame-tip/.hgignore");
@unlink("$username-$reponame-tip/.hg_archival.txt");
// function to delete all files in a directory recursively
function rmdir_recursively($dir) {
if (is_dir($dir)) {
$objects = scandir($dir);
foreach ($objects as $object) {
if ($object != "." && $object != "..") {
if (filetype($dir."/".$object) == "dir") rmdir_recursively($dir."/".$object); else unlink($dir."/".$object);
}
}
reset($objects);
rmdir($dir);
}
}
// function to recursively copy the files
function copy_recursively($src, $dest) {
if (is_dir($src)) {
if($dest != "./") rmdir_recursively($dest);
@mkdir($dest);
$files = scandir($src);
foreach ($files as $file)
if ($file != "." && $file != "..") copy_recursively("$src/$file", "$dest/$file");
}
else if (file_exists($src)) copy($src, $dest);
rmdir_recursively($src);
}
// start copying the files from extracted repo and delete the old directory recursively
copy_recursively("$username-$reponame-tip", $dest);
// delete the repo zip file
unlink("tip.zip");
// Yep, we're done :)
echo "We're done!";
?>
Upload SSH Key To GitHub Repository Go to Settings -> Deploy keys and click on the Add Deploy Key button to add the SSH key. You can also give a name to this key in the title field and copy the key to the box. Click on the Add Key button to save the SSH key.
Your repository is now connected to Heroku. In the “Automatic deploys” section, click “Enable Automatic deploys”. Once you make a change in your code and push it to GitHub, Heroku will automatically deploy it. Let's manually deploy a branch by clicking “Deploy branch” under the “Manual deploy” section.
The first step in deploying your PHP project is to connect the Git repository. You can easily connect a Github or Bitbucket account and choose from the list of repositories available within the account.
This solution do not provides authentication:
// download the repo zip file
$repofile = file_get_contents("https://bitbucket.org/$username/$reponame/get/tip.zip");
file_put_contents('tip.zip', $repofile);
unset($repofile);
But curl allows it. So a zip archive can be downloaded from a private repository in same way like in first script.
$node = ''; // a node from repo, like c366e96f16...
$fp = fopen($path, 'w');
$ch = curl_init("https://bitbucket.org/$username/$reponame/get/$node.zip");
curl_setopt($ch, CURLOPT_USERPWD, "$username:$password");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_FILE, $fp);
$data = curl_exec($ch);
curl_close($ch);
fclose($fp);
I have tested it for my bitbucket account. It's work very well.
If necessary to get last changeset node that we should use bitbucket api GET a list of changesets:
$username = 'login';
$password = 'pass';
$owner = $username; // if user is owner
$repo = 'repo name';
$response = "";
$callback = function($url, $chunk) use (&$response){
$response .= $chunk;
return strlen($chunk);
};
$ch = curl_init("https://api.bitbucket.org/1.0/repositories/$owner/$repo/changesets?limit=1");
curl_setopt($ch, CURLOPT_USERPWD, "$username:$password");
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('User-Agent:Mozilla/5.0'));
curl_setopt($ch, CURLOPT_WRITEFUNCTION, $callback);
curl_exec($ch);
curl_close($ch);
$changesets = json_decode($response, true);
$node = $changesets['changesets'][0]['node'];
$raw_node = $changesets['changesets'][0]['raw_node'];
print($node . PHP_EOL);
print($raw_node . PHP_EOL);
I recently discovered Capistrano which is a great tool. It was initially developed for ruby but it's also great in combination with php http://www.davegardner.me.uk/blog/2012/02/13/php-deployment-with-capistrano/
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With