- ~30m Packamon presentation: package overview, latest changes and features (Daan, Jasper, Marvin, Maxim)
- ~15m Real-world use case (Laure & Michela)
- ~15m Discussion
November 18, 2020
Continuous Integration is a software development practice where members of a team integrate their work frequently
Integration:
Continuous/Frequently:
Shorter development cycles
Automates and enforces good practices
Reduces manual work
Early discovery of bugs
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:
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
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.
pipeline {
agent {
# agent description
}
stages {
stage('build') {
steps {
# steps go here
}
}
stage('check') {
steps {
# steps go here
}
}
}
}
What steps should be run for an R package?
What steps should be run for an R package?
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:
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/)
run packamon::init() in a new project
(optional) run packamon::writeJenkinsfile() or packamon::writeDockerfile() for more flexibility
commit and push the generated files:
DockerfileJenkinsfiletemplate.Dockerfilecontinue working on your package as normal
if your dependencies change, run packamon::writeDockerfile() again
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.
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.
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
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
Continuous Delivery (CD): automated release of CI results
Continuous Deployment (also CD):
Compact Disc
Yes!
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.