GitHub Actions - NextJS

Cover Image for GitHub Actions - NextJS

Hello Developers πŸ‘‹,
In this article we will explore how we can use the GitHub actions to implement Continuous Integration & Continuous Deployment.

To get started, here are basic things we will require to implement the CI/CD pipeline.

  1. NextJS Project 😬

  2. Remote Server

    1. Username

    2. Password

    3. Host

    4. Port

Create main.yml file in .github/workflows/ directory. The first thing is to define the event, when the action will be executed.

on:
    push:
        branches:
            - master

As defined above, action will be executed on push on the branch master. You may specify other events as well. Refer to Github actions documentation to learn about all the events available. Whenever push is made to the master branch github action will run.

Once the event is defined, we need to define jobs to execute during the action.

jobs:
    deploy:
        runs-on: ubuntu-latest
    steps:

Under the jobs: directive we can define our job. I have defined the job named as deploy. You need to specify the base operating system on which job will executed. runs-on directive specifies the OS, I have used ubuntu-latest . Furthermore we need to define the steps to execute in the job. Steps will be written under steps: directive.

We need to define each of the steps with name. We can use premade actions to perform under step. uses: directive specifies a third party action to execute.

- name: Checkout code
  uses: actions/checkout@v2

Above step defines that we need the checkout the repository code, Github has a premade actions to checkout the repository, just need to use that. uses: actions/checkout@v2 imports the checkout action. We do not need to perform any extra step.

- name: Install dependencies
  run: npm install

Above step will install the dependencies via the command npm install the run: directive is used to specify command to be executed.

Generally each project needs .env to process build operation, As .env is not available on the repository we need to create one.

- name: Create .env
  run: |
    touch .env
    echo ENV_VARIABLE_KEY=${{ secrets.ENV_VARIABLE_KEY }} >> .env

To execute multiple commands in run directive, we can use the pipe | operator.
touch .env will create the .env file. Now to put the variables in the .env file. We will use below command. echo ENV_VARIABLE_KEY=${{ secrets.ENV_VARIABLE_KEY }} >> .env We are using ${{ secrets.ENV_VARIABLE_KEY }} to retrieve the environment variable from the Github secrets which can be configured in the repository settings page.

Once we have the environment variables, we need to build the app.

 - name: Build Next.js app
   run: npm run build

Using the npm run build the project will be built. Once the project build is ready we need to deploy it to the server.

- name: Deploy Build
  uses: appleboy/[email protected]
  with:
      host: ${{ secrets.HOST }}
      username: ${{ secrets.USERNAME }}
      password: ${{ secrets.PASSWORD }}
      port: 22
      source: .next/*
      target: /var/www/actions-demo/

I am using the appleboy/[email protected] action to use the scp command to transfer the build files to the server. In this action we need to specify the few parameters such as host , usesrname , password, port, source, target.
source specifies which folder need to be copied, and the target specifies the destination folder on the remote server where the build will be copied.

Once the build is copied to the server, we need to restart the process, I am using PM2 to manage the process on server.

 - name: Restart PM2
   uses: appleboy/[email protected]
   with:
       host: ${{ secrets.HOST }}
       username: ${{ secrets.USERNAME }}
       password: ${{ secrets.PASSWORD }}
       port: 22
       script: pm2 restart demo

To execute the command on our server, I am usging appleboy/[email protected] action to connect to the ssh and execute pm2 restart demo command. By using above steps, we have made the simple CI/CD pipeline to deploy the NextJs app on server using the GitHub Actions.

Here is the final file which you can use as template and configure accordingly.

on:
  push:
    branches:
      - master
jobs:
  deploy:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout code
        uses: actions/checkout@v2

      - name: Install dependencies
        run: npm install

      - name: Create .env
        run: |
          touch .env
          echo ENV_VARIABLE_KEY=${{ secrets.ENV_VARIABLE_KEY }} >> .env.local

      - name: Build Next.js app
        run: npm run build

      - name: Deploy Build
        uses: appleboy/[email protected]
        with:
          host: ${{ secrets.HOST }}
          username: ${{ secrets.USERNAME }}
          password: ${{ secrets.PASSWORD }}
          port: 22
          source: .next/*
          target: /var/www/actions-demo/

      - name: Restart PM2
        uses: aπŸ˜ƒppleboy/[email protected]
        with:
          host: ${{ secrets.HOST }}
          username: ${{ secrets.USERNAME }}
          password: ${{ secrets.PASSWORD }}
          port: 22
          script: pm2 restart demo

Happy Coding πŸ˜ƒ!