Last active
September 5, 2023 20:28
-
-
Save Snaver/f890b897229847ee427d32dd6ecff6fb to your computer and use it in GitHub Desktop.
Laravel Continuous Integration & Delivery with Bitbucket Pipelines https://medium.com/@Snaverz/laravel-continuous-integration-delivery-with-bitbucket-pipelines-d13c78539044
This file contains hidden or 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
# Laravel pipelines https://confluence.atlassian.com/bitbucket/laravel-with-bitbucket-pipelines-913473967.html | |
# | |
# ----- | |
# You can specify a custom docker image from Docker Hub as your build environment. | |
#image: php:7.1.1 | |
# Bitbucket Pipelines now includes the option to allocate additional resources. | |
# By specifying the size of '2x', your pipeline will include double the resources (eg. 4GB memory → 8GB memory). | |
#options: | |
# size: 2x | |
pipelines: | |
branches: | |
master: | |
- step: | |
name: Sentry Release | |
image: getsentry/sentry-cli | |
script: | |
- sentry-cli releases -o "${SENTRY_ORG}" new -p "${SENTRY_PROJECT}" "${BITBUCKET_BUILD_NUMBER}" | |
- sentry-cli releases -o "${SENTRY_ORG}" set-commits --auto "${BITBUCKET_BUILD_NUMBER}" | |
- step: | |
name: NPM Build | |
image: node:8.9.4 | |
caches: | |
- node | |
script: | |
- npm install | |
- npm run dev | |
#- npm run tests ??? | |
artifacts: | |
- public/** | |
- step: | |
name: PHP Build | |
#image: php:7.1.12 | |
image: | |
name: snaver/docker-deploy | |
caches: | |
- composer | |
script: | |
- php -r "copy('.env.pipelines', '.env');" | |
- composer install --optimize-autoloader --no-interaction --prefer-dist --ignore-platform-reqs | |
services: | |
#- mysql | |
#- redis | |
artifacts: | |
- vendor/** | |
- step: | |
name: PHP Test | |
#image: php:7.1.12 | |
image: | |
name: snaver/docker-deploy | |
services: | |
#- mysql | |
script: | |
- php -r "copy('.env.pipelines', '.env');" | |
- php artisan migrate --seed | |
- ./vendor/bin/phpunit | |
- step: | |
name: Deploy (Production) | |
deployment: production | |
image: | |
name: snaver/docker-deploy | |
script: | |
- envoy run deploy --host=$DEPLOY_HOST --user=$DEPLOY_USER --path=$DEPLOY_PATH --build=$BITBUCKET_BUILD_NUMBER --commit=$BITBUCKET_COMMIT --branch=$BITBUCKET_BRANCH --php=php --dir=$BITBUCKET_CLONE_DIR | |
- step: | |
name: Sentry Finalize Release & Deploy | |
image: getsentry/sentry-cli | |
script: | |
- sentry-cli releases -o "${SENTRY_ORG}" finalize "${BITBUCKET_BUILD_NUMBER}" | |
- sentry-cli releases -o "${SENTRY_ORG}" deploys "${BITBUCKET_BUILD_NUMBER}" new -e "production" | |
# definitions: | |
# services: | |
# mysql: | |
# image: mysql | |
# environment: | |
# MYSQL_DATABASE: 'test' | |
# MYSQL_RANDOM_ROOT_PASSWORD: 'yes' | |
# MYSQL_USER: 'test' | |
# MYSQL_PASSWORD: 'secret' | |
# redis: | |
# image: redis |
This file contains hidden or 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
{ | |
"build": null, | |
"commit": null, | |
"branch": null | |
} |
This file contains hidden or 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
/bootstrap/cache/*.php | |
/.* | |
/node_modules | |
/storage | |
/vendor/composer/composer/tests/* | |
bitbucket-pipelines.yml | |
deployment-exclude-list.txt | |
Envoy.blade.php | |
package-lock.json | |
package.json | |
README.md | |
webpack.mix.js | |
yarn.lock |
This file contains hidden or 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
@servers(['web' => $user.'@'.$host,'localhost' => '127.0.0.1']) | |
@setup | |
// Sanity checks | |
if (empty($host)) { | |
exit('ERROR: $host var empty or not defined'); | |
} | |
if (empty($user)) { | |
exit('ERROR: $user var empty or not defined'); | |
} | |
if (empty($path)) { | |
exit('ERROR: $path var empty or not defined'); | |
} | |
if (empty($build)) { | |
exit('ERROR: $build var empty or not defined'); | |
} | |
if (empty($commit)) { | |
exit('ERROR: $commit var empty or not defined'); | |
} | |
if (file_exists($path) || is_writable($path)) { | |
exit("ERROR: cannot access $path"); | |
} | |
// Ensure given $path is a potential web directory (/home/* or /var/www/*) | |
if (!(preg_match("/(\/home\/|\/var\/www\/)/i", $path) === 1)) { | |
exit('ERROR: $path provided doesn\'t look like a web directory path?'); | |
} | |
$current_release_dir = $path . '/current'; | |
$releases_dir = $path . '/releases'; | |
$new_release_dir = $releases_dir . '/' . $build . '_' . $commit; | |
$remote = $user . '@' . $host . ':' . $new_release_dir; | |
// Command or path to invoke PHP | |
$php = empty($php) ? 'php' : $php; | |
@endsetup | |
@story('deploy') | |
rsync | |
manifest_file | |
setup_symlinks | |
verify_install | |
activate_release | |
optimise | |
migrate | |
cleanup | |
@endstory | |
@task('debug', ['on' => 'localhost']) | |
ls -la {{ $dir }} | |
@endtask | |
@task('rsync', ['on' => 'localhost']) | |
echo "* Deploying code from {{ $dir }} to {{ $remote }} *" | |
# https://explainshell.com/explain?cmd=rsync+-zrSlh+--exclude-from%3Ddeployment-exclude-list.txt+.%2F.+%7B%7B+%24remote+%7D%7D | |
rsync -zrSlh --stats --exclude-from=deployment-exclude-list.txt {{ $dir }}/ {{ $remote }} | |
@endtask | |
@task('manifest_file', ['on' => 'web']) | |
echo "* Writing deploy manifest file *" | |
echo -e "{\"build\":\""{{ $build }}"\", \"commit\":\""{{ $commit }}"\", \"branch\":\""{{ $branch }}"\"}" > {{ $new_release_dir }}/deploy-manifest.json | |
@endtask | |
@task('setup_symlinks', ['on' => 'web']) | |
echo "* Linking .env file to new release dir ({{ $path }}/.env -> {{ $new_release_dir }}/.env) *" | |
ln -nfs {{ $path }}/.env {{ $new_release_dir }}/.env | |
if [ -f {{ $new_release_dir }}/storage ]; then | |
echo "* Moving existing storage dir *" | |
mv {{ $new_release_dir }}/storage {{ $new_release_dir }}/storage.orig 2>/dev/null | |
fi | |
echo "* Linking storage directory to new release dir ({{ $path }}/storage -> {{ $new_release_dir }}/storage) *" | |
ln -nfs {{ $path }}/storage {{ $new_release_dir }}/storage | |
@endtask | |
@task('verify_install', ['on' => 'web']) | |
echo "* Verifying install ({{ $new_release_dir }}) *" | |
cd {{ $new_release_dir }} | |
{{ $php }} artisan --version | |
@endtask | |
@task('activate_release', ['on' => 'web']) | |
echo "* Activating new release ({{ $new_release_dir }} -> {{ $current_release_dir }}) *" | |
ln -nfs {{ $new_release_dir }} {{ $current_release_dir }} | |
@endtask | |
@task('migrate', ['on' => 'web']) | |
echo '* Running migrations *' | |
cd {{ $new_release_dir }} | |
{{ $php }} artisan migrate --force | |
@endtask | |
@task('optimise', ['on' => 'web']) | |
echo '* Clearing cache and optimising *' | |
cd {{ $new_release_dir }} | |
{{ $php }} artisan cache:clear | |
{{ $php }} artisan config:clear | |
{{ $php }} artisan route:clear | |
{{ $php }} artisan view:clear | |
# https://laravel.com/docs/5.5/deployment#optimization | |
{{ $php }} artisan config:cache | |
# Only use when no closure used in routes | |
#{{ $php }} artisan route:cache | |
#echo '* Reloading php-fpm *' | |
#sudo -S service php7.1-fpm reload | |
#echo '* Gracefully terminating Laravel Horizon *' | |
#{{ $php }} artisan horizon:terminate | |
#sudo supervisorctl stop horizon # workaround | |
#sudo supervisorctl start horizon # workaround | |
@endtask | |
@task('cleanup', ['on' => 'web']) | |
echo "* Executing cleanup command in {{ $releases_dir }} *" | |
ls -dt {{ $releases_dir }}/*/ | tail -n +4 | xargs rm -rf | |
@endtask |
@Snaver Is there a reason to split the Sentry steps up?
https://gist.github.com/Snaver/f890b897229847ee427d32dd6ecff6fb#file-bitbucket-pipelines-yml-L16
and
https://gist.github.com/Snaver/f890b897229847ee427d32dd6ecff6fb#file-bitbucket-pipelines-yml-L66
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
thanks for your wonderfully script...is there any way to implement rollback functionality in it?