Skip to content

Instantly share code, notes, and snippets.

@paul1522
Last active September 22, 2020 22:01
Show Gist options
  • Save paul1522/ade61b670ac4911c914bcaee58689548 to your computer and use it in GitHub Desktop.
Save paul1522/ade61b670ac4911c914bcaee58689548 to your computer and use it in GitHub Desktop.
{{--
# Source: https://gist.github.com/paulgeneres/ade61b670ac4911c914bcaee58689548
# If you change it here don't forget to update the gist.
# Based on https://github.com/papertank/envoy-deploy/blob/master/Envoy.blade.php
#
# Quick Start: Put this at the top of your .env file. Create an .env.production file.
# DEPLOY_ENV="production"
# DEPLOY_SERVER="production.server"
# DEPLOY_REPOSITORY="git@github.com:owner/repo.git"
# DEPLOY_BRANCH="master"
# DEPLOY_PATH="/var/www/awesome.io"
# DEPLOY_PHP_VERSION="7.4"
# DEPLOY_LOCAL_TMP="/tmp/envoy/awesome.io"
--}}
@setup
require __DIR__.'/vendor/autoload.php';
$dotenv = Dotenv\Dotenv::createImmutable(__DIR__);
try {
$dotenv->load();
$dotenv->required(['DEPLOY_PHP_VERSION', 'DEPLOY_LOCAL_TMP', 'DEPLOY_SERVER', 'DEPLOY_REPOSITORY', 'DEPLOY_PATH'])->notEmpty();
} catch ( Exception $e ) {
echo $e->getMessage();
}
$php_ver = $_ENV['DEPLOY_PHP_VERSION'];
$tmp = $_ENV['DEPLOY_LOCAL_TMP'];
$user = $_ENV['DEPLOY_USER'] ?? 'envoy';
$server = $_ENV['DEPLOY_SERVER'];
$repo = $_ENV['DEPLOY_REPOSITORY'];
$branch = $_ENV['DEPLOY_BRANCH'] ?? 'master';
$path = $_ENV['DEPLOY_PATH'];
$slack = $_ENV['DEPLOY_SLACK_WEBHOOK'] ?? '';
$db_database = $_ENV['DB_DATABASE'];
$env = $_ENV['DEPLOY_ENV'];
if ( substr($path, 0, 1) !== '/' ) throw new Exception('Careful - your deployment path does not begin with /');
$date = ( new DateTime )->format('YmdHis');
$env = $env <> "" ? $env : "production";
$user = $user <> "" ? $user : "envoy";
$branch = $branch <> "" ? $branch : "master";
$path = rtrim($path, '/');
$release = $path.'/'.$date;
$tmp_release = $tmp.'/'.$date;
$db_password = bin2hex(random_bytes(16));
$php = "php{$php_ver}";
$user_server = "{$user}@{$server}";
$db_database = $env == "production" ? $db_database : "{$db_database}_{$env}"
@endsetup
@servers ( ['web' => "{$user}@{$server}", 'localhost' => "127.0.0.1" ] )
@story('test-locally')
clone-locally
build-locally
@endstory
@story('test-remotely')
clone-remotely
build-remotely
@endstory
@story('initial-deploy')
clone-remotely
build-remotely
rsync-remotely
initialize
@endstory
@story('deploy')
clone-remotely
build-remotely
rsync-remotely
deployment-links
deployment-migrate
deployment-cache
deployment-finish
@endstory
@story('cleanup')
deployment-cleanup
@endstory
@story('zap')
deployment-zap
@endstory
@task ('clone-locally', ['on' => 'localhost'])
echo "Cloning repository into {{ $tmp_release }}"
mkdir -p {{ $tmp }} || exit 1
cd {{ $tmp }} || exit 1
git clone {{ $repo }} --branch={{ $branch }} --depth=1 -q {{ $tmp_release }} || exit 1
rm -rf {{ $tmp_release }}/.git || exit 1
echo "Repository cloned"
@endtask
@task ('build-locally', ['on' => 'localhost'])
echo "Starting build {{ $date }}"
cd {{ $tmp_release }} || exit 1
{{ $php }} composer.phar install --no-dev
npm --non-interactive --no-progress install
npm --non-interactive --no-progress run production
echo "Build complete"
@endtask
@task ('clone-remotely', ['on' => 'web'])
echo "Cloning repository into {{ $tmp_release }}"
mkdir -p {{ $tmp }} || exit 1
cd {{ $tmp }} || exit 1
git clone {{ $repo }} --branch={{ $branch }} --depth=1 -q {{ $tmp_release }} || exit 1
rm -rf {{ $tmp_release }}/.git || exit 1
echo "Repository cloned"
@endtask
@task ('build-remotely', ['on' => 'web'])
echo "Starting build {{ $date }}"
cd {{ $tmp_release }} || exit 1
{{ $php }} composer.phar install --no-dev
npm --non-interactive --no-progress install
npm --non-interactive --no-progress run production
echo "Build complete"
@endtask
@task ('rsync-remotely', ['on' => 'web'])
echo "Copying build to {{ $path }}"
rsync -a {{ $tmp_release }} {{ $path }}
echo "Upload complete"
@endtask
@task ('initialize', ['on' => 'web'])
if [ ! -d {{ $path }}/current ]; then
cd {{ $path }}
mv {{ $release }}/storage {{ $path }}/storage
chmod -R ug+rwX,o-rwx {{ $path }}/storage
chmod -R ug+rwX,o-rwx {{ $release }}/bootstrap/cache
ln -s {{ $path }}/storage {{ $release }}
ln -s {{ $path }}/storage/app/public {{ $release }}/public/storage
echo {{$date}} > {{ $path }}/storage/app/build.dat
echo "Storage directory set up"
mv {{ $release }}/.env.{{ $env }} {{ $path }}/.env
rm {{ $release }}/.env.*
echo "DB_DATABASE={{ $db_database }}" >> {{ $path }}/.env
echo "DB_USERNAME={{ $db_database }}" >> {{ $path }}/.env
echo "DB_PASSWORD={{ $db_password }}" >> {{ $path }}/.env
chmod ug=rw,o-rwx {{ $path }}/.env
ln -s {{ $path }}/.env {{ $release }}/.env
cd {{ $release }}
{{ $php }} artisan key:generate
#{{ $php }} artisan optimize --quiet
echo "Environment file set up"
mysql -e "create database {{ $db_database }}"
mysql -e "create user '{{ $db_database }}'@'localhost' identified by '{{ $db_password }}'"
mysql -e "grant all privileges on {{$db_database}}.* to '{{ $db_database }}'@'localhost'"
{{ $php }} artisan migrate --force --no-interaction --seed
echo "Database initialized"
chmod -R u+rwX,g+rX-w,o-rwx {{ $release }}
chmod -R ug+rwX {{ $release }}/bootstrap/cache
sudo chown -R {{ $user }}.www-data {{ $release }}
sudo chown -R {{ $user }}.www-data {{ $path }}/storage {{ $release }}/bootstrap/cache
sudo chown {{ $user }}.www-data {{ $path }}/.env
ln -s {{ $release }} {{ $path }}/current
cd {{ $path }}/current
{{ $php }} composer.phar dumpautoload
echo "Initial deployment ({{ $date }}) complete"
else
echo "Deployment path already initialized (current symlink exists)!"
fi
@endtask
@task('deployment-links', ['on' => 'web'])
cd {{ $path }}
rm -rf {{ $release }}/storage
ln -s {{ $path }}/storage {{ $release }}/storage
ln -s {{ $path }}/storage/app/public {{ $release }}/public/storage
echo {{$date}} > {{ $path }}/storage/app/build.dat
echo "Storage directories set up"
ln -s {{ $path }}/.env {{ $release }}/.env
rm {{ $release }}/.env.{{ $env }}
echo "Environment file set up"
@endtask
@task('deployment-migrate', ['on' => 'web'])
{{ $php }} {{ $release }}/artisan migrate --env={{ $env }} --force --no-interaction
echo "Database migration complete"
@endtask
@task('deployment-cache', ['on' => 'web'])
{{ $php }} {{ $release }}/artisan view:clear --quiet
{{ $php }} {{ $release }}/artisan cache:clear --quiet
{{ $php }} {{ $release }}/artisan config:clear --quiet
{{ $php }} {{ $release }}/artisan route:clear --quiet
echo 'Cache cleared'
@endtask
@task('deployment-finish', ['on' => 'web'])
chmod -R u+rwX,g+rX-w,o-rwx {{ $release }}
sudo chown -R {{ $user }}.www-data {{ $release }}
sudo chown -R {{ $user }}.www-data {{ $path }}/storage {{ $release }}/bootstrap/cache
sudo chmod -R ug+rwX,o-rwx {{ $path }}/storage
sudo chmod -R ug+rwX,o-rwx {{ $release }}/bootstrap/cache
ln -nfs {{ $release }} {{ $path }}/current
cd {{ $path }}/current
{{ $php }} composer.phar dumpautoload
echo "Deployment ({{ $date }}) finished"
@endtask
@task('deployment-cleanup', ['on' => 'web'])
cd {{ $path }}
find . -maxdepth 1 -name "20*" -mmin +2880 | head -n 5 | xargs rm -Rf
echo "Cleaned up old deployments"
@endtask
@task('deployment_option_cleanup', ['on' => 'web'])
cd {{ $path }}
@if ( isset($cleanup) && $cleanup )
find . -maxdepth 1 -name "20*" -mmin +2880 | head -n 5 | xargs rm -Rf
echo "Cleaned up old deploments"
@endif
@endtask
@task('deployment-zap', ['on' => 'web'])
sudo rm -rf {{ $path }}
mysql -e "drop database {{ $db_database }}"
mysql -e "drop user '{{ $db_database }}'@'localhost'"
echo "Zapped it"
@endtask
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment