Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mirroring repositories locally to deployer #129

Merged
merged 78 commits into from
Mar 2, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
78 commits
Select commit Hold shift + click to select a range
f371c52
Working on mirroring repositories locally to deployer
REBELinBLUE Nov 17, 2015
44471ed
cleanup
REBELinBLUE Nov 17, 2015
7ab3183
Fix DeployProject so it actually runs the script file rather than pas…
REBELinBLUE Nov 17, 2015
4c6699e
Removing then commands from a script
REBELinBLUE Nov 17, 2015
bbbd4f9
Make the name of the mirror reusable so that if multiple projects use…
REBELinBLUE Nov 17, 2015
279e0a5
Storing references to branches and tags from git
REBELinBLUE Nov 17, 2015
c4089d7
The association to the project model
REBELinBLUE Nov 17, 2015
aba35ca
Change the deployment reason dialog
REBELinBLUE Nov 17, 2015
7ca5b46
Run php-cs-fixer
REBELinBLUE Nov 17, 2015
ada6447
Hide branches and tags if none exist
REBELinBLUE Nov 17, 2015
91c9700
Move generating tags and branches to a job
REBELinBLUE Nov 17, 2015
4a4601d
Moved updating the git mirror to a separate job
REBELinBLUE Nov 17, 2015
e701c2f
Tar Gzip the release and send to the server
REBELinBLUE Nov 17, 2015
fd86ede
check for the tar program
REBELinBLUE Nov 17, 2015
de788ce
Ran php-cs-fixer
REBELinBLUE Nov 17, 2015
6d38693
Removed unused method
REBELinBLUE Nov 17, 2015
995adcf
Clean up
REBELinBLUE Nov 18, 2015
3e26e99
Fixed the remote_archive variable being wrong
REBELinBLUE Nov 18, 2015
690f029
Added a comment for refactoring
REBELinBLUE Nov 18, 2015
98aecc2
Using rsync to transfer files instead of scp, and git archive to arch…
REBELinBLUE Nov 18, 2015
fb57e79
Checking for gzip with installer
REBELinBLUE Nov 18, 2015
c10d41c
Reversing tags
REBELinBLUE Nov 18, 2015
47b2f85
Add missing PHPDoc block
REBELinBLUE Nov 18, 2015
2f35c92
Adding skeleton jobs for updating and cleaning up git mirrors
REBELinBLUE Nov 18, 2015
e1552c3
Moving git mirrors to another folder
REBELinBLUE Nov 18, 2015
7b93861
Fixed git archive script to set GIT_DIR and GIT_WORK_TREE
REBELinBLUE Nov 23, 2015
adcf491
Re-add recursive option
REBELinBLUE Dec 5, 2015
710bba3
Working on a cronjob to mirror repositories
REBELinBLUE Dec 10, 2015
31516d1
Fixed incorrect class
REBELinBLUE Jan 14, 2016
8b503c6
Fix a merge failure
REBELinBLUE Jan 14, 2016
7828984
Ran php-cs-fixer
REBELinBLUE Jan 14, 2016
f15efc3
Fixing an undefined variable
REBELinBLUE Feb 14, 2016
2f263b1
Changed update git mirrors to loop through the projects
REBELinBLUE Feb 14, 2016
0855ffa
Fixed update mirrors so it doesn't exit with a status of 1
REBELinBLUE Feb 14, 2016
141f4b7
Change storage_path() call
REBELinBLUE Feb 14, 2016
48301b8
Fixed command to use $this
REBELinBLUE Feb 14, 2016
379be67
Remove orphaned mirror directories
REBELinBLUE Feb 14, 2016
b105185
Remove unneeded use
REBELinBLUE Feb 14, 2016
3a00993
Clean up variable names
REBELinBLUE Feb 14, 2016
fab55b2
Cleanup
REBELinBLUE Feb 14, 2016
7ff7e95
Renamed the clone step to create
REBELinBLUE Feb 14, 2016
a6f8dfa
Removed an unneeded command
REBELinBLUE Feb 14, 2016
9e4a02a
Compare tags with version suffixes
REBELinBLUE Feb 14, 2016
60caa71
Change select lists on dialog to use select2
REBELinBLUE Feb 14, 2016
b1bd650
Change deploy project so it exports the commit hash not HEAD
REBELinBLUE Feb 14, 2016
87b258e
Refactor the updateRepoInfo() method as it does not need to clone the…
REBELinBLUE Feb 14, 2016
9aa25b3
Remove method which is no longer needed
REBELinBLUE Feb 14, 2016
8def2fe
Clean up PHPCS complaints
REBELinBLUE Feb 14, 2016
32a8af1
Ran "php-cs-fixer"
REBELinBLUE Feb 14, 2016
48474a4
Fixed typo
REBELinBLUE Feb 14, 2016
e7d87c2
Do not update the git mirror as part of the updateRepoInfo() process
REBELinBLUE Feb 15, 2016
69cef60
Starting to implement rollback
REBELinBLUE Feb 15, 2016
1cf8d6f
Work on rollback to a previous deployment
REBELinBLUE Feb 15, 2016
4991e82
Updated dependencies
REBELinBLUE Feb 16, 2016
0622ebf
Added IDE helper
REBELinBLUE Feb 19, 2016
535db98
Clean up
REBELinBLUE Feb 19, 2016
f4ca627
Updated
REBELinBLUE Feb 20, 2016
d9e06a9
Tweak supervisor config
REBELinBLUE Feb 20, 2016
aa782c5
Formatting
REBELinBLUE Feb 20, 2016
5f5b90e
Added JSCS to vagrantfile
REBELinBLUE Feb 20, 2016
9394d54
Clean up
REBELinBLUE Feb 20, 2016
87890c9
Clean up the format of the scripts
REBELinBLUE Feb 20, 2016
4b1035a
Working on re-deployment
REBELinBLUE Feb 21, 2016
852a2db
PHPDoc block
REBELinBLUE Feb 24, 2016
34331cc
Added a method to load the commands used in a deployment
REBELinBLUE Feb 25, 2016
6e123d0
Filter optional commands
REBELinBLUE Feb 25, 2016
fda4f2d
Clean up
REBELinBLUE Feb 25, 2016
641bd26
Switch route to post
REBELinBLUE Feb 25, 2016
654434f
Populating the rollback dialog
REBELinBLUE Feb 25, 2016
a819e46
Clean up code style
REBELinBLUE Feb 25, 2016
813d252
Add vendor/bin to /var/www/deployer/vendor/bin:/home/vagrant/.compose…
REBELinBLUE Feb 25, 2016
cde0095
Sort out JS for rollback dialog
REBELinBLUE Feb 25, 2016
cf981cd
Sort out JS for rollback dialog
REBELinBLUE Feb 25, 2016
0cf6e2d
Getting rollback working
REBELinBLUE Feb 25, 2016
757fd12
Ran php-cs-fixer
REBELinBLUE Feb 25, 2016
7d52ffe
Fixing composer.lock
REBELinBLUE Mar 2, 2016
5e9cf11
Ran php-cs-fixer
REBELinBLUE Mar 2, 2016
f2499a3
Ignore create-release
REBELinBLUE Mar 2, 2016
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions .php_cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ $finder = Symfony\Component\Finder\Finder::create()
->in('app')
->in('database')
->name('*.php')
->notName('Kernel.php') // There has to be a better way to do this!
->ignoreDotFiles(true)
->ignoreVCS(true);

Expand Down Expand Up @@ -70,4 +69,4 @@ return Symfony\CS\Config\Config::create()
->level(Symfony\CS\FixerInterface::PSR2_LEVEL)
->fixers($fixers)
->finder($finder)
->setUsingCache(true);
->setUsingCache(true);
1 change: 1 addition & 0 deletions .phpci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ build_settings:
- "storage"
- "tests"
- "vendor"
- "create-release"

setup:
wipe:
Expand Down
2 changes: 2 additions & 0 deletions Vagrantfile
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,8 @@ Vagrant.configure("2") do |config|
config.vm.provision "shell", inline: "echo 'alias phpunit=\"php $(which phpunit)\"' >> /home/vagrant/.profile"
config.vm.provision "shell", inline: "echo 'export PATH=/var/www/deployer/vendor/bin:$PATH' >> /home/vagrant/.profile"

config.vm.provision "shell", inline: "echo 'export PATH=/var/www/deployer/vendor/bin:$PATH' >> /home/vagrant/.profile"

# Update composer on each boot
config.vm.provision "shell", inline: "sudo /usr/local/bin/composer self-update", run: "always"
end
4 changes: 2 additions & 2 deletions app/Console/Commands/ClearOldKeys.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@ public function __construct()
public function handle()
{
// Clear out old SSH key files
$files = glob(storage_path() . '/app/*ssh*'); // sshkey and gitssh
$folders = glob(storage_path() . '/app/*clone*'); // cloned copies of code
$files = glob(storage_path('app/') . '*ssh*'); // sshkey and gitssh
$folders = glob(storage_path('app/') . '*clone*'); // cloned copies of code

$this->info('Found ' . count($files) . ' files and ' . count($folders) . ' folders to purge');

Expand Down
75 changes: 75 additions & 0 deletions app/Console/Commands/ClearOrphanMirrors.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
<?php

namespace REBELinBLUE\Deployer\Console\Commands;

use Illuminate\Console\Command;
use REBELinBLUE\Deployer\Project;
use Symfony\Component\Process\Process;

/**
* Checks for and cleans up orphaned git mirrors.
*/
class ClearOrphanMirrors extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'deployer:purge-mirrors';

/**
* The console command description.
*
* @var string
*/
protected $description = 'Purges git mirrors which are no longer in use by projects';

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

/**
* Execute the console command.
*
* @return mixed
*/
public function handle()
{
$current_mirrors = [];

Project::where('is_template', false)->chunk(10, function ($projects) use (&$current_mirrors) {
foreach ($projects as $project) {
$current_mirrors[] = $project->mirrorPath();
}
});

$current_mirrors = collect($current_mirrors);

$all_mirrors = collect(glob(storage_path('app/mirrors/') . '*.git'));

// Compare the 2 collections get a list of mirrors which are no longer in use
$orphan_mirrors = $all_mirrors->diff($current_mirrors);

$this->info('Found ' . $orphan_mirrors->count() . ' orphaned mirrors');

// Now loop through the mirrors and delete them from storage
foreach ($orphan_mirrors as $mirror_dir) {
$process = new Process("rm -rf {$mirror_dir}");
$process->setTimeout(null);
$process->run();

if ($process->isSuccessful()) {
$this->info('Deleted ' . basename($mirror_dir));
} else {
$this->info('Failed to delete ' . basename($mirror_dir));
}
}
}
}
3 changes: 2 additions & 1 deletion app/Console/Commands/CreateUser.php
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,8 @@ public function handle()

event(new UserWasCreated($user, $arguments['password']));
} elseif ($password_generated) {
$message .= ', however you elected to not email the account details to them. Their password is ' . $arguments['password'];
$message .= ', however you elected to not email the account details to them. ';
$message .= 'Their password is ' . $arguments['password'];
}

$this->info($message);
Expand Down
15 changes: 9 additions & 6 deletions app/Console/Commands/InstallApp.php
Original file line number Diff line number Diff line change
Expand Up @@ -118,9 +118,9 @@ public function handle()
$this->line('');
$this->comment('2. Setup the cronjobs, see "crontab"');
$this->line('');
$this->comment('3. Setup the socket server and queue runner, see "supervisor.conf" for an example of how to do this with supervisor');
$this->comment('3. Setup the socket server & queue runner, see "supervisor.conf" for an example commands');
$this->line('');
$this->comment('4. Ensure that "storage" and "public/upload" are writable by the webserver, for example run "chmod -R 777 storage"');
$this->comment('4. Ensure that "storage" and "public/upload" are writable by the webserver');
$this->line('');
$this->comment('5. (Optional) Setup logrotate, see "logrotate.conf"');
$this->line('');
Expand Down Expand Up @@ -391,7 +391,8 @@ private function getInstallInformation()
if (count($locales) === 1) {
$locale = $locales[0];
} else {
$locale = $this->choice('Language', $locales, array_search(Config::get('app.fallback_locale'), $locales, true));
$default = array_search(Config::get('app.fallback_locale'), $locales, true);
$locale = $this->choice('Language', $locales, $default);
}

