In this article by Alfred Nutile from the book, Laravel 5.x Cookbook, we will learn the following topics:
(For more resources related to this topic, see here.)
Level 0 of any work should be getting a deployment workflow setup. What that means in this case is that a push to GitHub will trigger our Continuous Integration (CI). And then from the CI, if the tests are passing, we trigger the deployment. In this example I am not going to hit the URL Forge gives you but I am going to send an Artifact to S3 and then have call CodeDeploy to deploy this Artifact.
You really need to see the section before this, otherwise continue knowing this will make no sense.
sudo apt-get install ruby2.0-dev
sudo gem install travis -v 1.8.2 --no-rdoc --no-ri
> travis setup codedeploy
Well if you did the CodeDeploy section before this one you will know this is not as easy as it looks. After all the previous work we are able to, with the one command travis setup codedeploy punch in securely all the needed info to get this passing build to deploy. So after phpunit reports things are passing we are ready.
With that said we had to have a lot of things in place, S3 bucket to put the artifact, permission with the KEY and SECRET to access the Artifact and CodeDeploy, and a CodeDeploy Group and Application to deploy to. All of this covered in the previous section.
After that it is just the magic of Travis and CodeDeploy working together to make this look so easy.
Travis Docs:
The workflow around this can be tricky. Going from Local, to TravisCI, to CodeDeploy and then to AWS without storing your info in .env on GitHub can be a challenge. What I will show here are some tools and techniques to do this well.
A base install is fine I will use the existing install to show some tricks around this.
>composer require alfred-nutile-inc/env-deployer:dev-master
Follow the readme.md for that library. Then as it says in the docs setup your config file so that it matches the destination IP/URL and username and path for those services.
I end up with this config file config/envdeployer.php
Now the trick to this library is you start to enter KEY=VALUES into your .env file stacked on top of each other. For example, my database settings might look like this.
so now I can type:
>php artisan envdeployer:push production
Then this will push over SSH your .env to production and swap out the related @production values for each KEY they are placed above.
The first mindset to follow is conventions before you put a new KEY=VALUE into the .env file set back and figure out defaults and conventions around what you already must have in this file. For example must haves, APP_ENV, and then I always have APP_NAME so those two together do a lot to make databases, queues, buckets and so on. all around those existing KEYs.
It really does add up, whether you are working alone or on a team focus on these conventions and then using the config/some.php file workflow to setup defaults.
Then libraries like the one I use above that push this info around with ease. Kind of like Heroku you can command line these settings up to the servers as needed.
https://packagist.org/packages/mathiasgrimm/laravel-env-validator
https://laracasts.com/series/laravel-5-fundamentals/episodes/6
So your app is now on Production! Start clicking away at hundreds of little and big features so you can make sure everything went okay or better yet run Behat! Behat on production? Sounds crazy but I will cover some tips on how to do this including how to setup some remote conditions and clean up when you are done.
Any app will do. In my case I am going to hit production with some tests I made earlier.
> vendor/bin/behat -shome_ui --tags=@smoke --profile=production
I run an Artisan command to run all these
Then you will see it hit the production url and only the Scenarios you feel are safe for Behat.
>php artisan envdeploy:push production
Since this is a seed and not a migration I need to rerun seeds on production. Since this is a new site, and no one has used it this is fine BUT of course this would have been a migration if I had to do this later in the applications life.
> vendor/bin/behat -slogin_ui --profile=production
> php artisan make:controller SetupBehatController
Not to hard! Now we have a workflow that can save us a ton of clicking around Production after every deployment.
To begin with I add the tag @smoke to tests I considered safe for production. What does safe mean? Basically read only tests that I know will not effect that site's data. Using the @smoke tag I have a consistent way to make Suites or Scenarios as safe to run on Production.
But then I take it a step further and create a way to test authenticated related state. Like make a Favorite or updating a Profile! By using some simple routes and a user I can begin to tests many other things on my long list of features I need to consider after every deploy.
All of this happens with the configurability of Behat and how it allows me to manage different Profiles and Suites in the behat.yml file!
Lastly I tie into the fact that Behat has hooks. I this case I tie in to the @AfterScenario by adding that to my Annotation. And I add another hooks @profile so it only runs if the Scenario has that Tag.
That is it, thanks to Behat, Hooks and how easy it is to make Routes in Laravel I can easily take care of a large percentage of what otherwise would be a tedious process after every deployment!
This article gives a summary of Setting up Travis, working with .env files and Behat.
Further resources on this subject: