Skip to content

test ci: add gh workflows to generate sbom #15

test ci: add gh workflows to generate sbom

test ci: add gh workflows to generate sbom #15

Workflow file for this run

name: Download SBOM from Insights and Convert to CSV
on:
pull_request:
branches:
- main
jobs:
convert-sbom:
runs-on: ubuntu-latest
steps:
- name: Checkout Code
uses: actions/checkout@v3
- name: Set Timestamp and Unique Filename
run: |
FILE_PREFIX=$(echo "${{ github.repository }}" | sed 's|/|-|g')-$(date +%Y%m%d%H%M%S)
echo "FILE_PREFIX=${FILE_PREFIX}" >> $GITHUB_ENV
- name: Download SBOM
run: |
curl -L \
-H "Accept: application/vnd.github+json" \
-H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \
-H "X-GitHub-Api-Version: 2022-11-28" \
https://api.github.com/repos/${{ github.repository }}/dependency-graph/sbom \
-o "${FILE_PREFIX}-sbom.json"
- name: Verify SBOM JSON File
run: |
ls -l "${FILE_PREFIX}-sbom.json"
- name: Preview SBOM JSON Content
run: |
head -n 20 "${FILE_PREFIX}-sbom.json"
- name: Convert SBOM to CSV using jq
run: |
echo "name,SPDXID,versionInfo,downloadLocation,externalRefs,license,source_code_url,vendor" > "${FILE_PREFIX}-sbom.csv"
jq -r '
.sbom.packages[] | [
.name,
.SPDXID,
.versionInfo,
.downloadLocation,
( .externalRefs[]? | .referenceLocator ),
"None", "None", "None"
] | @csv' "${FILE_PREFIX}-sbom.json" >> "${FILE_PREFIX}-sbom.csv"
- name: Preview SBOM CSV Content
run: |
head -n 20 "${FILE_PREFIX}-sbom.csv"
- name: Enrich SBOM CSV with RubyGems Data
run: |
TEMP_CSV="${FILE_PREFIX}-sbom-temp.csv"
echo "name,SPDXID,versionInfo,downloadLocation,externalRefs,license,source_code_url,vendor" > "$TEMP_CSV"
tail -n +2 "${FILE_PREFIX}-sbom.csv" | while IFS=, read -r name SPDXID versionInfo downloadLocation externalRefs license source_code_url vendor; do
# Debug each row
echo "Processing: $name, $SPDXID, $versionInfo, $downloadLocation, $externalRefs, $license, $source_code_url, $vendor"
if [[ "$externalRefs" == *"pkg:gem"* ]]; then
echo "Processing RubyGem: $name"
gem_name=$(echo "$name" | tr -d '"')
version=$(echo "$versionInfo" | tr -d '"')
# If version has a comparison operator (e.g., ~>, >=, <=)
if [[ "$versionInfo" =~ [\~\>\<\=\ ] ]]; then
echo "Evaluating version constraint: $versionInfo"
# Extract the base version (e.g., "2.11" from "~> 2.11")
base_version=$(echo "$versionInfo" | sed -E 's/[^\d.]//g')
# Get the list of available versions from RubyGems API
api_url="https://rubygems.org/api/v2/rubygems/${gem_name}/versions.json"
available_versions=$(curl -s "$api_url" | jq -r '.[].version')
# Find the valid version according to the constraint
valid_version=""
if [[ "$versionInfo" == "~>"* ]]; then
# Handle pessimistic constraint "~> 2.11" (i.e., 2.11.x but not 3.0)
valid_version=$(echo "$available_versions" | grep -E "^${base_version}\." | sort -V | head -n 1)
elif [[ "$versionInfo" == ">="* ]]; then
# Handle >= constraint
valid_version=$(echo "$available_versions" | grep -E "^${base_version}" | sort -V | head -n 1)
elif [[ "$versionInfo" == "<="* ]]; then
# Handle <= constraint
valid_version=$(echo "$available_versions" | grep -E "^${base_version}" | sort -V | tail -n 1)
fi
if [ -z "$valid_version" ]; then
echo "No valid version found for constraint $versionInfo"
continue
fi
# Proceed with the valid version
echo "Using version: $valid_version for $gem_name"
api_url="https://rubygems.org/api/v2/rubygems/${gem_name}/versions/${valid_version}.json"
response=$(curl -s "$api_url")
# Extract relevant fields from the response
new_license=$(echo "$response" | jq -r '.licenses[0] // "None"')
new_source_code_url=$(echo "$response" | jq -r '.source_code_uri // "None"')
new_vendor=$(echo "$response" | jq -r '.authors // "None"')
else
# Handle fixed version
echo "Fixed version: $versionInfo"
api_url="https://rubygems.org/api/v2/rubygems/${gem_name}/versions/${versionInfo}.json"
response=$(curl -s "$api_url")
new_license=$(echo "$response" | jq -r '.licenses[0] // "None"')
new_source_code_url=$(echo "$response" | jq -r '.source_code_uri // "None"')
new_vendor=$(echo "$response" | jq -r '.authors // "None"')
fi
else
# Default values if not a RubyGem
new_license="None"
new_source_code_url="None"
new_vendor="None"
fi
# Write updated values to temp CSV
echo "$name,$SPDXID,$versionInfo,$downloadLocation,$externalRefs,$new_license,$new_source_code_url,$new_vendor" >> "$TEMP_CSV"
done
mv "$TEMP_CSV" "${FILE_PREFIX}-sbom.csv"
- name: Verify SBOM CSV File
run: |
ls -l "${FILE_PREFIX}-sbom.csv"
- name: Upload SBOM JSON as Artifact
uses: actions/upload-artifact@v3
with:
name: sbom-json
path: ${{ env.FILE_PREFIX }}-sbom.json
- name: Upload SBOM CSV as Artifact
uses: actions/upload-artifact@v3
with:
name: sbom-csv
path: ${{ env.FILE_PREFIX }}-sbom.csv