Skip to content

Instantly share code, notes, and snippets.

@wodka

wodka/deploy.php Secret

Forked from clops/deploy.php
Last active August 29, 2015 14:04
Show Gist options
  • Save wodka/0e75e036fb9ac1ca3077 to your computer and use it in GitHub Desktop.
Save wodka/0e75e036fb9ac1ca3077 to your computer and use it in GitHub Desktop.
#!/usr/bin/php
<?php
/**
* GIT Merge Helper
*
* Installation:
* 1. Download / Clone this GIST https://gist.github.com/clops/3ac9cd6c42a66ba65101 into some directory
* 2. chmod a+x deploy.php
* 3. Add an alias into .bash_profile with a full path to the deploy.php script, mine is:
* alias deploy="~/dev/3ac9cd6c42a66ba65101/deploy.php"
* 4. Done!
*
* Usage:
* 1. Inside a GIT directory type: deploy
* 2. Follow on-screen instructions
*
* @author Alexey Kulikov <a.kulikov@gmail.com>
* @since Aug 2014
**/
echo "+++++++++ \e[1mGIT P4T Console Deploy V 1.0\e[0m Author: AK +++++++++\n";
/* 1. ---- COLLECT PARAMETER / USER INPUT --------------------------------------------- */
//what is the branch name that needs to be merged?
if(!isset($_SERVER['argv'][1])){
$branchName = readline("Enter branchname to merge: ");
}else{
$branchName = $_SERVER['argv'][1];
}
//what is the branch type (hotfix/bugfix/feature)?
$branchType = explode('/', $branchName);
if(count($branchType) != 2){ //yes this is not the full syntax check, branch name is checked for validity later
errorMessage("Incorrent branch name \"".$branchName."\", it must be of the form (hotfix|bugfix|feature)/ZEN-XXXXX");
}
//is there some special destination or are we doing a special deployment-merge
if(!isset($_SERVER['argv'][2])){
$mergeIntoBranchName = trim(readline("Enter branchname to merge into (leave empty for default master/release/development merge): "));
}else{
$mergeIntoBranchName = $_SERVER['argv'][2];
}
/* 2. ---- REMEMBER STARTING POINT ---------------------------------------------------- */
//first step --> remember the currently selected branch and stash any changes made
$currentState = `git status --porcelain -b`;
$currentState = explode("\n", $currentState);
$currentBranch = trim(str_replace('##','',$currentState[0]));
$currentBranch = explode('...', $currentBranch);
$currentBranch = $currentBranch[0]; //weird :)
$stashed = false;
if(isset($currentState[1]) && !empty($currentState[1])){ //any modified files? stash them!
echo "Stashing unsaved changes away...\n";
echo `git stash`;
$stashed = true;
}
/* 3. ---- SOME BASIC ERROR CHECKS ---------------------------------------------------- */
//lets roll
$branchType = $branchType[0];
echo "Will deploy branch \"".$branchName."\", of type \"".$branchType."\"\n";
echo "Pulling fresh branch list from origin... ";
echo `git pull`; //refresh list of branches
//now check if the desired branch that has to be merged exists at all
$existingBranches = getBranches();
if(!in_array($branchName, $existingBranches)){
errorMessage("Branch \"".$branchName."\" does NOT exist!");
}
//we also defined a destination branch? check is also then
if(!empty($mergeIntoBranchName)){
if(!in_array($mergeIntoBranchName, $existingBranches)){
errorMessage("Destination Branch \"".$mergeIntoBranchName."\" does NOT exist!");
}
//set special marker for a manual A->B merge
$branchType = 'manual';
}
/* 4. ---- ACTUAL MERGING ------------------------------------------------------------- */
//make sure we have the desired branch locally (needed for merge)
echo "Checking out branch \"{$branchName}\"\n";
echo `git checkout {$branchName}`;
switch($branchType){
case 'hotfix': {
if(!mergeBranch($branchName, 'master')){
errorMessage("Merge Terminated manually");
}
}
case 'bugfix': {
if($currentReleaseBranch = getCurrentReleaseBranch()){
if(!mergeBranch($branchName, $currentReleaseBranch)){
errorMessage("Merge Terminated manually");
}
}else{
echo "There is no current release branch, skipping\n";
}
}
case 'feature': {
if(!mergeBranch($branchName, 'development')){
errorMessage("Merge Terminated manually");
}
break;
}
case 'manual': { //this is a special type denoting a merge into a user-defined branch
if(!mergeBranch($branchName, $mergeIntoBranchName)){
errorMessage("Merge Terminated manually");
}
break;
}
default: {
errorMessage("Unknown branch type \"".$branchType."\", possible types are \"hotfix\", \"bugfix\" or \"feature\"");
}
}
//no errors, great! remove remote branch, its been merged everywhere %)
$confirm = readline("\n\e[92mRemove branch from origin? Confirm with \"Y\", any other input to skip:\e[0m ");
if($confirm == 'Y'){
echo "Removing branch from origin...";
echo `git push origin --delete {$branchName}`;
echo "done!\n";
}
//switch back to the original branch
if($currentBranch != 'development'){
echo "Switching back to the initial branch\n";
echo `git checkout {$currentBranch}`;
}
//anything stashed away before?
if($stashed){
echo "Getting back stashed changes...\n";
echo `git stash pop`;
}
echo "FIN!\n\n";
###################### UTILITY HELPER FUNCTIONS BELOW ######################
/**
* Utility function: Merge a source branch into the destination branch
*
* @param String $source
* @param String $destination
**/
function mergeBranch($source, $destination){
echo "\n+++++++++ \e[1mMerging ".$source." --> ".$destination."\e[0m +++++++++\n";
echo "Checking out {$destination}\n";
echo `git checkout {$destination}`;
echo `git pull`;
echo "Merging {$source}\n";
echo `git merge {$source} `;
//now need the user to confirm this prior to pushing changes
$confirm = readline("\n\e[92mConfirm merge with \"Y\", any other input to terminate:\e[0m ");
if($confirm == 'Y'){
echo `git push -u origin {$destination}`;
echo "\n\n";
return true;
}
return false;
}
/**
* Utility function: Echo error message and terminate script
*
* @param String $message
**/
function errorMessage($message){
echo "\n\e[31mERROR: ".$message.". Terminating\e[0m\n\n";
exit;
}
/**
* Utility function: get a list of all known branches
*
* @return Array
**/
function getBranches(){
$branches = `git branch -a`;
$branches = explode("\n",$branches);
foreach($branches as &$branch){
$branch = str_replace('remotes/origin/', '', trim($branch));
}
return $branches;
}
/**
* Utility Function: get the current release branch from origin
*
* @return String
**/
function getCurrentReleaseBranch(){
$branches = `git branch -r --no-merged`;
$branches = explode("\n",$branches);
foreach($branches as $branch){
$branch = trim($branch);
if(strstr($branch, 'origin/release/') !== false){
return str_replace('origin/', '', $branch);
}
}
return false;
}
?>
@clops
Copy link

clops commented Aug 12, 2014

Thanks for the fix :)
btw, I have pushed V1.2 with more bugs fixed and some convenience options added!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment