Setting up CI/CD in Github Actions for Laravel and Vue.js

Setting up CI/CD in Github Actions for Laravel and Vue.js

CI/CD (Continuous Integration/Continuous Deployment) is a software development methodology that aims to simplify and speed up the process of delivering changes and new features to the user. 

CI, or Continuous Integration, is the process of automatically merging code from different developers into one common branch. This process usually includes automated tests, which helps detect and fix bugs faster.

CD, or continuous delivery, is the next step after CI. It is the process of automatically deploying code to production. This means that once your code is ready and all tests are passed, it automatically moves to the production stage.

Advantages of CI/CD

1- Faster time to market  

   With CI/CD, you can automate various stages of development, thereby speeding up the software delivery process.

2. higher product quality  

   CI/CD involves frequent code testing, which helps in detecting and fixing bugs early in the development process.

3. Increased team productivity  

   By automating routine processes, developers can focus on writing code rather than integrating and delivering it.

4. Quick rollback  

   If something goes wrong, you can quickly roll back to a previous version of code, reducing risk to your users.

5. Accountability  

   With CI/CD, every code change can be traced back to a specific commit and developer, improving transparency and accountability.

CI/CD is a powerful tool for development teams that can greatly improve the development process and the delivery of high quality software.

Customize CI/CD with GitHub Actions

GitHub Actions is a GitHub functionality that allows you to automate, customize, and execute software without intermediaries. Today, we'll look at how to customize continuous integration and delivery (CI/CD) using GitHub Actions.

Creating a workflow file

Create a new file in the .github/workflows directory in your repository. Name it dev.yml, for example. This file will contain all the settings for your CI/CD workflow. I usually name the file by the name of the branch it is attached to.

An example of a file for Laravel + Vue.js that I usually use in my projects

 

name: Continuous Integration and Deployment

 

on:

  push:

    branches: [ dev ]

  pull_request:

    branches: [ dev ]

 

jobs:

  build:

    runs-on: ubuntu-latest

 

    steps:

      - name: Checkout code

        uses: actions/checkout@v2

 

      - name: Setup PHP

        uses: shivammathur/setup-php@v2

        with:

          php-version: '8.1'

 

      - name: Install Dependencies

        run: composer install --prefer-dist --no-progress --no-suggest

 

      - name: Setup Laravel

        run: |

          cp .env.example .env

          php artisan config:clear

          php artisan cache:clear

          php artisan key:generate

 

      - name: Composer Lint

        run: ./vendor/bin/phplint --no-cache

 

      - name: Composer Audit

        run: composer audit

 

      - name: Composer Validate

        run: composer validate --no-check-all --strict

 

      - name: Setup Node.js

        uses: actions/setup-node@v2

        with:

          node-version: '16'

 

      - name: Install Node.js Dependencies

        run: npm install

 

      - name: Build Vue.js

        run: npm run build

 

      - name: Run PHPUnit Tests

        run: ./vendor/bin/phpunit --colors=always

 

      - name: Lint PHP Code

        run: ./vendor/bin/pint --test

 

      - name: PHPStan

        run: ./vendor/bin/phpstan analyse

 

  deploy:

    needs: [build]

    runs-on: ubuntu-latest

    steps:

      - name: Checkout code

        uses: actions/checkout@v2

 

      - name: Setup PHP

        uses: shivammathur/setup-php@v2

        with:

          php-version: '8.1'

 

      - name: Install Dependencies

        run: composer install -q --no-ansi --no-interaction --no-scripts --no-progress --prefer-dist

 

      - name: Setup Environment File

        run: |

          cp .env.example .env

          sed -i 's/DB_USERNAME=root/DB_USERNAME=${{ secrets.DB_USERNAME }}/g' .env

          sed -i 's/DB_PASSWORD=/DB_PASSWORD=${{ secrets.DB_PASSWORD }}/g' .env

          sed -i 's|VTIGER_URL=http://localhost:8080|VTIGER_URL=${{ secrets.VTIGER_URL }}|g' .env

          sed -i 's/VTIGER_USERNAME=admin/VTIGER_USERNAME=${{ secrets.VTIGER_USERNAME }}/g' .env

          sed -i 's/VTIGER_ACCESS_KEY=1234567890/VTIGER_ACCESS_KEY=${{ secrets.VTIGER_ACCESS_KEY }}/g' .env

 

      - name: Setup Laravel

        run: |

          php artisan config:clear

          php artisan cache:clear

          php artisan key:generate

          php artisan storage:link

 

      - name: Permission setup

        run: |

          chmod -R 777 storage bootstrap/cache

 

      - name: Setup Node.js

        uses: actions/setup-node@v2

        with:

          node-version: '16'

 

      - name: Install Node.js Dependencies

        run: npm install

 

      - name: Build Vue.js

        run: npm run build

 

      - name: Clean Up

        run: rm -rf node_modules

 

      - name: copy file via ssh key

        uses: appleboy/scp-action@v0.1.4

        with:

          host: ${{ secrets.SERVER_IP }}

          username: ${{ secrets.SERVER_USERNAME }}

          password: ${{ secrets.PASSWORD }}

          port: 22

          key: ${{ secrets.DEPLOY_KEY }}

          source: "./"

          target: "~/path_to_project"

 

      - name: Run laravel commands

        uses: appleboy/ssh-action@master

        with:

          host: ${{ secrets.SERVER_IP }}

          username: ${{ secrets.SERVER_USERNAME }}

          key: ${{ secrets.DEPLOY_KEY }}

          port: 22

          script:

            chown -R www-root ~/path_to_project && cd ~/path_to_project && php artisan cache:clear && php artisan config:clear && php artisan view:clear && php artisan migrate

 

Example you can find also in github: https://github.com/semelyanov86/realty-objects/blob/dev/.github/workflows/laravel.yml

The dev.yml file specifies the events that should trigger the CI/CD process. In our example, it is configured so that it is triggered whenever a push or pull request is made to the dev branch:

 

name: Continuous Integration and Deployment

 

on:

  push:

    branches: [ dev ]

  pull_request:

    branches: [ dev ]

 

Jobs are individual steps in your CI/CD process. They can be run in parallel or sequentially, depending on your requirements. Below is an example of a task for building a project:

 

jobs:

  build:

    runs-on: ubuntu-latest

 

    steps:

    - name: Checkout code

      uses: actions/checkout@v2

 

    - name: Setup PHP

      uses: shivammathur/setup-php@v2

      with:

        php-version: '8.2'

 

    # ...

 

Here we basically start building the project - get the sources from github, install php.

Then we need to install dependencies and run various checks:

 

    - name: Install Dependencies

      run: composer install --prefer-dist --no-progress --no-suggest

 

    - name: Composer Lint

      run: ./vendor/bin/phplint --no-cache

 

    - name: Composer Audit

      run: composer audit

 

    - name: Composer Validate

      run: composer validate --no-check-all --strict

 

    - name: Run PHPUnit Tests

      run: ./vendor/bin/phpunit --colors=always

 

    # ...

 

Before submitting changes to the server, we need to verify that our code meets all the required standards, namely:

  1. automatic code refactoring and updating (Rector)
  2. codestyle - Pint
  3. static analysis - Larastan
  4. vulnerability check (composer audit command)
  5. validity of composer.json (the composer validate command)
  6. Absence of unused packages. If a package is not used, no need to keep it on the system (composer-unused).
  7. control of dependency cohesion/chaining and direction (Deptrac).
  8. Linter (phplint).
  9. And of course tests (PHPUnit).

 

Deploy to the server

When all the tests are passed, we can move on to the server deploy:

 

  deploy:

    needs: [build]

    runs-on: ubuntu-latest

    steps:

    - name: Checkout code

      uses: actions/checkout@v2

 

    - name: Setup PHP

      uses: shivammathur/setup-php@v2

      with:

        php-version: '8.2'

 

    - name: Install Dependencies

      run: composer install -q --no-ansi --no-interaction --no-scripts --no-progress --prefer-dist

 

    # ...

 

      - name: copy file via ssh key

        uses: appleboy/scp-action@v0.1.4

        with:

          host: ${{ secrets.SERVER_IP }}

          username: ${{ secrets.SERVER_USERNAME }}

          password: ${{ secrets.PASSWORD }}

          port: 22

          key: ${{ secrets.DEPLOY_KEY }}

          source: "./"

          target: "~/path_to_project"

 

      - name: Run laravel commands

        uses: appleboy/ssh-action@master

        with:

          host: ${{ secrets.SERVER_IP }}

          username: ${{ secrets.SERVER_USERNAME }}

          key: ${{ secrets.DEPLOY_KEY }}

          port: 22

          script:

            chown -R www-root ~/path_to_project && cd ~/path_to_project && php artisan cache:clear && php artisan config:clear && php artisan view:clear && php artisan migrate

 

There are a number of strategies for deployment. You can build on the server itself, accept changes from the git, install dependencies, build the frontend. You can do the opposite, build everything on gitHub, send the files via ftp. In our example, we go with the second option, since we may not always have node, git or composer installed on the server. After sending the changes, we still need to connect to the server via ssh, clear the cache, and run the migrations.

To securely store sensitive data such as SSH keys and database access parameters, use GitHub secrets. You can add them in the "Secrets" section of your repository settings. For example, if you look at this command - ssh ${{ secrets.SERVER_USERNAME }}@${{ secrets.SERVER_IP }}} , then here we connect to the server using the variables from the github - SERVER_USERNAME and SERVER_IP.

To authorize on the server, we need to add a private key as secrets on the github, and on the server we need to add a public key to the authorized_keys file.

You will probably need to fill the .env file with the necessary keys. In our example, we copy the .env.example file to .env and then replace the strings with the github secrets:

      - name: Setup Environment File

        run: |

          cp .env.example .env

          sed -i 's/DB_USERNAME=root/DB_USERNAME=${{ secrets.DB_USERNAME }}/g' .env

          sed -i 's/DB_PASSWORD=/DB_PASSWORD=${{ secrets.DB_PASSWORD }}/g' .env

          sed -i 's|VTIGER_URL=http://localhost:8080|VTIGER_URL=${{ secrets.VTIGER_URL }}|g' .env

          sed -i 's/VTIGER_USERNAME=admin/VTIGER_USERNAME=${{ secrets.VTIGER_USERNAME }}/g' .env

          sed -i 's/VTIGER_ACCESS_KEY=1234567890/VTIGER_ACCESS_KEY=${{ secrets.VTIGER_ACCESS_KEY }}/g' .env

          

This is a basic CI/CD setup using GitHub Actions. Remember that every project is unique, and you can always customize this example to meet your specific needs. Happy coding!

Popular Posts

My most popular posts

Maximum productivity on remote job
Business

Maximum productivity on remote job

I started my own business and intentionally did my best to work from anywhere in the world. Sometimes I sit with my office with a large 27-inch monitor in my apartment in Cheboksary. Sometimes I’m in the office or in some cafe in another city.

Hello! I am Sergey Emelyanov and I am hardworker
Business PHP

Hello! I am Sergey Emelyanov and I am hardworker

I am a programmer. I am an entrepreneur in my heart. I started making money from the age of 11, in the harsh 90s, handing over glassware to a local store and exchanging it for sweets. I earned so much that was enough for various snacks.

Hire Professional CRM developer for $25 per hour

I will make time for your project. Knowledge of Vtiger CRM, SuiteCRM, Laravel, and Vue.js. I offer cooperation options that will help you take advantage of external experience, optimize costs and reduce risks. Full transparency of all stages of work and accounting for time costs. Pay only development working hours after accepting the task. Accept PayPal and Payoneer payment systems. How to hire professional developer? Just fill in the form

Telegram
@sergeyem
Telephone
+4915211100235