Skip to content

Workflow file for this run

name: Audit Dependencies 🕵️‍♀️
on:
push:
branches:
- main
pull_request:
types:
- opened
- synchronize
- reopened
- ready_for_review
branches:
- main
workflow_dispatch:
workflow_call:
inputs:
package-subdirectory:
description: Subdirectory in the repository, where the R package is located.
required: false
type: string
default: "."
allow-failure:
description: Allow workflow to fail if one or more vulnerabilities are found.
required: false
type: boolean
default: false
jobs:
audit:
runs-on: ubuntu-latest
container:
image: ghcr.io/insightsengineering/rstudio:latest
name: oysteR scan 🦪
if: >
!contains(github.event.commits[0].message, '[skip audit]')
&& github.event.pull_request.draft == false
steps:
- name: Get branch names 🌿
id: branch-name
uses: tj-actions/branch-names@v7
- name: Checkout repo (PR) 🛎
uses: actions/[email protected]
if: github.event_name == 'pull_request'
with:
ref: ${{ steps.branch-name.outputs.head_ref_branch }}
repository: ${{ github.event.pull_request.head.repo.full_name }}
fetch-depth: 1
- name: Checkout repo 🛎
uses: actions/[email protected]
if: github.event_name != 'pull_request'
with:
ref: ${{ steps.branch-name.outputs.head_ref_branch }}
fetch-depth: 1
- name: Check commit message 💬
run: |
git config --global --add safe.directory $(pwd)
export head_commit_message="$(git show -s --format=%B | tr '\r\n' ' ' | tr '\n' ' ')"
echo "head_commit_message = $head_commit_message"
if [[ $head_commit_message == *"$SKIP_INSTRUCTION"* ]]; then
echo "Skip instruction detected - cancelling the workflow."
exit 1
fi
shell: bash
env:
SKIP_INSTRUCTION: "[skip audit]"
- name: Normalize inputs 🛠️
id: normalizer
run: |
ALLOW_FAILURE="${{ inputs.allow-failure }}"
if [ "$ALLOW_FAILURE" == "" ]
then {
ALLOW_FAILURE=false
}
fi
echo "allow-failure=$ALLOW_FAILURE" >> "$GITHUB_ENV"
shell: bash
- name: Run oysteR scan on dependencies 🔍
run: |
tryCatch(
expr = {
dependencies_scan = oysteR::audit_description(
dir = ".",
fields = c("Depends", "Imports", "Suggests"),
verbose = TRUE
)
print(as.data.frame(
dependencies_scan[c(
"package",
"version",
"vulnerabilities",
"no_of_vulnerabilities"
)]
))
Sys.sleep(1)
deps_with_vulnerabilities = subset(dependencies_scan, no_of_vulnerabilities > 0)
if(nrow(deps_with_vulnerabilities) > 0) {
message("❗ Vulnerabilities found in the following dependencies:")
message(deps_with_vulnerabilities["package"])
if ("${{ env.allow-failure }}" == "true") quit(status=1)
}
},
error = function(e) {
message('🚨 Caught an error!')
print(e)
}
)
shell: Rscript {0}
working-directory: ${{ inputs.package-subdirectory }}
- name: Run oysteR scan on renv.lock 🔒
run: |
tryCatch(
expr = {
if (file.exists("renv.lock")) {
renv_lock_scan = oysteR::audit_renv_lock(dir = ".", verbose = TRUE)
print(as.data.frame(
renv_lock_scan[c(
"package",
"version",
"vulnerabilities",
"no_of_vulnerabilities"
)]
))
Sys.sleep(1)
deps_with_vulnerabilities = subset(renv_lock_scan, no_of_vulnerabilities > 0)
if(nrow(deps_with_vulnerabilities) > 0) {
message("❗ Vulnerabilities found in the following dependencies:")
message(deps_with_vulnerabilities["package"])
if ("${{ env.allow-failure }}" == "true") quit(status=1)
}
} else {
print("No renv.lock file, not scanning.")
}
},
error = function(e) {
message('🚨 Caught an error!')
print(e)
}
)
shell: Rscript {0}