CI/CD for developers

$ whoami

Inna Ivashchuk

Senior Software Engineer

JS dev, music fan, movie-dependent and Star Wars fan 🤓

May the Force be with you!

3+ years with GlobalLogic

about 5 years in Web Development

        GitHub page

Speaker at GL JS community

Agenda:

  • CI vs CD vs CD 
  • What are the benefits of each practice?
  • Popular CI/CD tools
  • Easy start with Travis CI
  • GitHub Actions in actions
  • Parameterized build on Jenkins

What is CI?

Continuous Integration

build

checks

developer

artifact

CI

VCS

(static files/ docker image)

  • set up the environment
  • install required dependencies

CI: preparation

Code checks:

  • run linters (code styles, typos, missing symbols) 

CI: checks

CI: tests

Write and run tests is always a good idea

  • build application

CI: build

CI: useful tools

   Danger runs during your CI process and gives teams the chance to automate common code review chores.

    This provides another logical step in your build, through this Danger can help lint your rote tasks in daily code review.

CI: useful tools

   Reviewdog provides a way to post review comments to code hosting service, such as GitHub, automatically by integrating with any linter tools with ease. It uses an output of lint tools and posts them as a comment if findings are in diff of patches to review.

What is CD?

Continuous Delivery/Deployment

artifact

CD

stage

production

(static files/ docker image)

CI vs CD vs CD

 Continuous Integration vs Continuous Delivery vs Continuous Deployment

CI/CD tools

GitLab CI pipeline

Nowadays CI/CD pipeline with containers and orchestration

What are the benefits of each practice?

  • write automated tests

  • CI server/service to monitor the main repository and run the tests automatically for every new commits pushed

  • merge changes as often as possible, at least once a day

CI: What you need (cost)

CI: What you gain

  • less bugs get shipped to production

  • building the release is easy

  • less context switching as developers are alerted as soon as they break the build

  • testing costs are reduced – CI server can run hundreds of tests in a matter of seconds

  • QA team spend less time testing and can focus on significant improvements to the quality culture

  • a strong foundation in CI and test suite needs to cover enough of a codebase

  • deployments need to be automated

  • use feature flags so that incomplete features do not affect customers in production (Launch Darkly service) 

Continuous Delivery: What you need (cost)

Continuous Delivery: What you gain

  • the complexity of deploying software has been taken away. Team doesn't have to spend days preparing for a release anymore

  • release more often

  • less pressure on decisions for small changes, hence encouraging iterating faster

Continuous Deployment: What you need

(cost)

  • testing culture will determine the quality of your releases
  • documentation process will need to keep up with the pace of deployments
  • feature flags become an inherent part of the process of releasing significant changes

Continuous Deployment: What you gain

  • develop faster as there's no need to pause development for releases
  • releases are less risky and easier to fix in case of problem (small batches of changes)
  • customers see a continuous stream of improvements, and quality increases every week, instead of every month, quarter or year

Easy start with Travis CI

To get started with Travis CI

  • Go to Travis-ci.com and Sign up with GitHub.

  • Accept the Authorization of Travis CI. You’ll be redirected to GitHub.

  • Click on your profile picture in the top right of your Travis Dashboard, click the green Activate button, and select the repositories you want to use with Travis CI.

  • Add a .travis.yml file to your repository to tell Travis CI what to do.

Let's configure .travis.yml

# CONFIGURATION

# specify programming language
language: node_js
node_js: 10.15.0
cache: npm

# installation phase
install:
  - npm i

# tasks phase
script:
  - npm run lint
  - npm run test
  - npm run test:cov

Configuration with deployment

# CONFIGURATION

# specify programming language
language: node_js
node_js: 10.15.0
cache: npm

branches:
  only:
  - master

# installation phase
install:
  - npm i

# tasks phase
script:
  - npm run lint
  - npm run test:cov
  - npm run build

# deployment phase
deploy:
  provider: surge
  skip_cleanup: true
  project: ./dist/
  domain: rmosaic.surge.sh

Deployment with Surge

# install surge globally
$ npm i -g surge


# init surge in your working directory
$ surge


# get your token and add it as a Travis envs
$ surge token

Specify env. variables one the page settings in Travis

Build stages using Travis CI 

# CONFIGURATION
language: node_js
node_js: 12.16.3
cache: npm
    
# run tasks
jobs:
  include:
    - stage: install
      script: npm install

    - stage: lint
      script: npm run lint

    - stage: test
      script: npm run test

    - stage: pushDockerImage
      if: (type = push AND branch = master)
      script: npm run dockerLogin
      	&& npm run buildDocker
        && npm run dockerTag 
        && npm run dockerPush

Build stages is a way to group jobs, and run jobs in each stage in parallel, but run one stage after another sequentially.

Conditional jobs, stages using Travis CI 

# stages
# require the branch name to be master
# (note for PRs this is the base branch name)
stages:
  - name: deploy   
    if: branch = master
    
# jobs
jobs:
  include:
    - # require the branch name to be master
      if: branch = master
      env: FOO=foo

You can filter out and reject builds, stages and jobs by specifying conditions in your build configuration (your .travis.yml file).

Branch protection on GitHub

Branch protection example

GitHub Action in action

Why care about Github Actions?

  • Build into GitHub

    • fully integrated and doesn't require an external server/service

  • Multi-container testing

    • multiple templates for all kinds of CI

    • ability to create your own templates and publish it as an Action on the Github Marketplace

  • Great free plan

    • completely free for every open-source repository

    • 2000 free build minutes per month for all your private repositories

Core concepts

  • Actions - the smallest portable building block of a workflow and can be combined as steps to create a job

  • Events - specific activities that trigger a workflow run

  • Runner - a machine with the Github Actions runner application installed

  • Job - made up of multiple steps and runs in an instance of the virtual environment

  • Steps - a set of tasks that can be executed by a job. Steps can run commands or actions

  • Workflow - an automated process that is made up of one or multiple jobs and can be triggered by an event (defined using a YAML file)

Using workflow and action templates

Adding a workflow template:

1. On the main page of your repository navigate to Actions.

 

Adding a workflow template:

2. Pick a template you would like to use and click Set up this workflow

 

Adding a workflow template:

3. We can make changes in the editor and commit the action to your repository using the Start commit button

 

Adding an action template to your workflow:

   Action templates can be found on the Github Marketplace or directly in the workflow editor on the far right side.

   The template can be added by copying the code of the actions and pasting it into your .yml file. The unique action name and version number need to be defined with the uses keyword.

 

Workflow is ready - let's run it

Tips and tricks

There are many possible ways, how workflow can be configured. It helps us to make the build faster and more flexible.

Examples:

  • based on branch name, run only part of tests
  • trigger different checks, tests on a PR (MR) and merge into master
  • do deployment only for the release branch (when all checks are ok)

Parameterized build on Jenkins

Defining Build Parameters

A build parameter allows us to pass data into our Jenkins jobs. Using build parameters, we can pass any data we want: git branch name, secret credentials, and so on. Then, click Add Parameter button.
Any Jenkins job or pipeline can be parameterized. All we have to do is check the box on the General settings tab that says This project is parameterized:

 

Then, click Add Parameter button.

Defining Build Parameters: Add Parameter

Specify several pieces of information:

  • Type: the data type for the parameter (string, bool, etc)
  • Name: the name by which the parameter will be identified
  • Default value: an optional value that will be used when a user does not specify one
  • Description: optional text that describes how the parameter is used

A single Jenkins job or pipeline can have multiple params (should be unique).

Types of Parameters

The list of the most common parameters (plugins may add new parameter types):

  • String: any combination of characters and numbers
  • Choice: a pre-defined set of strings from which a user can pick a value
  • Credentials: a pre-defined Jenkins credential
  • File: the full path to a file on the filesystem
  • Multi-line String: same as String, but allows newline characters
  • Password: similar to Credentials type, but allows us to pass a plain text parameter specific to the job or pipeline
  • Run: an absolute URL to a single run of another job

Using Build Parameters: Jobs

With tradinional Jenkins job, we define one or more build steps. The most common build step is executing a shell script.

If we have a build parameter packageName, inside a shell script, we can access build params (as env. variables) using the shell syntax:

 


${packageName}

Using Build Parameters: Pipelines

Inside a Jenkins Pipeline, accessing a build parameter can be done in multiple ways:

1) from params variable

2) parameters are added to the environment of the pipeline

pipeline {
    agent any
    stages {
        stage('Build') {
            when {
                expression { params.packageName == "forms" }
            }
        }
    }
}
pipeline {
    agent any
    stages {
        stage('Build') {
            steps {
                echo "${packageName}"
            }
        }
    }
}

1

2

Setting Parameter Values

 

Starting a job with Jenkins UI is the easiest way to pass build parameters. All we do is log in, navigate to our job, and click the Build with Parameters link (1).

This will take us to a screen (2) that asks for inputs for each parameter.

Based on the type of parameter, the way we input its value will be different.

1

2

Benefits:

Using Build with Parameters can help us to make our build job more flexible, as based on passed params we will get different results.

Examples:

  • if a build is successful - deploy changed to the testing environments
  • provide a list of required tests, that should be triggered for the current changes
  • provide a list of components, that should be published

 

Questions time

GitHub repos:

CI/CD

By Inna Ivashchuk

CI/CD

Long story short

  • 985