Last active
January 27, 2023 10:10
-
-
Save syntaxlexx/ea34d9370119bb8d7496545ad3083756 to your computer and use it in GitHub Desktop.
GitHub Actions - Test & Deploy Laravel Inertia (w/ Vite) to VPS CLoud Server, Notify via Slack
This file contains 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
# script to deploy the laravel upstream to the dev server | |
# required secrets: HOST, USERNAME, PASSWORD, APP_PATH, APPNAME, SLACK_WEBHOOK, SSH_PRIVATE_KEY | |
# If you are using OpenSSH | |
# If you are currently using OpenSSH and are getting the following error: | |
# ssh: handshake failed: ssh: unable to authenticate, attempted methods [none publickey] | |
# Make sure that your key algorithm of choice is supported. On Ubuntu 20.04 or later you must explicitly allow the use of the ssh-rsa algorithm. Add the following line to your OpenSSH daemon file (which is either /etc/ssh/sshd_config or a drop-in file under /etc/ssh/sshd_config.d/): | |
# CASignatureAlgorithms +ssh-rsa | |
name: Deploy Laravel App to Production | |
# Controls when the workflow will run | |
on: | |
# Triggers the workflow on push or pull request events but only for the "main" branch | |
push: | |
branches: [ "main" ] | |
pull_request: | |
branches: [ "main" ] | |
# Allows you to run this workflow manually from the Actions tab | |
workflow_dispatch: | |
# A workflow run is made up of one or more jobs that can run sequentially or in parallel | |
jobs: | |
# This workflow contains a single job called "build" | |
build: | |
# The type of runner that the job will run on | |
runs-on: ubuntu-latest | |
# setup services | |
services: | |
redis: | |
image: redis | |
# Set health checks to wait until redis has started | |
options: >- | |
--health-cmd "redis-cli ping" | |
--health-interval 10s | |
--health-timeout 5s | |
--health-retries 5 | |
ports: | |
# Maps port 6379 on service container to the host | |
- 6379:6379 | |
strategy: | |
fail-fast: false | |
matrix: | |
php-versions: ['8.1'] | |
operating-system: [ubuntu-latest] | |
dependency-stability: [ prefer-stable ] | |
# Steps represent a sequence of tasks that will be executed as part of the job | |
steps: | |
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it | |
- uses: actions/checkout@v3 | |
- uses: actions/setup-node@v3 | |
with: | |
node-version: 18 | |
check-latest: true | |
- name: Setup PHP, with composer and extensions | |
uses: shivammathur/setup-php@v2 #https://github.com/shivammathur/setup-php | |
with: | |
php-version: ${{ matrix.php-versions }} | |
extensions: mbstring, dom, fileinfo, mysql, libxml, xml, xmlwriter, dom, tokenizer, filter, json, phar, pcre, openssl, pdo, intl, curl | |
- name: Get composer cache directory | |
id: composer-cache | |
run: echo "::set-output name=dir::$(composer config cache-files-dir)" | |
- name: Cache composer dependencies | |
uses: actions/cache@v1 | |
with: | |
path: ${{ steps.composer-cache.outputs.dir }} | |
# Use composer.json for key, if composer.lock is not committed. | |
# key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }} | |
key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }} | |
restore-keys: ${{ runner.os }}-composer- | |
# Run tests on Laravel | |
- name: Copy .env | |
run: php -r "file_exists('.env') || copy('.env.testing', '.env');" | |
- name: Install Dependencies | |
run: composer install -q --no-ansi --no-interaction --no-scripts --no-progress --prefer-dist | |
- name: Create Database | |
run: | | |
mkdir -p database | |
touch database/database.sqlite | |
- name: Run Migrations | |
env: | |
DB_CONNECTION: sqlite | |
DB_DATABASE: database/database.sqlite | |
run: php artisan migrate --force | |
- name: Generate key | |
run: php artisan key:generate --force | |
- name: Directory Permissions | |
run: chmod -R 777 storage bootstrap/cache | |
# Run npm tests | |
- name: Build and Test Node Packages | |
run: | | |
npm ci | |
npm run build | |
# Run php tests | |
- name: Execute tests (Unit and Feature tests) via Pest | |
env: | |
DB_CONNECTION: sqlite | |
DB_DATABASE: database/database.sqlite | |
run: ./vendor/bin/pest | |
# Deploy to prod server | |
- name: Deploying System | |
uses: appleboy/ssh-action@master | |
with: | |
host: ${{ secrets.HOST }} | |
username: ${{ secrets.USERNAME }} | |
# password: ${{ secrets.PASSWORD }} | |
key: ${{ secrets.SSH_PRIVATE_KEY }} | |
script: | | |
cd ${{ secrets.APP_PATH }} | |
git reset --hard | |
git clean -fd | |
php artisan down | |
git pull --ff | |
composer install --no-interaction --prefer-dist --optimize-autoloader -q | |
php artisan migrate --force | |
export NVM_DIR=~/.nvm | |
source ~/.nvm/nvm.sh | |
npm ci | |
npm run build | |
php artisan up | |
- name: Slack success notification | |
if: success() | |
uses: rtCamp/action-slack-notify@master | |
env: | |
SLACK_CHANNEL: acelords-and-apps | |
SLACK_COLOR: good | |
SLACK_ICON: https://github.githubassets.com/images/modules/logos_page/GitHub-Mark.png | |
SLACK_MESSAGE: '${{ secrets.APPNAME }}: Deployment achieved with success' | |
SLACK_TITLE: CI | |
SLACK_USERNAME: GitHub | |
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }} | |
- name: Slack error notification | |
if: failure() | |
uses: rtCamp/action-slack-notify@master | |
env: | |
SLACK_CHANNEL: acelords-and-apps | |
SLACK_COLOR: danger | |
SLACK_ICON: https://github.githubassets.com/images/modules/logos_page/GitHub-Mark.png | |
SLACK_MESSAGE: '${{ secrets.APPNAME }}: The deployment has failed' | |
SLACK_TITLE: CI | |
SLACK_USERNAME: GitHub | |
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This script assumes you have installed
npm
vianvm
. The lines below ensure the script findsnpm
Adjust accordingly.
.ENV File
As you can tell by this line
The
.env
file is set to such values as below to ensure the tests run as close to a production environment as possible.Adjust accordingly. (Here, I copy the
.env.testing
to.env
. Popular convention is to have an extraenv.ci
, but my local testing environment is almost - if not an exact copy - of theCI/CD
environment. So, update yours accordingly)