Created
July 9, 2020 18:35
-
-
Save mattstein/588a0540ebb71b734db73d59233cc702 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?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