[CHECK] check for oss vulnerabilites - 2 #1
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Security Check | |
| on: [push, pull_request] | |
| jobs: | |
| security-audit: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Set up R | |
| uses: r-lib/actions/setup-r@v2 | |
| with: | |
| r-version: 'release' | |
| - name: Install system dependencies | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y libcurl4-openssl-dev libssl-dev libxml2-dev | |
| - name: Cache R packages | |
| uses: actions/cache@v3 | |
| with: | |
| path: ~/.local/lib/R/site-library | |
| key: ${{ runner.os }}-r-${{ hashFiles('DESCRIPTION') }} | |
| restore-keys: ${{ runner.os }}-r- | |
| - name: Install oysteR | |
| run: | | |
| R -e "install.packages('oysteR', repos='https://cran.r-project.org')" | |
| - name: Install clintrialx (if needed) | |
| run: | | |
| R -e "if (!require('clintrialx', quietly = TRUE)) install.packages('clintrialx', repos='https://cran.r-project.org')" | |
| continue-on-error: true | |
| - name: Run security audit | |
| id: audit | |
| run: | | |
| # Create R script for vulnerability check | |
| cat > check_vulnerabilities.R << 'EOF' | |
| library(oysteR) | |
| # Function to safely check vulnerabilities | |
| check_package_vulnerabilities <- function(pkg_name) { | |
| tryCatch({ | |
| # Try to get vulnerabilities for the package | |
| result <- expect_secure(pkg_name) | |
| # If we get here, no vulnerabilities found | |
| cat("VULNERABILITY_COUNT=0\n", file = Sys.getenv("GITHUB_OUTPUT"), append = TRUE) | |
| cat("STATUS=success\n", file = Sys.getenv("GITHUB_OUTPUT"), append = TRUE) | |
| cat("MESSAGE=No vulnerabilities found\n", file = Sys.getenv("GITHUB_OUTPUT"), append = TRUE) | |
| return(0) | |
| }, error = function(e) { | |
| # Check if error is due to vulnerabilities found | |
| if (grepl("vulnerabilities", e$message, ignore.case = TRUE)) { | |
| # Parse vulnerability count if possible | |
| vuln_match <- regexpr("[0-9]+", e$message) | |
| if (vuln_match > 0) { | |
| vuln_count <- regmatches(e$message, vuln_match) | |
| cat(paste0("VULNERABILITY_COUNT=", vuln_count, "\n"), file = Sys.getenv("GITHUB_OUTPUT"), append = TRUE) | |
| } else { | |
| cat("VULNERABILITY_COUNT=unknown\n", file = Sys.getenv("GITHUB_OUTPUT"), append = TRUE) | |
| } | |
| cat("STATUS=failure\n", file = Sys.getenv("GITHUB_OUTPUT"), append = TRUE) | |
| cat(paste0("MESSAGE=", gsub("\n", " ", e$message), "\n"), file = Sys.getenv("GITHUB_OUTPUT"), append = TRUE) | |
| } else { | |
| # Other error (package not found, network issue, etc.) | |
| cat("VULNERABILITY_COUNT=error\n", file = Sys.getenv("GITHUB_OUTPUT"), append = TRUE) | |
| cat("STATUS=error\n", file = Sys.getenv("GITHUB_OUTPUT"), append = TRUE) | |
| cat(paste0("MESSAGE=Check failed: ", gsub("\n", " ", e$message), "\n"), file = Sys.getenv("GITHUB_OUTPUT"), append = TRUE) | |
| } | |
| return(1) | |
| }) | |
| } | |
| # Run the check | |
| result <- check_package_vulnerabilities("clintrialx") | |
| quit(status = result) | |
| EOF | |
| # Run the R script | |
| R --slave < check_vulnerabilities.R | |
| continue-on-error: true | |
| - name: Create vulnerability badge | |
| run: | | |
| # Determine badge color and message based on results | |
| case "${{ steps.audit.outputs.STATUS }}" in | |
| "success") | |
| BADGE_COLOR="brightgreen" | |
| BADGE_MESSAGE="0" | |
| ;; | |
| "failure") | |
| BADGE_COLOR="red" | |
| BADGE_MESSAGE="${{ steps.audit.outputs.VULNERABILITY_COUNT }}" | |
| ;; | |
| "error") | |
| BADGE_COLOR="orange" | |
| BADGE_MESSAGE="check%20failed" | |
| ;; | |
| *) | |
| BADGE_COLOR="lightgrey" | |
| BADGE_MESSAGE="unknown" | |
| ;; | |
| esac | |
| # Create badge URL | |
| BADGE_URL="https://img.shields.io/badge/clintrialx%20vulnerabilities-${BADGE_MESSAGE}-${BADGE_COLOR}" | |
| # Output badge info | |
| echo "BADGE_URL=${BADGE_URL}" >> $GITHUB_OUTPUT | |
| echo "Badge URL: ${BADGE_URL}" | |
| echo "Status: ${{ steps.audit.outputs.STATUS }}" | |
| echo "Message: ${{ steps.audit.outputs.MESSAGE }}" | |
| id: badge | |
| - name: Update README badge (optional) | |
| if: github.ref == 'refs/heads/main' || github.ref == 'refs/heads/master' | |
| run: | | |
| # This step would update your README.md file with the new badge | |
| # You can customize this based on your README structure | |
| echo "Badge URL for README: ${{ steps.badge.outputs.BADGE_URL }}" | |
| echo "You can manually update your README.md with this badge URL" | |
| - name: Create badge artifact | |
| uses: actions/upload-artifact@v3 | |
| with: | |
| name: security-badge | |
| path: | | |
| badge_info.txt | |
| retention-days: 30 | |
| if: always() | |
| - name: Save badge info | |
| run: | | |
| echo "Badge URL: ${{ steps.badge.outputs.BADGE_URL }}" > badge_info.txt | |
| echo "Status: ${{ steps.audit.outputs.STATUS }}" >> badge_info.txt | |
| echo "Vulnerability Count: ${{ steps.audit.outputs.VULNERABILITY_COUNT }}" >> badge_info.txt | |
| echo "Message: ${{ steps.audit.outputs.MESSAGE }}" >> badge_info.txt | |
| if: always() |