Skip to content

Instantly share code, notes, and snippets.

@mattstein
Created July 9, 2020 18:35
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mattstein/588a0540ebb71b734db73d59233cc702 to your computer and use it in GitHub Desktop.
Save mattstein/588a0540ebb71b734db73d59233cc702 to your computer and use it in GitHub Desktop.
<?php
namespace Deployer;
require 'recipe/common.php';
require 'recipe/rsync.php';
set('application', 'workingconcept/wrkcpt-craft');
set('repository', 'https://github.com/workingconcept/wrkcpt-craft');
$shared = [
'storage',
'web/cpresources',
];
$exclude = [
'.git',
'.babelrc',
'/.gitignore',
'/.env',
'/.env.example',
'/storage/',
'/node_modules/',
'.github',
'/.lando/',
'/.lando.yml',
'/scripts/',
'/src/',
'.ddev',
'.storybook',
'/stories/',
'deploy.php',
'/*.config.js',
'/webpack.mix.js',
'/tests/',
'/codeception.yml',
];
add('rsync', [ 'exclude' => $exclude ]);
// Sync from the current directory (project root)
set('rsync_src', function () {
return __DIR__;
});
// Exclude anything that doesn’t need to be in production.
set('upload_exclude', $exclude);
// Hosts
host('cms.workingconcept.com')
->hostname('kitty.wrk.us')
->stage('master') // branch from GitHub Action
->user('forge')
->set('db_database', 'forge')
->set('deploy_path', '~/cms.workingconcept.com');
host('deploy.workingconcept.com')
->hostname('georgemichael.wrk.us')
->stage('develop') // branch from GitHub Action
->user('forge')
->set('db_database', 'forge')
->set('deploy_path', '~/deploy.workingconcept.com');
set('db_backup_path', '{{deploy_path}}/release-backups');
// Speed up deployment
set('ssh_multiplexing', true);
// [Optional] Allocate tty for git clone. Default value is false.
set('git_tty', true);
// Shared files/dirs between deploys
add('shared_files', [ '.env' ]);
add('shared_dirs', $shared);
// Writable dirs by web server
add('writable_dirs', $shared);
task('deploy:clear-caches', function () {
run('{{bin/php}} {{release_path}}/craft cache/flush-all');
run('{{bin/php}} {{release_path}}/craft clear-caches/all');
})->desc('Clear caches');
task('deploy:run-migrations', function () {
run('{{bin/php}} {{release_path}}/craft migrate/all');
run('{{bin/php}} {{release_path}}/craft project-config/sync');
})->desc('Run migrations');
task('database:backup', function () {
run('mkdir -p {{db_backup_path}}');
// match .dep/releases format for comparison: `20200701022225`
$datestamp = date('YmdHis');
run('{{bin/php}} {{release_path}}/craft backup/db {{db_backup_path}}/{{release_name}}-'.$datestamp.'.sql');
})->desc('Back up database');
task('database:restore', function () {
// TODO: import MySQL backup
})->desc('Restore database');
set('db_backups_list', function() {
$list = explode("\n", run('ls -dt {{db_backup_path}}/*.sql'));
$list = array_map(function ($dump) {
return basename(rtrim(trim($dump), '/'));
}, $list);
return $list;
});
task('database:prune-backups', function () {
$releases = get('releases_list');
$backups = get('db_backups_list');
foreach ($backups as $filename) {
$parts = explode('-', $filename);
if (count($parts) < 1) {
continue;
}
$release = $parts[0];
if (!in_array($release, $releases)) {
run("rm {{db_backup_path}}/$filename");
}
}
})->desc('Prune database backups');
task('check-health', function () {
// TODO: ping something on host (CP login?) to confirm pulse
})->desc('Check health');
// nearly works identically, except for major difference in flags
/**
* Nearly works like rsync recipe, except for major difference in flags
* that can’t be changed with upload’s rsync. (`rsync -rz -e` vs `rsync -azP`).
*/
task('upload', function () {
$options = [
'--delete'
];
foreach (get('upload_exclude') as $item) {
$options[] = sprintf("--exclude='%s'", $item);
}
upload(
__DIR__ . '/',
'{{release_path}}/',
['options' => $options]
);
});
// Tasks
desc('Deploy + migrate + symlink');
task('deploy', [
'deploy:info',
'deploy:prepare',
'deploy:lock',
'deploy:release',
'rsync',
//'upload',
'deploy:shared',
'deploy:writable',
'deploy:clear-caches',
'database:backup',
'deploy:run-migrations',
'deploy:clear-caches',
'deploy:symlink',
'deploy:unlock',
'cleanup',
]);
after('deploy', 'success');
after('cleanup', 'database:prune-backups');
// [Optional] if deploy fails automatically unlock.
after('deploy:failed', 'deploy:unlock');
/**
* In an ideal world, we’d pull the target environment’s database and files into
* the build server and run the migration before continuing.
*/
/**
* TODO
* - confirm health before deploy:symlink?
* - redirect traffic while migrations are running?
* - create Craft recipe?
* - make sure `craft` is executable
* - automatically roll back database on failure?
* - replace `rsync` with custom task that uses upload()
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment