November 18, 2020

Agenda

  • ~30m Packamon presentation: package overview, latest changes and features (Daan, Jasper, Marvin, Maxim)
  • ~15m Real-world use case (Laure & Michela)
  • ~15m Discussion

Introduction

What is Continuous Integration (CI)?

Continuous Integration is a software development practice where members of a team integrate their work frequently

Integration:

  • push to a shared (git) repository
  • build and compile code
  • verify, check and test

Continuous/Frequently:

  • as often as possible: with each commit
  • automation is a necessity!

Why Continuous Integration (CI)

  • Shorter development cycles

    • Faster release of new features
    • Frequent testing reduces the complexity of errors
  • Automates and enforces good practices

  • Reduces manual work

    • Saves (waiting) time
    • Reduces errors
  • Early discovery of bugs

What is packamon?

The name is a portmanteau of package and monitoring: if there are problems with your package, packamon will help you catch ’em all.

packamon contains tools for R package quality control:

  • detect dependencies in local environment
  • generate Dockerfiles to record dependencies
  • generate Jenkinsfiles to automate quality control steps

What is Jenkins?

Jenkins is a self-contained, open source automation server which can be used to automate all sorts of tasks related to building, testing, and delivering or deploying software.

(source: https://www.jenkins.io/doc/)

The OA jenkins can be found at https://ci.openanalytics.eu

What is a Jenkinsfile?

A Jenkinsfile describes a sequence of steps to be run by Jenkins every time one or more commits are pushed to a repository.

These steps are grouped into stages.

Stages run on a particular agent.

Jenkinsfile anatomy

pipeline {
    agent {
        # agent description
    }
    stages {
        stage('build') {
            steps {
                # steps go here
            }
        }
        stage('check') {
            steps {
                # steps go here
            }
        }
    }
}

A Jenkinsfile for R (quiz)

What steps should be run for an R package?

A Jenkinsfile for R

What steps should be run for an R package?

  • (Rcpp)
  • roxygen
  • R CMD build
  • R CMD check
  • tests
  • … others?

What is the Dockerfile for?

For reproducibility, we use docker containers as ephemeral agents.

The image used to run the container needs to have everything to run the steps we defined:

  • (a specific version of) R installed
  • all R package dependencies (Imports, Suggest, Depends)
  • all system dependencies

Who is running docker build?

First stage in the Jenkinsfile: run docker build with the Dockerfile included in the repository.

All remaining stages are run using in a container created from the resulting image.

(source: https://xkcd.com/1629/)

Packamon Workflow

  1. run packamon::init() in a new project

  2. (optional) run packamon::writeJenkinsfile() or packamon::writeDockerfile() for more flexibility

  3. commit and push the generated files:

    • Dockerfile
    • Jenkinsfile
    • template.Dockerfile
  4. continue working on your package as normal

  5. if your dependencies change, run packamon::writeDockerfile() again

Demo

New Features

New: Coverage and JUnit export

The best way to see if your code is of good quality is to test it. Therefore we added a default step that runs all testthat tests and reports the code coverage using covr.

JUnit export: Keeps track of which tests succeeded/skipped/failed for each commit. This way you can easily detect at which point code got broken.

Coverage: Shows how much code of your package is captured within the tests. One should try to get the coverage as high as possible.


New: Dockerfile templates

Problem: after Dockerfile has been generated, difficult to add extra non-autodetected dependencies since next generate will overwrite them.

Solution: Templates!

Templates are regular Dockerfiles with an extra #include directive.

Lines of the form

#include packamon.<step>

will be replaced in the final Dockerfile by packamon::writeDockerfile() or packamon::init()

Other lines (docker command or comments) will be copied to the generated Dockerfile.

New: Dockerfile templates

The default template:

#include packamon.disclaimer

#include packamon.from

#include packamon.system-dependencies

#include packamon.r-repos

#include packamon.r-dependencies

#include packamon.local-r-dependencies

#include packamon.runtime-settings

New: Dockerfile templates

Using a different base image and extra sysdeps:

#include packamon.disclaimer

FROM openanalytics/my-super-cool-image:latest

#include packamon.system-dependencies
RUN apt update && apt install libfunny

#include packamon.r-repos

#include packamon.r-dependencies

#include packamon.local-r-dependencies

#include packamon.runtime-settings

The next acronym: CD

Continuous Delivery (CD): automated release of CI results

  • automatically push new software versions to a repository
  • simplifies release of new software versions
  • reduces manual work

Continuous Deployment (also CD):

  • automated deployment of the CI/CD output

Compact Disc

CD: can packamon help?

Yes!

  • Docker images can be used to run beyond CI context
  • R packages in RDepot (next packamon release)

Try it!

Install from RDepot:

install.packages("packamon", repos = c(
  rdepot = "https://rdepot-dev.openanalytics.eu/repo/public",
  getOption("repos")
))

Alternatively pull from https://scm.openanalytics.eu/git/packamon and install:

install.packages("~/git/packamon/packamon", repos = NULL)

You can take a look at the getting-started vignette if you get lost.

Questions