return [
Expand Down Expand Up @@ -584,7 +585,9 @@ protected function checkRequirements()
}

if (!count($this->getDatabaseDrivers())) {
$this->error('At least 1 PDO database driver is required. Either sqlite, mysql, pgsql or sqlsrv, check your php.ini file');
$this->error(
'At least 1 PDO driver is required. Either sqlite, mysql, pgsql or sqlsrv, check your php.ini file'
);
$errors = true;
}

Expand All @@ -599,7 +602,7 @@ protected function checkRequirements()
}

// Programs needed in $PATH
$required_commands = ['ssh', 'ssh-keygen', 'git', 'scp'];
$required_commands = ['ssh', 'ssh-keygen', 'git', 'scp', 'tar', 'gzip'];

foreach ($required_commands as $command) {
$process = new Process('which ' . $command);
Expand Down Expand Up @@ -630,7 +633,7 @@ protected function checkRequirements()

if ($errors) {
$this->line('');
$this->block('Deployer cannot be installed, as not all requirements are met. Please review the errors above before continuing.');
$this->block('Deployer cannot be installed. Please review the errors above before continuing.');
$this->line('');

return false;
Expand Down
5 changes: 4 additions & 1 deletion app/Console/Commands/UpdateApp.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,10 @@ public function __construct()
*/
public function handle()
{
if (!$this->verifyInstalled() || $this->hasRunningDeployments() || $this->composerOutdated() || !$this->checkRequirements()) {
if (!$this->verifyInstalled() ||
$this->hasRunningDeployments() ||
$this->composerOutdated() ||
!$this->checkRequirements()) {
return;
}

Expand Down
61 changes: 61 additions & 0 deletions app/Console/Commands/UpdateGitMirrors.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
<?php

namespace REBELinBLUE\Deployer\Console\Commands;

use Carbon\Carbon;
use Illuminate\Console\Command;
use Illuminate\Foundation\Bus\DispatchesJobs;
use REBELinBLUE\Deployer\Jobs\UpdateGitMirror;
use REBELinBLUE\Deployer\Project;

/**
* Updates the mirrors for all git repositories.
*/
class UpdateGitMirrors extends Command
{
use DispatchesJobs;

const UPDATES_TO_QUEUE = 3;
const UPDATE_FREQUENCY_MINUTES = 5;

/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'deployer:update-mirrors';

/**
* The console command description.
*
* @var string
*/
protected $description = 'Pulls in updates for git mirrors';

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

/**
* Execute the console command.
*
* @return mixed
*/
public function handle()
{
$last_mirrored_since = Carbon::now()->subMinutes(self::UPDATE_FREQUENCY_MINUTES);
$todo = self::UPDATES_TO_QUEUE;

Project::where('last_mirrored', '<', $last_mirrored_since)->chunk($todo, function ($projects) {
foreach ($projects as $project) {
$this->dispatch(new UpdateGitMirror($project));
}
});
}
}
15 changes: 13 additions & 2 deletions app/Console/Kernel.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@

namespace REBELinBLUE\Deployer\Console;

use REBELinBLUE\Deployer\Bootstrap\ConfigureLogging;
use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
use REBELinBLUE\Deployer\Bootstrap\ConfigureLogging;
use REBELinBLUE\Deployer\Bootstrap\ConfigureLogging as ConsoleLogging;

/**
* Kernel class.
Expand All @@ -16,7 +17,7 @@ class Kernel extends ConsoleKernel
* @var array
*/
protected $customBooters = [
\Illuminate\Foundation\Bootstrap\ConfigureLogging::class => ConfigureLogging::class,
\Illuminate\Foundation\Bootstrap\ConfigureLogging::class => ConsoleLogging::class,
];

/**
Expand All @@ -37,8 +38,10 @@ class Kernel extends ConsoleKernel
\REBELinBLUE\Deployer\Console\Commands\CheckUrl::class,
\REBELinBLUE\Deployer\Console\Commands\CreateUser::class,
\REBELinBLUE\Deployer\Console\Commands\ClearOrphanAvatars::class,
\REBELinBLUE\Deployer\Console\Commands\ClearOrphanMirrors::class,
\REBELinBLUE\Deployer\Console\Commands\ClearStalledDeployment::class,
\REBELinBLUE\Deployer\Console\Commands\ClearOldKeys::class,
\REBELinBLUE\Deployer\Console\Commands\UpdateGitMirrors::class,
\REBELinBLUE\Deployer\Console\Commands\InstallApp::class,
\REBELinBLUE\Deployer\Console\Commands\UpdateApp::class,
\REBELinBLUE\Deployer\Console\Commands\ResetApp::class,
Expand All @@ -57,6 +60,10 @@ protected function schedule(Schedule $schedule)
->everyFiveMinutes()
->withoutOverlapping();

$schedule->command('deployer:update-mirrors')
->everyFiveMinutes()
->withoutOverlapping();

$schedule->command('deployer:checkurls')
->everyFiveMinutes()
->withoutOverlapping();
Expand All @@ -67,6 +74,10 @@ protected function schedule(Schedule $schedule)
->at('00:30')
->withoutOverlapping();

$schedule->command('deployer:purge-mirrors')
->daily()
->withoutOverlapping();

$schedule->command('deployer:purge-temp')
->hourly()
->withoutOverlapping();
Expand Down
40 changes: 38 additions & 2 deletions app/Deployment.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace REBELinBLUE\Deployer;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\DB;
Expand Down Expand Up @@ -35,14 +36,15 @@ class Deployment extends Model implements PresentableInterface, RuntimeInterface
*
* @var array
*/
protected $fillable = ['reason', 'branch', 'project_id', 'source', 'build_url'];
protected $fillable = ['reason', 'branch', 'project_id', 'source', 'build_url',
'commit', 'committer_email', 'committer', ];

/**
* The attributes excluded from the model's JSON form.
*
* @var array
*/
protected $hidden = ['created_at', 'deleted_at', 'updated_at', 'user'];
protected $hidden = ['created_at', 'deleted_at', 'updated_at', 'user', 'commands'];

/**
* Additional attributes to include in the JSON representation.
Expand Down Expand Up @@ -107,6 +109,40 @@ public function user()
->withTrashed();
}

/**
* Define a command attribute to be able to access to commands relationship.
*
* @return Command
*/
public function getCommandsAttribute()
{
if (!$this->relationLoaded('commands')) {
$this->loadCommands();
}

return $this->getRelation('commands');
}

/**
* Query the DB and load the HasMany relationship for commands.
*
* @return Deployment
*/
private function loadCommands()
{
$collection = Command::join('deploy_steps', 'commands.id', '=', 'deploy_steps.command_id')
->where('deploy_steps.deployment_id', $this->getKey())
->distinct()
->orderBy('step')
->orderBy('order')
->get(['commands.*', 'deployment_id']);

$hasMany = new HasMany(Command::query(), $this, 'deployment_id', 'id');
$hasMany->matchMany([$this], $collection, 'commands');

return $this;
}

/**
* Has many relationship.
*
Expand Down
2 changes: 1 addition & 1 deletion app/Http/Controllers/Admin/UserController.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public function index()
{
return view('admin.users.listing', [
'title' => Lang::get('users.manage'),
'users' => $this->repository->getAll()->toJson(), // Because PresentableInterface toJson() is not working in the view
'users' => $this->repository->getAll()->toJson(), // PresentableInterface toJson() is not working in view
]);
}

Expand Down
Loading