Using Bitbucket for Automated Deployments

Posted . Visible to the public.

See also:

  • http://jonathannicol.com/blog/2013/11/19/automated-git-deployments-from-bitbucket/
  • http://symmetrycode.com/super-easy-deployment-with-git-and-bitbucket/

Bitbucket provides git hooks that can be used for code deployment. Code deployment means updating the code changes to the production server. The following requires that git client is installed in the production.

Workflow

  • Commit changes and push them up to your Bitbucket repository
  • Bitbucket sends a POST request to a deployment script on your server
  • The deployment script pulls changes into it’s local repository (which is in the web-root) which updates the website
  • Repeat
  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 name of the branch to pull from.
  * 
  * @var string
  */
  private $_branch = 'master';

  /**
  * The name of the remote to pull from.
  * 
  * @var string
  */
  private $_remote = 'origin';

  /**
  * The directory where your website and git repository are located, can be 
  * a relative or absolute path
  * 
  * @var string
  */
  private $_directory;

  /**
  * Sets up defaults.
  * 
  * @param  string  $directory  Directory where your website is located
  * @param  array   $data       Information about the deployment
  */
  public function __construct($directory, $options = array())
  {
      // Determine the directory path
      $this->_directory = realpath($directory).DIRECTORY_SEPARATOR;

      $available_options = array('log', 'date_format', 'branch', 'remote');

      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()
  {
      try
      {
          // Make sure we're in the right directory
          exec('cd '.$this->_directory, $output);
          $this->log('Changing working directory... '.implode(' ', $output));

          // Discard any changes to tracked files since our last deploy
          exec('git reset --hard HEAD', $output);
          $this->log('Reseting repository... '.implode(' ', $output));

          // Update the local repository
          exec('git pull '.$this->_remote.' '.$this->_branch, $output);
          $this->log('Pulling in changes... '.implode(' ', $output));

          // Secure the .git directory
          exec('chmod -R og-rx .git');
          $this->log('Securing .git directory... ');

          if (is_callable($this->post_deploy))
          {
              call_user_func($this->post_deploy, $this->_data);
          }

          $this->log('Deployment successful.');
      }
      catch (Exception $e)
      {
          $this->log($e, 'ERROR');
      }
  }

  }

    // This is just an example
   $deploy = new Deploy('/var/www/foobar.com');

   $deploy->post_deploy = function() use ($deploy) {
     // hit the wp-admin page to update any db changes
     exec('curl http://www.foobar.com/wp-admin/upgrade.php?step=upgrade_db');
     $deploy->log('Updating wordpress database... ');
   };

   $deploy->execute();
kiatng
Last edit
Posted by kiatng to Git (2014-06-21 08:52)