DEV Community

Clément POISSON for ScaleDynamics

Posted on • Updated on • Originally published at docs.scaledynamics.com

CI/CD with a simple NestJS server

In this tutorial, we will see how we can make a CI/CD (Continuous Integration and Continuous Delivery) script with GitHub Actions and a simple NestJS server.

Introduction

NestJS is a Framework for building Node.js server side application. It is built with TypeScript and use Express or Fastify HTTP server framework under the hood. It's architecture is heavily inspired by Angular. It integrates a lot of features and is very easy to use.

GitHub Actions is GitHub take on CI/CD. It allows you to automate your build process and deploy your code directly from your GitHub repository.

Goals

Our goal is to create a simple NestJS server with the Nest CLI, deploy it using ScaleDynamics cloud platform and then automate it with GitHub Actions. We'll learn how you can use GitHub Actions to deploy with the ScaleDynamics platform.

Prerequisites

To follow along, you will need:

  • A GitHub account and a repository ready to be used with GitHub Actions.
  • Knowledge of Git and have it installed on your machine.
  • Node.js and yarn / npm installed. You can go here to download the latest version of Node.js and npm.

Creating the project

To create the project, we can use the Nest CLI or clone a project starter from GitHub:

npm i -g @nestjs/cli
nest new my-server
Enter fullscreen mode Exit fullscreen mode

or

git clone https://github.com/nestjs/typescript-starter.git my-server
Enter fullscreen mode Exit fullscreen mode

Move into the project folder:

cd my-server
Enter fullscreen mode Exit fullscreen mode

You can test if the project is working locally by running:

npm run start
Enter fullscreen mode Exit fullscreen mode

You can check you receive Hello World! by running:

curl localhost:3000
Enter fullscreen mode Exit fullscreen mode

Now that we saw the project working, we just need to make a change in the scripts of the package.json file. When the server is deployed with ScaleDynamics, the server is started with the startcommand. We will change it so it launch the server in production mode by default and not in dev mode.

// package.json
"scripts": {
    "prebuild": "rimraf dist",
    "build": "nest build",
    "format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"",
    "dev": "nest start",
    "dev:watch": "nest start --watch",
    "dev:debug": "nest start --debug --watch",
    "start": "node dist/main",
    "lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix",
    "test": "jest",
    "test:watch": "jest --watch",
    "test:cov": "jest --coverage",
    "test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand",
    "test:e2e": "jest --config ./test/jest-e2e.json"
  },
Enter fullscreen mode Exit fullscreen mode

Everything is ready to be deployed !

Account creation and ressource selection

To deploy this server on ScaleDynamics's cloud, you need an account and create an environment with a ressource for it. The cloud resource provides virtual CPU and storage capacities used to execute the app. In this tutorial we will use a free shared resource available on ScaleDynamics’s cloud. These are the best one for testing. In this tutorial we will see later how you can upgrade to a dedicated production resource on the public cloud provider and region of your choice.

If you don't have an account, feel free to create one here (it's free and no credit card are required). Once your account is created, sign in.

Let's create a project and an environment on the ScaleDynamics's console. Select your organization, create a new project, then create a new environmnent. Now we need to choose what kind of service we need for our deployment. There are four types:

  • managed HTTP docker
  • managed Node.js server
  • managed Node.js module
  • static assets hosting

For our NestJS server, we need a (surprise) server. Let's pick the managed Node.js server. You can learn more on the other types in the ScaleDynamics documentation.

Environment creation

Deployment

The environment is ready to run our application, let's deploy on it.

Configuration file

First, let's add a configuration to tell the SDK what type of application we want to deploy. At the root of the project, create a warp.config.js file:

// warp.config.js
module.exports = {
  server: "nest",
};
Enter fullscreen mode Exit fullscreen mode

Build

Build the project to let Nest compile TypeScript and optimize and bundle everything for us:

yarn build
Enter fullscreen mode Exit fullscreen mode

Login

Log into your account and select your organization via the prompt:

npx warp login
Enter fullscreen mode Exit fullscreen mode

Deploy

Finally, we can run the deployment command:

npx warp deploy
Enter fullscreen mode Exit fullscreen mode

This command will dump something like this:

Deploy dump

You can see that a server was detected from your configuration file. Now follow the prompt, select the project you created, then the environment. The prompt will also ask you for a hostname, you can leave it blank for a random name or use the one you want. Finally, you can select a host.

The deployment will be done in a few minutes. At the end, the command will dump something like this:

Deploy end dump

You can now open test it by visiting the URL dumped or doing a curl request.

Automation with GitHub Actions

To simplify and automate this process, let's use GitHub Actions.

Create a GitHub repository

Before we can automate the process, you need to create a GitHub repository and upload the project there.
You can learn more about it on the GitHub documentation.

Define our workflow

Now let's think about what workflow we want to automate. Our final goal is to deploy our server, but before deploying, we need to check the quality of the code, test it, build the project and finally deploy it. For this example there will be four steps:

  • Lint our code with ESLint
  • Test our code with Jest
  • Build our project
  • Deploy it

The NestJS startup project we use got everything to do so.

Create the workflow

Let's create a new workflow by creating a new folder at the root of the project called .github and an other folder inside called workflows. Inside workflows, create a main.yml file and copy this code:

name: Deploy

# Controls when the workflow will run
on:
  # 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:
  deploy:
    name: Deploy
    runs-on: ubuntu-latest
    env:
      # replace with your project/env name
      ORG_PROJECT: nest-test
      DEPLOY_ENV: dev
    # 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@v2

      - name: Install dependencies
        run: yarn

      - name: Lint the codebase
        run: yarn lint

      - name: Test our code
        run: yarn test

      - name: Build
        run: yarn build

      - name: Login
        run: npx warp login --api-key=${{ secrets.SD_API_KEY }}

      - name: Deploy
        run: npx warp deploy --project ${ORG_PROJECT} --env ${DEPLOY_ENV}
Enter fullscreen mode Exit fullscreen mode

API key for login

Your workflow is ready, but for the login step, we need an API key to authenticate with ScaleDynamics. This API key can be created on the ScaleDynamics console:

API key creation

Once your API key is created, we can create a secret in your repository so we can use it in our workflow:

GitHub secret creation

Test it

Now you can try it by going into the Actions tab on your repository and trigger the workflow:

Trigger workflow

The workflow will run and you will be able to see the job deploy. Click on it and you can see all the steps that are executed. At the end if all go well you should have something like:

Workflow results

If there is an error along the way you will be able to easily spot it and fix it.

Go further

This was a simple example of setting up CI/CD to deploy an server with ScaleDynamics, but you can do way more things with it. For exemple, you could lint the code on every commit to ensure styling coherence and ensure no mistake are present in your codebase, or you could deploy you code in preproduction at every commit on a branch preprod. The sky is the limit.

If you want to know more, I encourage you to read this JetBrains guide. It's related to their TeamCity CI/CD platform but they perfectly explain the principles and what you can do with CI/CD in general.

Enjoy !

Latest comments (1)

Collapse
 
saralufi profile image
Sara Lufi

npx warp deploy got succeeded but
Image description
I am getting this error. What to do?