DEV Community

Riju Pramanik
Riju Pramanik

Posted on

How to use Github Actions with Laravel Vapor

Laravel Vapor has been the hot new technology to deploy an infinitely* scalable app powered by AWS Lambda. But with new technology, comes new additional hurdles to deploy your app.

*Note - Albeit limited by budget and resource limits

TLDR: Use this YAML file

name: Deploy to production on: push: branches: [ master ] jobs: vapor: name: Check out, build and deploy using Vapor runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - name: Setup PHP uses: shivammathur/setup-php@v2 with: php-version: 8.0 tools: composer:v2 coverage: none - name: Require Vapor CLI run: composer global require laravel/vapor-cli - name: Deploy Environment run: vapor deploy production env: VAPOR_API_TOKEN: ${{ secrets.VAPOR_API_TOKEN }} 
Enter fullscreen mode Exit fullscreen mode

YAML File to deploy right from your Github Repository

And ensure VAPOR_API_TOKEN is set in your Github repository secrets. You can generate the token from this link.

Note - This file does NOT run tests before deploying. Testing-step added in the next section.
Running tests before deploying

If you are deploying to any production-level server, you probably want to run your tests to get a sanity check on every feature working as intended.

A couple of things to note while running tests for your Laravel Application in a CI

  1. You want to avoid SQLite and use MySQL whenever possible. This is because of some edge case migrations which show up as errors, even though they work fine on MySQL
  2. If you are using PHPUnit instead of Pest (Highly recommended) , change the action named "Run Tests"
name: Test and deploy to Vapor on: push: jobs: test: name: Test runs-on: ubuntu-latest services: mysql: image: mysql:8.0 env: MYSQL_ROOT_PASSWORD: password MYSQL_DATABASE: test ports: - 3306:3306 options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3 steps: - name: Check out code uses: actions/checkout@v2 - name: Cache dependencies uses: actions/cache@v2 with: path: ~/.composer/cache/files key: dependencies-composer-${{ hashFiles('composer.json') }} - name: Set up PHP uses: shivammathur/setup-php@v2 with: php-version: 8.0 extensions: dom, curl, libxml, mbstring, zip, pcntl, pdo, sqlite, pdo_sqlite, mysql - name: Copy environment config file run: php -r "file_exists('.env') || copy('.env.ci', '.env');" - name: Validate Composer run: composer validate - name: Install Composer dependencies run: composer install --prefer-dist --no-interaction --no-suggest - name: Generate key run: php artisan key:generate - name: Directory Permissions run: chmod -R 777 storage bootstrap/cache - name: Run DB migrations run : php artisan migrate - name: Run Tests run: ./vendor/bin/pest env: APP_ENV: testing DB_CONNECTION: mysql DB_DATABASE: test DB_HOST: 127.0.0.1 DB_PORT: 3306 DB_USERNAME: root DB_PASSWORD: password - name: Upload artifacts uses: actions/upload-artifact@v2 if: failure() with: name: Logs path: ./storage/logs deploy: name: Deploy to Vapor runs-on: ubuntu-latest if: github.ref == 'refs/heads/develop' || github.ref == 'refs/heads/master' needs: - test steps: - name: Check out code uses: actions/checkout@v2 - name: Validate Composer run: composer validate - name: Install Composer dependencies run: composer install --prefer-dist --no-interaction --no-suggest --no-dev - name: Deploy code run: ./vendor/bin/vapor deploy ${{ env.APP_ENV }} --commit="${{ github.sha }}" env: APP_ENV: ${{ github.ref == 'refs/heads/master' && 'production' || 'staging' }} VAPOR_API_TOKEN: ${{ secrets.VAPOR_API_TOKEN }} - name: Upload artifacts uses: actions/upload-artifact@v2 if: failure() with: name: Logs path: ./storage/logs 
Enter fullscreen mode Exit fullscreen mode

Entire CI file for running tests before deploying

A few salient features of this CI file are -

  • It runs tests before deploying
  • If tests fail, the artefacts/logs are available immediately as downloadable zip files
  • Develop branch deploys to staging, Master/Main branch deploys to production automatically. Single file across both the branches.
  • Github allows granular control over each step, and this remains highly customizable as per your needs
  • Every step is broken down into clean modular sections, with verbose logging if any step fails

Builds take around 3-5 minutes but depend a lot on the number and size of your tests. This will greatly reduce if you use the multithreaded option for PHPUnit, but that's an optimization I can leave for you.

Top comments (0)