Skip to content

Instantly share code, notes, and snippets.

@akuzemchak
Created July 8, 2013 17:20
Show Gist options
  • Select an option

  • Save akuzemchak/5950710 to your computer and use it in GitHub Desktop.

Select an option

Save akuzemchak/5950710 to your computer and use it in GitHub Desktop.

Revisions

  1. Aaron Kuzemchak created this gist Jul 8, 2013.
    165 changes: 165 additions & 0 deletions DeployCommand.php
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,165 @@
    <?php

    // app/commands/DeployCommand.php

    use Illuminate\Console\Command;
    use Symfony\Component\Console\Input\InputOption;
    use Symfony\Component\Console\Input\InputArgument;

    class DeployCommand extends Command
    {
    /**
    * The console command name
    *
    * @var string
    */
    protected $name = 'deploy';

    /**
    * The console command description
    *
    * @var string
    */
    protected $description = 'Deploy the application to a server';

    /**
    * The server configuration
    *
    * @var array
    */
    protected $config = array();

    /**
    * The SFTP client
    *
    * @var Net_SFTP
    */
    protected $sftp;

    /**
    * Create a new command instance
    *
    * @return void
    */
    public function __construct()
    {
    parent::__construct();
    }

    /**
    * Execute the console command.
    *
    * @return void
    */
    public function fire()
    {
    $this->verifyServer();
    $this->buildArchive();
    $this->moveToServer();
    $this->runServerCommands();
    $this->cleanUp();
    }

    /**
    * Verify that the specified server exists in the config
    *
    * @return void
    */
    protected function verifyServer()
    {
    $server = $this->argument('server');
    $config = Config::get("deployments.{$server}");

    if (is_null($config)) {
    $this->error("Environment \"{$server}\" does not exist");
    exit;
    }

    $this->config = $config;
    }

    /**
    * Build an archive of the local files
    *
    * @return void
    */
    protected function buildArchive()
    {
    $this->comment('Building archive...');
    exec('git archive HEAD --format=tar | gzip > project.tar.gz');
    }

    /**
    * Copy the archive to the server
    *
    * @return void
    */
    protected function moveToServer()
    {
    $this->comment('Moving archive to server...');
    $this->sftp = new Net_SFTP($this->config['host']);

    if (!$this->sftp->login($this->config['user'], $this->config['password'])) {
    $this->error('Could not connect to server');
    exit;
    }

    $this->sftp->chdir($this->config['path']);
    $this->sftp->put('project.tar.gz', 'project.tar.gz', NET_SFTP_LOCAL_FILE);
    }

    /**
    * Run commands on the server
    *
    * @return void
    */
    protected function runServerCommands()
    {
    $this->comment('Executing commands on server...');

    $commands = array();
    $commands[] = "cd {$this->config['path']}";
    $commands[] = 'tar -xzf project.tar.gz';
    $commands[] = './composer.phar self-update';
    $commands[] = './composer.phar install --no-dev';
    $commands[] = '/usr/local/bin/php artisan migrate';
    $commands[] = 'rm project.tar.gz';

    echo $this->sftp->exec(implode('; ', $commands));
    }

    /**
    * Miscellaneous cleanup
    *
    * @return void
    */
    protected function cleanUp()
    {
    $this->comment('Cleaning up...');
    exec('rm project.tar.gz');

    $this->info('Finished!');
    }

    /**
    * Get the console command arguments
    *
    * @return array
    */
    protected function getArguments()
    {
    return array(
    array('server', InputArgument::REQUIRED, 'The deployment server'),
    );
    }

    /**
    * Get the console command options
    *
    * @return array
    */
    protected function getOptions()
    {
    return array();
    }
    }
    16 changes: 16 additions & 0 deletions artisan.php
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,16 @@
    <?php

    // app/start/artisan.php

    /*
    |--------------------------------------------------------------------------
    | Register The Artisan Commands
    |--------------------------------------------------------------------------
    |
    | Each available Artisan command must be registered with the console so
    | that it is available to be called. We'll register every command so
    | the console gets access to each of the command object instances.
    |
    */

    Artisan::add(new DeployCommand());
    7 changes: 7 additions & 0 deletions composer.json
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,7 @@
    {
    // Other composer.json stuff...

    "require-dev": {
    "phpseclib/phpseclib": "0.3.*"
    }
    }
    12 changes: 12 additions & 0 deletions deployments.php
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,12 @@
    <?php

    // app/config/deployments.php

    return array(
    'production' => array(
    'host' => 'myserver.com',
    'user' => 'ssh_user',
    'password' => 'ssh_password',
    'path' => '/path/to/project/root',
    ),
    );