Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
Save more on your purchases now! discount-offer-chevron-icon
Savings automatically calculated. No voucher code required.
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Conferences
Free Learning
Arrow right icon

Laravel 5.0 Essentials

Save for later
  • 9 min read
  • 12 Aug 2016

article-image

In this article by Alfred Nutile from the book, Laravel 5.x Cookbook, we will learn the following topics:

  • Setting up Travis to Auto Deploy when all is Passing
  • Working with Your .env File
  • Testing Your App on Production with Behat

(For more resources related to this topic, see here.)

Setting up Travis to Auto Deploy when all is Passing

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.

Getting ready…

You really need to see the section before this, otherwise continue knowing this will make no sense.

How to do it…

  1. Install the travis command line tool in Homestead as noted in their docs https://github.com/travis-ci/travis.rb#installation. Make sure to use Ruby 2.x:
    sudo apt-get install ruby2.0-dev
    sudo gem install travis -v 1.8.2 --no-rdoc --no-ri
    
  2. Then in the recipe folder I run the command
    > travis setup codedeploy
  3. I answer all the questions keeping in mind:
    •     The KEY and SECRET are the ones we made of the I AM User in the Section before this
    •     The S3 KEY is the filename not the KEY we used for a above. So in my case I just use the name again of the file latest.zip since it sits inside the recipe-artifact bucket.
  4. Finally I open the .travis.yml file, which the above modifies and I update the before-deploy area so the zip command ignores my .env file otherwise it would overwrite the file on the server.

    laravel-50-essentials-img-0

How it works…

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.

See also…

Travis Docs:

Working with Your .env File

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.

Getting ready….

A base install is fine I will use the existing install to show some tricks around this.

How to do it…

  1. Minimize using Conventions as much as possible
    •     config/queue.php I can do this to have one or more Queues

      laravel-50-essentials-img-1

    •     config/filesystems.php

      laravel-50-essentials-img-2

  2. Use the Config file as much as possible. For example this is in my .env

    laravel-50-essentials-img-3

  3. If I add config/marvel.php and then make it look like this

    laravel-50-essentials-img-4

  4. My .env can be trimmed down by KEY=VALUES later on I can call to those:
    •    Config::get('marvel.MARVEL_API_VERSION')
    •    Config::get('marvel.MARVEL_API_BASE_URL')

      laravel-50-essentials-img-5

  5. Now to easily send to Staging or Production using the EnvDeployer library

    >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

laravel-50-essentials-img-6

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.

laravel-50-essentials-img-7

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.

How it works…

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.

See also…

Testing Your App on Production with Behat

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.

Getting ready…

Any app will do. In my case I am going to hit production with some tests I made earlier.

How to do it…

  1. Tag a Behat test @smoke or just a Scenario that you know it is safe to run on Production for example features/home/search.feature.

    laravel-50-essentials-img-8

  2. Update behat.yml adding a profile call production.

    laravel-50-essentials-img-9

  3. Then run
    > 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.

  4. Another method is to login as a demo user. And after logging in as that user you can see data that is related to that user only so you can test authenticated level of data and interactions. For example database/seeds/UserTableSeeder.php add the demo user to the run method

    laravel-50-essentials-img-10

  5. Then update your .env.

    laravel-50-essentials-img-11

  6. Now push that .env setting up to Production. 
    >php artisan envdeploy:push production
  7. Then we update our behat.yml file to run this test even on Production features/auth/login.feature.

    laravel-50-essentials-img-12

  8. Now we need to commit our work and push to GitHub so TravisCI can deploy and changes:

    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.

  9. Now let's run this test, from our vagrant box
    > vendor/bin/behat -slogin_ui --profile=production
  10. But it fails because I am setting up the start of this test for my local database not the remote database features/bootstrap/LoginPageUIContext.php.

    laravel-50-essentials-img-13

  11. So I can basically begin to create a way to setup the state of the world on the remote server.
    > php artisan make:controller SetupBehatController
  12. And update that controller to do the setup.

    laravel-50-essentials-img-14

  13. And make the route app/Http/routes.php

    laravel-50-essentials-img-15

  14. Then update the behat test features/bootstrap/LoginPageUIContext.php

    laravel-50-essentials-img-16

  15. And we should do some cleanup! First add a new method to features/bootstrap/LoginPageUIContext.php.

    laravel-50-essentials-img-17

  16. Then add that tag to the Scenarios this is related to features/auth/login.feature

    laravel-50-essentials-img-18

  17. Then add the controller like before and route app/Http/Controllers/CleanupBehatController.php

    laravel-50-essentials-img-19

  18. Then Push and we are ready test this user with fresh state and then clean up when they are done! In this case I could test editing the Profile from one state to another.

How it works…

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!

See also…

Summary

This article gives a summary of Setting up Travis, working with .env files and Behat. 

Resources for Article:


Further resources on this subject: