Node.js CI with Tekton Pipelines

Francesco Vitullo
ITNEXT
Published in
3 min readNov 25, 2019

--

Photo by Andrea Jaime on Unsplash

Today, Kubernetes is an amazing orchestrator while Tekton is one of the most recent solutions to native CI/CD in-cluster and, IMHO, this combination is spectacular.

In my career, I have been progressively embracing DevOps practices over the years, working with different tools and applying different approaches.

Then, suddenly I checked Tekton Pipelines and, boom, it addresses all the issues I was having in the past (I may name dozens of them), from duplication in the pipelines to tasks’ dependencies.

These few lines are not going to focus on what is Tekton but how it can be used to achieve Continuous Integration with Node.js codebases (well, it might be expanded to whatever stack you use).

Our case will be a simple Nuxt application which needs the following steps for our CI:

  • Dependencies Installation
  • Auditing for potential vulnerabilities
  • Linting
  • Unit Testing
  • Building

First of all, let’s set-up our Tekton Resource which points to the Git repository, in this case, https://github.com/cdbkr/nuxt.

Resources.yaml

In the file above we are declaring the resource (a git repo) which we are going to use in our Task/Pipeline.

Next, we use this resource in our Tekton Task:

Task.yaml

Let me explain the anatomy of the Tekton Task Spec.

  • Within Inputs we are specifying the wiring with the declared Git repo;
  • Within Steps we are specifying a set of sequential steps which need to be executed;

Now, let’s go through the steps which are tight to a usual Node.js application:

  • npm install installing dependencies;
  • npm audit checking vulnerabilities with installed dependencies;
  • npm run lint running lint checks;
  • npm run test running unit tests;
  • npm run build building our application’s bundle;

When one of these steps will be failing, the execution will be terminated (e.g. we don’t want to proceed if NPM discovered some vulnerabilities in the installed dependencies).

Afterward, we need only to execute the Task and, for this, we have a couple of options:

  • TaskRun: it’s allowing us to execute a single Task;
  • PipelineRun: it’s allowing us to execute a group of defined Tasks and specified in a Pipeline resource definition;

Since this example is pretty simple, we are going to use a TaskRun, which triggers a Pod with the containers/steps to execute.

Once executed and correctly validated, we can check the pods created with

+ kubectl get pods
NAME READY STATUS RESTARTS AGE
nodejs-taskrun-pod-67caed 6/6 Running 0 11s

And after completion:

+ kubectl get pods -w
NAME READY STATUS RESTARTS AGE
nodejs-taskrun-pod-67caed 6/6 Running 0 11s
nodejs-taskrun-pod-67caed 5/6 Running 0 52s
nodejs-taskrun-pod-67caed 4/6 Running 0 53s
nodejs-taskrun-pod-67caed 3/6 Running 0 55s
nodejs-taskrun-pod-67caed 2/6 Running 0 58s
nodejs-taskrun-pod-67caed 1/6 Running 0 64s
nodejs-taskrun-pod-67caed 0/6 Completed 0 81s
----+ kubectl get taskruns
NAME SUCCEEDED REASON STARTTIME COMPLETIONTIME
nodejs-taskrun True Succeeded 2m4s 43s

Nice! So, every step is executed as a separate container and TaskRun resource is marked with the execution’s status, Success in this case :).

This is a very easy example of how to run CI with a common Node.js project. By this way, you can imagine how many things could be achieved:

  • Re-using declared Tasks and Pipelines across Runs
  • Isolate dependencies between steps/containers (yes, it would be possible to use different images for each step). E.g. running E2E testing with a specific environment (sandboxed in a Docker Image), security testing with a given library relying on a different technology stack, executing scripts requiring a special Image, etc…

I hope this article gave you an idea of how to achieve this common task with Tekton Pipelines and for the next article, I will demonstrate how to achieve Continuous Deployment based on this work. In case you are interested and want to explore more, have a look at these two resources:

Cheers! :)

--

--

Senior Front End Engineer @IBM — thoughts are my own / I’m a passionate developer and kitesurfer