R is a powerfull tool for data scientists but a huge pain for software developers and system administrators.
It’s hard to automate and integrate into other systems. That’s because it was developed mostly in academic environments for adhoc analytics instead of IT departments for business processes.
As every meal gets better if you gratinate it with cheese, every command line tool gets better if you wrap it in a PowerShell Commandlet.
You can do a lot with the R command line tools
Rscript.exe, but the developer of R seem to have a strange understanding of concepts like standard streams and return codes. So i created the PowerShell module PSRTools, that provides Commandlets for basic tasks needed for CI/CD pipelines.
If you have build dependecies, you have to install a R package from a repository. You can specify a snapshot to get reproducable builds. An example is:
Install-RPackage -Name 'devtools' -Repository 'https://mran.microsoft.com/' -Snapshot '2019-02-01'
In case you have the package on the disk you can install it with the Path parameter.
In both cases you can specify the library path, to install it on a specific location.
Install-RPackage -Path '.\devtools.tar.gz' -Library 'C:\temp\build\library'
If you have inline documentation in your R functions, you have to generate Rd files for the package. There is the Commandlet
New-RDocumentation for that.
The build can be executed using
New-RPackage. Both Commandlets have the parameters
Path for the project location and
Library for required R packages.
The build script depends a little on your solution. It could be something like:
param ( $Project, $StagingDirectory ) $Repository = 'https://mran.microsoft.com/' $Snapshot = '2019-02-01' $Library = New-Item ` -ItemType Directory ` -Path ( Join-Path ( [System.IO.Path]::GetTempPath() ) ( [System.Guid]::NewGuid().ToString() )) Import-Module PSRTools -Scope CurrentUser Set-RScriptPath 'C:\Program Files\Microsoft\R Open\R-3.5.2\bin\x64\Rscript.exe' Install-RPackage -Name 'devtools' -Repository $Repository -Snapshot $Snapshot -Library $Library Install-RPackage -Name 'roxygen2' -Repository $Repository -Snapshot $Snapshot -Library $Library New-RDocumentation -Path $Project -Library $Library $Package = New-RPackage -Path $Project -Library $Library Copy-Item -Path $Package -Destination $StagingDirectory
For build scripts i recommend InvokeBuild, but wanted a simple example.
To achive automated builds, you have to integrate it in a build script.
I tested it successfully in Appveyor and Azure Pipelines. Both work pretty much the same.
If you don’t have your own build agent, that can be prepared manually, you need to install R and RTools in your build script.
That can be done using Chocolatey.
In your appveyor.yml it is like:
install: - choco install microsoft-r-open - choco install rtools build_script: - ps: Build.ps1 -Project $env:APPVEYOR_BUILD_FOLDER -StagingDirectory "$env:APPVEYOR_BUILD_FOLDER\bin"
In you azure-pipelines.yml it is like:
steps: - script: | choco install microsoft-r-open choco install rtools displayName: Install build dependencies - task: PowerShell@2 inputs: targetType: 'inline' script: | Build.ps1 -Project '$(Build.SourcesDirectory)' -StagingDirectory '$(Build.ArtifactStagingDirectory)'
Not that terrible anymore, right?