Skip to content

Instantly share code, notes, and snippets.

@mzarallo
Last active April 26, 2024 17:08
Show Gist options
  • Save mzarallo/496cd218a5f2401fe9367b10be0c938c to your computer and use it in GitHub Desktop.
Save mzarallo/496cd218a5f2401fe9367b10be0c938c to your computer and use it in GitHub Desktop.
Github action to test your application in Laravel and deploy via SSH
APP_KEY=
APP_ENV=local
APP_DEBUG=true
APP_URL=http://127.0.0.1:8000
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laravel
DB_USERNAME=root
DB_PASSWORD=root
SESSION_LIFETIME=1

Instructions

Summary

Github Actions to test Laravel application (unit, feature & dusk tests) on MySql 8, deploy application connecting via ssh and run deployment script inside your server.

Just to test your app.

  1. Create the directory ./github/workflows at the root of the project.
  2. Add the test_main.yml file inside the ./github/workflows.
  3. Add the .env.ci file at the root of the project.
  4. Now any pull request on the main branch that affects code within the paths configured in the pipeline will execute the pipeline (feel free to modify the pipeline as best suits your workflow).

If you want to deploy to your server via ssh.

  1. Add the deploy_prod.yml file inside the ./github/workflows.
  2. Add the deploy.sh file at the root of the project.
  3. Modify all the lines /var/www/project inside the deploy.sh and deploy_prod.yml files with the name of your directory.
  4. Add the following secrets inside repository settings (repository settings -> secrets -> actions): HOST (your server), PRIVATE_SSH_KEY (your private ssh key, you must have previously added your public key to the server at ~/ .ssh/authorized_keys to allow you to connect to the server), USER (user that will be used to try to connect to the server).
  5. Now any push on the main branch will execute the deployment on your server, once it successfully connects to your server it will execute the deploy.sh script located at the root of the project (feel free to modify the pipeline and script as best suits your workflow).
#!/bin/sh
set -e
echo "๐Ÿšš Dploying application"
echo "โฌ‡๏ธ Laravel down"
(sudo php artisan down) || true
echo "โฌ‡๏ธ Updating base code: main branch"
sudo git fetch origin main
sudo git reset --hard origin/main
echo "๐Ÿ“ฆ Installing composer dependencies"
sudo composer install --no-interaction --prefer-dist --optimize-autoloader --no-dev
echo "๐Ÿ—ƒ๏ธ Running migrations"
sudo php artisan migrate --force
echo "๐Ÿ”„ Restarting queue"
sudo php artisan queue:restart
echo "๐Ÿงน Recreating cache"
sudo php artisan optimize
echo "๐Ÿ“ฆ Installing Npm dependencies"
sudo npm ci
echo "๐Ÿ—๏ธ Compiling assets"
sudo npm run production
echo "๐Ÿ” Applying permissions"
sudo find /var/www/project -type f -exec chmod 644 {} \;
sudo find /var/www/project -type d -exec chmod 755 {} \;
sudo chown -R www-data:www-data /var/www/project
sudo chgrp -R www-data /var/www/project/storage /var/www/project/bootstrap/cache
sudo chmod -R ug+rwx /var/www/project/storage /var/www/project/bootstrap/cache
echo "๐Ÿ”„ Restarting Php"
echo "" | sudo -S service php8.1-fpm reload
echo "โฌ†๏ธ Rising Laravel"
sudo php artisan up
echo "๐ŸŽ‰ Deployed application"
name: Deploy Prod
on:
push:
branches: [main]
paths:
- "app/**"
- "config/**"
- "database/**"
- "routes/**"
- "resources/**"
- "tests/**"
jobs:
deploy:
name: Deploy Prod
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v2
- name: Deploy to Prod
uses: appleboy/ssh-action@master
with:
username: ${{ secrets.USER }}
host: ${{ secrets.HOST }}
key: ${{ secrets.PRIVATE_SSH_KEY }}
script: "cd /var/www/project && sudo sh deploy.sh"
name: Build & Test Main
on:
pull_request:
branches: [main]
paths:
- ".github/**"
- "app/**"
- "config/**"
- "database/**"
- "routes/**"
- "resources/**"
- "tests/**"
jobs:
build-test:
name: Build & Test (main branch)
runs-on: ubuntu-20.04
steps:
- name: Setting MySql 8
run: |
echo -e "Enable LOAD DATA LOCAL INFILE in my.cnf\n"
echo -e "SETTING secure-file-priv TO EMPTY STRING\n"
echo -e "[mysqld]\nsecure-file-priv=''" | sudo tee -a /etc/mysql/my.cnf
echo -e "SETTING local_infile TO ON\n"
echo -e "[mysqld]\nlocal_infile='ON'" | sudo tee -a /etc/mysql/my.cnf
echo -e "Start MYSQL service, it is off by default\n"
sudo systemctl enable mysql.service
sudo systemctl start mysql.service
echo -e "Creating Laravel Database\n"
mysql --host 127.0.0.1 -uroot -proot -e 'CREATE DATABASE IF NOT EXISTS laravel;'
echo -e "Check new settings\n"
mysql --host 127.0.0.1 -uroot -proot -e "SELECT @@global.secure_file_priv, @@global.local_infile"
- uses: shivammathur/setup-php@15c43e89cdef867065b0213be354c2841860869e
with:
php-version: "8.1"
- uses: actions/checkout@v2
- name: Setup Node.js
uses: actions/setup-node@v1
with:
node-version: "17.x"
- name: Copy .env
run: cp .env.ci .env
- name: Install Dependencies
run: composer install -q --no-ansi --no-interaction --no-scripts --no-progress --prefer-dist
- name: Generate key
run: php artisan key:generate
- name: Directory Permissions
run: chmod -R 777 storage bootstrap/cache
- name: Install NPM dependencies
run: npm ci
- name: Run Webpack for dev
run: npm run dev
- name: Run migrations and seeders
run: php artisan migrate:fresh --seed --force
- name: Execute tests (Unit and Feature tests) via PHPUnit
run: php artisan test --parallel
- name: Install Latest Chrome
run: |
wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb
sudo dpkg -i google-chrome-stable_current_amd64.deb
- name: Upgrade Chrome Driver
run: php artisan dusk:chrome-driver
- name: Start Chrome Driver
run: ./vendor/laravel/dusk/bin/chromedriver-linux > /dev/null 2>&1 &
- name: Run Laravel Server
run: php artisan serve > /dev/null 2>&1 &
- name: Run Dusk Tests
run: |
chmod -R 0755 vendor/laravel/dusk/bin/
php artisan dusk
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment