Setting Up A CI/CD Pipeline With Circle CI
Tags: javascript, devops, productivity, programming
Published: 2021-07-21 15:44:38

DevOps or CI/CD as it is commonly called is practice that involves automating everything and anything we can from writing our code to deploying it. Most of the time you are just building on existing knowledge just leveraging tools provided to you to automate certain repetitive parts of the  software development cycle. Things like running tests, linting your code, or deploying to your production environment; they are often repetitive and impacts your productivity as developer. But if we are super hero developers we would use CI/CD tools to automatically do all this for us when we push our code to our repository. By the end of this article you will be using CI/CD to automate your workflow and become a super hero developer, let's decipher what this term really is. I will be using circle-CI for setting up this workflow. Let's dive in.

To read more articles like this please visit [Netcreed](https://netcreed-blog.vercel.app)

## Continuous Integration - CI

Continuous Integration is concerned with all practices geared towards automating the process of adding new code to the code base, we might have a project we are working with alone or with some other developer, we can set up a CI pipeline that will test any new code that is being added to the code base, this will keep our focus on writing code because immediately we have a pull request or a push to the repo, the tests will automatically run and we get a console where we can see the logs coming from the process. 

* Head to [circle ci](https://circleci.com) to create an account, when you are done create an empty git repository on github.
* Go back to your circle-ci dashboard click on `projects` and create a new project.
* Select from the repo dropdown the repository which you just created circle-ci will automatically give you a setup from which you can start a workflow.

If you pay attention to the logs on the project in your dashboard, you will see information about the process and it will tell you why your workflow failed, if it did. Normally it will fail for the first time because we have not added any code whatsoever or dependencies, let's go ahead and do that.

Assuming a dummy project and we have some test that we want to automate with our workflow, the project structure looks like this;

```javascript
Root-------------/spec/
        	|---/node_modules/
			|--.gitignore
            |--package.json
			|--package.lock.json
```

Our tests are contained inside the spec folder and i will not go into detail or show any code example about the tests because it is outside the scope of this article. We need to add some circle-ci configuration files to define a workflow that will help us automate our test. First create a directory in the root folder and it should be named `.circleci` and create a file `config.yml` inside this folder. This should give you a big hint, the configuration file for setting up a circle-ci workflow is written in yml, if you have used github acitons then the process becomes a lot more easier.

```javascript
Root-------------/spec/
        	|---/node_modules/
			|--.gitignore
            |--package.json
			|--package.lock.json
			|--/.circleci/config.yml
```

Let's look at the actual structure of the `config.yml` file

```yaml
# You must choose a version of circle ci you want to use, all config files requires this
version: 2.1

# You can use already packaged circle ci workflows, they are called orbs
orbs: 
	node:  circleci/node@4.1 # We use the orbs for creating a node js workflow
	
jobs: 	# This is where we define our actual process, each process is classified into a job. we can run multiple jobs
# Each job should have a name, you can call it whatever you like
	test-code:
	# Executor, we must define one, you can use circle-ci's docker executors or your own custom docker executors
	docker:
      - image: cimg/node:15.1
     # next we define the steps involved in creating the workflow
     steps: 
     	# Checkout the code as the first step. move our code to the host machine
      - checkout
      	# Install our dependencies with npm, we can use circleci to cache dependencies them for future use
      - node/install-packages
      	# We specify commands to run, each command has a name and the actual terminal command like below
      - run:
          name: Run tests
          command: npm test

workflows:
  # Below is the definition of your workflow.
  # Inside the workflow, you provide the jobs you want to run, e.g this workflow runs the test-my-code job above.
  # CircleCI will run this workflow on every commit.
  sample: 
    jobs:
      - test-code
```

if you save this file, commit and push it to the repo associated with your circle-ci project, the workflow will immediately trigger and you should see the result of the workflow and the logs from the process in your dashboard, it will enable you to see what went wrong so you would know how to tackle it, if the test passed you can then merge it to the code base, that is where continuous deployment comes in. 

## Continuous Deployment

If continuous integration is about adding new code to existing code base, then continuous deployment is concerned with automating the deployment of the newly added coded. You might run your deploy command directly from the terminal after working on your project, but it makes no sense to automate your tests, then manually deploy your code? But we are superhero developers so we will set up a circle-ci CD pipeline to help us automate our code deployment, we will be deploying to firebase hosting, so i will assume that you are already familiar with firebase. Assuming that our working directory above now contains a firebase project that we want to deploy. Obviously we need to obtain our login credentials we can use in the CD.

*  From the command line run `firebase login:ci`. This will return us a login credential in the command line, copy the credentials.

*  Head over to your circle-ci dashboard, navigate to the current project that we setup a CI for, enter project settings.
*  From the project settings select environment variables and add new environment variable. 
*  It's name should be `FIREBASE_TOKEN` paste in the login credentials that firebase gave to us as it's value.

Head back to your local projects, we will make some changes to our `config.yml`, we will be adding two commands, one to build the project and another to deploy the project.

```yaml
# PAY ATTENTION TO NEW JOBS ADDED
version: 2.1

orbs: 
	node:  circleci/node@4.1 
	
jobs: 	
	test-and-deploy-code:
	docker:
      - image: cimg/node:15.1
     # next we define the steps involved in creating the workflow
     steps: 
     	 
      - checkout
      
      - node/install-packages
      	
      - run:
          name: Run tests
          command: npm test
          # This command builds the project, e.g a react or angular project
      - run:
      	  name: Build Project	
      	  command: npm run build
      	  # This command deploys to the project to firebase using the FIREBASE_TOKEN we set earlier
      - run:
      	  name: Deploy Project
          command: ./node_modules/.bin/firebase deploy --token "$FIREBASE_TOKEN"

workflows:
  sample: 
    jobs:
      - test-and-deploy-code
```

Now if you save commit and push your local project to github, circle-ci will immediately run your workflow to test, build and deploy the project. But it doesn't make any sense to deploy the project every time there is a commit. So you might want to create another branch  makes continue working and push the code to the repository with this new branch, thus anytime there is a pull request to the master branch we can tell cirlce-ci to run our workflow. 

* Enter project settings on circle-ci dashboard.
* click on advanced settings.
* Turn on `only build pull requests`.

That's it for this article, i hope you find this useful, maybe we might see how to set up pipelines to test and deploy to other platforms in the future.

To read more articles like this please visit [Netcreed](https://netcreed-blog.vercel.app)