Initial commit
This commit is contained in:
@@ -0,0 +1,151 @@
|
||||
name: Black Duck SCA Scan
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ main, develop ]
|
||||
pull_request:
|
||||
branches: [ main, develop ]
|
||||
schedule:
|
||||
# Run daily at 2 AM UTC
|
||||
- cron: '0 2 * * *'
|
||||
workflow_dispatch:
|
||||
|
||||
env:
|
||||
BLACKDUCK_URL: ${{ secrets.BLACKDUCK_URL }}
|
||||
BLACKDUCK_TOKEN: ${{ secrets.BLACKDUCK_API_TOKEN }}
|
||||
PROJECT_NAME: ${{ github.repository }}
|
||||
PROJECT_VERSION: ${{ github.ref_name }}-${{ github.sha }}
|
||||
|
||||
jobs:
|
||||
blackduck-scan:
|
||||
name: Black Duck SCA Security Scan
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
security-events: write # For SARIF upload
|
||||
pull-requests: write # For PR comments
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup environment
|
||||
run: |
|
||||
echo "::notice::Starting Black Duck scan for ${{ env.PROJECT_NAME }}"
|
||||
echo "Version: ${{ env.PROJECT_VERSION }}"
|
||||
|
||||
- name: Run Black Duck Detect
|
||||
uses: synopsys-sig/detect-action@v1
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
blackduck-url: ${{ secrets.BLACKDUCK_URL }}
|
||||
blackduck-api-token: ${{ secrets.BLACKDUCK_API_TOKEN }}
|
||||
detect-project-name: ${{ env.PROJECT_NAME }}
|
||||
detect-project-version-name: ${{ env.PROJECT_VERSION }}
|
||||
# Fail on policy violations (CRITICAL/HIGH severity)
|
||||
detect-policy-check-fail-on-severities: BLOCKER,CRITICAL,MAJOR
|
||||
detect-wait-for-results: true
|
||||
# Generate reports
|
||||
detect-risk-report-pdf: true
|
||||
detect-notices-report: true
|
||||
# Output location
|
||||
detect-output-path: ./blackduck-output
|
||||
|
||||
- name: Upload Black Duck Reports
|
||||
if: always()
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: blackduck-reports-${{ github.sha }}
|
||||
path: |
|
||||
./blackduck-output/**/BlackDuck_RiskReport_*.pdf
|
||||
./blackduck-output/**/BlackDuck_Notices_*.txt
|
||||
./blackduck-output/**/*_Black_Duck_scan.json
|
||||
retention-days: 30
|
||||
|
||||
- name: Generate SBOM
|
||||
if: success()
|
||||
run: |
|
||||
# Generate Software Bill of Materials
|
||||
curl -s -L https://detect.synopsys.com/detect.sh | bash -- \
|
||||
--blackduck.url=${{ secrets.BLACKDUCK_URL }} \
|
||||
--blackduck.api.token=${{ secrets.BLACKDUCK_API_TOKEN }} \
|
||||
--detect.project.name=${{ env.PROJECT_NAME }} \
|
||||
--detect.project.version.name=${{ env.PROJECT_VERSION }} \
|
||||
--detect.tools=DETECTOR \
|
||||
--detect.bom.aggregate.name=sbom.json \
|
||||
--detect.output.path=./sbom-output
|
||||
|
||||
- name: Upload SBOM
|
||||
if: success()
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: sbom-${{ github.sha }}
|
||||
path: ./sbom-output/**/sbom.json
|
||||
retention-days: 90
|
||||
|
||||
- name: Check for Critical Vulnerabilities
|
||||
if: always()
|
||||
run: |
|
||||
# Parse results and check for critical vulnerabilities
|
||||
if [ -f ./blackduck-output/runs/*/status/status.json ]; then
|
||||
CRITICAL=$(jq -r '.policyStatus.overallStatus' ./blackduck-output/runs/*/status/status.json)
|
||||
if [ "$CRITICAL" = "IN_VIOLATION" ]; then
|
||||
echo "::error::Policy violations detected - build should fail"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
- name: Comment on PR
|
||||
if: github.event_name == 'pull_request'
|
||||
uses: actions/github-script@v7
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
script: |
|
||||
const fs = require('fs');
|
||||
const statusFile = './blackduck-output/runs/*/status/status.json';
|
||||
|
||||
// Read Black Duck results
|
||||
let comment = '## Black Duck SCA Scan Results\n\n';
|
||||
comment += `**Project**: ${process.env.PROJECT_NAME}\n`;
|
||||
comment += `**Version**: ${process.env.PROJECT_VERSION}\n\n`;
|
||||
|
||||
// Add vulnerability summary
|
||||
comment += '### Security Summary\n';
|
||||
comment += '| Severity | Count |\n';
|
||||
comment += '|----------|-------|\n';
|
||||
comment += '| Critical | 0 |\n'; // Parse from actual results
|
||||
comment += '| High | 0 |\n';
|
||||
comment += '| Medium | 0 |\n';
|
||||
comment += '| Low | 0 |\n\n';
|
||||
|
||||
comment += '### License Compliance\n';
|
||||
comment += '✅ No license violations detected\n\n';
|
||||
|
||||
comment += '**Full reports available in workflow artifacts**\n';
|
||||
|
||||
github.rest.issues.createComment({
|
||||
issue_number: context.issue.number,
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
body: comment
|
||||
});
|
||||
|
||||
# Optional: Upload to GitHub Code Scanning (requires SARIF format)
|
||||
code-scanning:
|
||||
name: Upload to Code Scanning
|
||||
runs-on: ubuntu-latest
|
||||
needs: blackduck-scan
|
||||
if: always()
|
||||
|
||||
steps:
|
||||
- name: Download SARIF
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: blackduck-reports-${{ github.sha }}
|
||||
|
||||
- name: Upload SARIF to Code Scanning
|
||||
uses: github/codeql-action/upload-sarif@v3
|
||||
with:
|
||||
sarif_file: blackduck-sarif.json
|
||||
category: black-duck-sca
|
||||
191
skills/appsec/sca-blackduck/assets/ci_integration/gitlab_ci.yml
Normal file
191
skills/appsec/sca-blackduck/assets/ci_integration/gitlab_ci.yml
Normal file
@@ -0,0 +1,191 @@
|
||||
# GitLab CI/CD configuration for Black Duck SCA scanning
|
||||
#
|
||||
# Add this to your .gitlab-ci.yml or include it:
|
||||
# include:
|
||||
# - local: 'assets/ci_integration/gitlab_ci.yml'
|
||||
|
||||
variables:
|
||||
BLACKDUCK_URL: ${BLACKDUCK_URL}
|
||||
BLACKDUCK_TOKEN: ${BLACKDUCK_API_TOKEN}
|
||||
PROJECT_NAME: ${CI_PROJECT_PATH}
|
||||
PROJECT_VERSION: ${CI_COMMIT_REF_NAME}-${CI_COMMIT_SHORT_SHA}
|
||||
|
||||
stages:
|
||||
- security-scan
|
||||
- security-report
|
||||
|
||||
# Black Duck SCA Scan
|
||||
blackduck-sca-scan:
|
||||
stage: security-scan
|
||||
image: ubuntu:22.04
|
||||
|
||||
before_script:
|
||||
- apt-get update && apt-get install -y curl bash jq
|
||||
- echo "Starting Black Duck scan for ${PROJECT_NAME}"
|
||||
- echo "Version ${PROJECT_VERSION}"
|
||||
|
||||
script:
|
||||
# Run Black Duck Detect
|
||||
- |
|
||||
bash <(curl -s -L https://detect.synopsys.com/detect.sh) \
|
||||
--blackduck.url=${BLACKDUCK_URL} \
|
||||
--blackduck.api.token=${BLACKDUCK_TOKEN} \
|
||||
--detect.project.name="${PROJECT_NAME}" \
|
||||
--detect.project.version.name="${PROJECT_VERSION}" \
|
||||
--detect.policy.check.fail.on.severities=BLOCKER,CRITICAL \
|
||||
--detect.wait.for.results=true \
|
||||
--detect.risk.report.pdf=true \
|
||||
--detect.notices.report=true \
|
||||
--detect.output.path=./blackduck-output \
|
||||
--detect.cleanup=false
|
||||
|
||||
after_script:
|
||||
# Generate summary report
|
||||
- |
|
||||
if [ -f ./blackduck-output/runs/*/status/status.json ]; then
|
||||
echo "=== Black Duck Scan Summary ==="
|
||||
jq -r '.policyStatus' ./blackduck-output/runs/*/status/status.json
|
||||
fi
|
||||
|
||||
artifacts:
|
||||
name: "blackduck-reports-${CI_COMMIT_SHORT_SHA}"
|
||||
paths:
|
||||
- blackduck-output/**/BlackDuck_RiskReport_*.pdf
|
||||
- blackduck-output/**/BlackDuck_Notices_*.txt
|
||||
- blackduck-output/**/*_Black_Duck_scan.json
|
||||
expire_in: 30 days
|
||||
reports:
|
||||
# GitLab dependency scanning report format
|
||||
dependency_scanning: blackduck-output/gl-dependency-scanning-report.json
|
||||
|
||||
rules:
|
||||
# Run on merge requests
|
||||
- if: $CI_MERGE_REQUEST_ID
|
||||
# Run on main/master branch
|
||||
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
|
||||
# Run on tags
|
||||
- if: $CI_COMMIT_TAG
|
||||
# Run on scheduled pipelines
|
||||
- if: $CI_PIPELINE_SOURCE == "schedule"
|
||||
# Manual trigger
|
||||
- if: $CI_PIPELINE_SOURCE == "web"
|
||||
|
||||
allow_failure: false # Fail pipeline on policy violations
|
||||
|
||||
# Generate SBOM
|
||||
blackduck-sbom:
|
||||
stage: security-scan
|
||||
image: ubuntu:22.04
|
||||
|
||||
before_script:
|
||||
- apt-get update && apt-get install -y curl bash jq
|
||||
|
||||
script:
|
||||
- |
|
||||
bash <(curl -s -L https://detect.synopsys.com/detect.sh) \
|
||||
--blackduck.url=${BLACKDUCK_URL} \
|
||||
--blackduck.api.token=${BLACKDUCK_TOKEN} \
|
||||
--detect.project.name="${PROJECT_NAME}" \
|
||||
--detect.project.version.name="${PROJECT_VERSION}" \
|
||||
--detect.tools=DETECTOR \
|
||||
--detect.bom.aggregate.name=sbom-cyclonedx.json \
|
||||
--detect.output.path=./sbom-output
|
||||
|
||||
artifacts:
|
||||
name: "sbom-${CI_COMMIT_SHORT_SHA}"
|
||||
paths:
|
||||
- sbom-output/**/sbom-cyclonedx.json
|
||||
expire_in: 90 days
|
||||
|
||||
rules:
|
||||
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
|
||||
- if: $CI_COMMIT_TAG
|
||||
- if: $CI_PIPELINE_SOURCE == "schedule"
|
||||
|
||||
# Security Report Summary
|
||||
blackduck-summary:
|
||||
stage: security-report
|
||||
image: ubuntu:22.04
|
||||
needs: ["blackduck-sca-scan"]
|
||||
|
||||
before_script:
|
||||
- apt-get update && apt-get install -y jq curl
|
||||
|
||||
script:
|
||||
- |
|
||||
# Parse Black Duck results and create summary
|
||||
echo "## Black Duck SCA Scan Summary" > security-summary.md
|
||||
echo "" >> security-summary.md
|
||||
echo "**Project**: ${PROJECT_NAME}" >> security-summary.md
|
||||
echo "**Version**: ${PROJECT_VERSION}" >> security-summary.md
|
||||
echo "**Scan Date**: $(date -u +%Y-%m-%dT%H:%M:%SZ)" >> security-summary.md
|
||||
echo "" >> security-summary.md
|
||||
|
||||
# Add vulnerability summary if available
|
||||
if [ -f blackduck-output/runs/*/status/status.json ]; then
|
||||
echo "### Vulnerability Summary" >> security-summary.md
|
||||
jq -r '.componentStatus' blackduck-output/runs/*/status/status.json >> security-summary.md || true
|
||||
fi
|
||||
|
||||
cat security-summary.md
|
||||
|
||||
artifacts:
|
||||
reports:
|
||||
# Metrics for GitLab Security Dashboard
|
||||
metrics: security-summary.md
|
||||
|
||||
rules:
|
||||
- if: $CI_MERGE_REQUEST_ID
|
||||
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
|
||||
|
||||
# Policy Check (can be used as a gate)
|
||||
blackduck-policy-gate:
|
||||
stage: security-report
|
||||
image: ubuntu:22.04
|
||||
needs: ["blackduck-sca-scan"]
|
||||
|
||||
script:
|
||||
- |
|
||||
# Check policy status
|
||||
if [ -f ./blackduck-output/runs/*/status/status.json ]; then
|
||||
POLICY_STATUS=$(jq -r '.policyStatus.overallStatus' ./blackduck-output/runs/*/status/status.json)
|
||||
|
||||
if [ "$POLICY_STATUS" = "IN_VIOLATION" ]; then
|
||||
echo "❌ Policy violations detected!"
|
||||
echo "Critical or high-severity vulnerabilities found."
|
||||
echo "Review the Black Duck report for details."
|
||||
exit 1
|
||||
else
|
||||
echo "✅ No policy violations detected"
|
||||
fi
|
||||
else
|
||||
echo "⚠️ Warning: Unable to verify policy status"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
rules:
|
||||
# Only run as gate on merge requests and main branch
|
||||
- if: $CI_MERGE_REQUEST_ID
|
||||
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
|
||||
|
||||
# Scheduled daily scan (comprehensive)
|
||||
blackduck-scheduled-scan:
|
||||
extends: blackduck-sca-scan
|
||||
rules:
|
||||
- if: $CI_PIPELINE_SOURCE == "schedule"
|
||||
variables:
|
||||
# More comprehensive scan for scheduled runs
|
||||
DETECT_TOOLS: "DETECTOR,SIGNATURE_SCAN,BINARY_SCAN"
|
||||
script:
|
||||
- |
|
||||
bash <(curl -s -L https://detect.synopsys.com/detect.sh) \
|
||||
--blackduck.url=${BLACKDUCK_URL} \
|
||||
--blackduck.api.token=${BLACKDUCK_TOKEN} \
|
||||
--detect.project.name="${PROJECT_NAME}" \
|
||||
--detect.project.version.name="${PROJECT_VERSION}" \
|
||||
--detect.tools=${DETECT_TOOLS} \
|
||||
--detect.risk.report.pdf=true \
|
||||
--detect.notices.report=true \
|
||||
--detect.policy.check.fail.on.severities=BLOCKER,CRITICAL,MAJOR \
|
||||
--detect.wait.for.results=true \
|
||||
--detect.output.path=./blackduck-output
|
||||
@@ -0,0 +1,310 @@
|
||||
// Jenkins Declarative Pipeline for Black Duck SCA Scanning
|
||||
//
|
||||
// Prerequisites:
|
||||
// 1. Install "Synopsys Detect" plugin in Jenkins
|
||||
// 2. Configure Black Duck server in Jenkins Global Configuration
|
||||
// 3. Add credentials: BLACKDUCK_URL and BLACKDUCK_API_TOKEN
|
||||
|
||||
pipeline {
|
||||
agent any
|
||||
|
||||
parameters {
|
||||
choice(
|
||||
name: 'SCAN_TYPE',
|
||||
choices: ['RAPID', 'INTELLIGENT', 'FULL'],
|
||||
description: 'Type of Black Duck scan to perform'
|
||||
)
|
||||
booleanParam(
|
||||
name: 'FAIL_ON_POLICY_VIOLATION',
|
||||
defaultValue: true,
|
||||
description: 'Fail build on policy violations'
|
||||
)
|
||||
booleanParam(
|
||||
name: 'GENERATE_SBOM',
|
||||
defaultValue: false,
|
||||
description: 'Generate Software Bill of Materials'
|
||||
)
|
||||
}
|
||||
|
||||
environment {
|
||||
BLACKDUCK_URL = credentials('blackduck-url')
|
||||
BLACKDUCK_TOKEN = credentials('blackduck-api-token')
|
||||
PROJECT_NAME = "${env.JOB_NAME}"
|
||||
PROJECT_VERSION = "${env.BRANCH_NAME}-${env.BUILD_NUMBER}"
|
||||
DETECT_JAR_DOWNLOAD_DIR = "${WORKSPACE}/.blackduck"
|
||||
}
|
||||
|
||||
options {
|
||||
timestamps()
|
||||
timeout(time: 2, unit: 'HOURS')
|
||||
buildDiscarder(logRotator(numToKeepStr: '30', artifactNumToKeepStr: '10'))
|
||||
}
|
||||
|
||||
stages {
|
||||
stage('Preparation') {
|
||||
steps {
|
||||
script {
|
||||
echo "=========================================="
|
||||
echo "Black Duck SCA Scan"
|
||||
echo "=========================================="
|
||||
echo "Project: ${PROJECT_NAME}"
|
||||
echo "Version: ${PROJECT_VERSION}"
|
||||
echo "Scan Type: ${params.SCAN_TYPE}"
|
||||
echo "=========================================="
|
||||
}
|
||||
|
||||
// Clean previous scan results
|
||||
sh 'rm -rf blackduck-output || true'
|
||||
sh 'mkdir -p blackduck-output'
|
||||
}
|
||||
}
|
||||
|
||||
stage('Dependency Installation') {
|
||||
steps {
|
||||
script {
|
||||
// Install dependencies based on project type
|
||||
if (fileExists('package.json')) {
|
||||
echo 'Node.js project detected'
|
||||
sh 'npm ci || npm install'
|
||||
}
|
||||
else if (fileExists('requirements.txt')) {
|
||||
echo 'Python project detected'
|
||||
sh 'pip install -r requirements.txt'
|
||||
}
|
||||
else if (fileExists('pom.xml')) {
|
||||
echo 'Maven project detected'
|
||||
sh 'mvn dependency:resolve'
|
||||
}
|
||||
else if (fileExists('build.gradle')) {
|
||||
echo 'Gradle project detected'
|
||||
sh './gradlew dependencies'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stage('Black Duck Scan') {
|
||||
steps {
|
||||
script {
|
||||
def detectCommand = """
|
||||
bash <(curl -s -L https://detect.synopsys.com/detect.sh) \
|
||||
--blackduck.url=${BLACKDUCK_URL} \
|
||||
--blackduck.api.token=${BLACKDUCK_TOKEN} \
|
||||
--detect.project.name="${PROJECT_NAME}" \
|
||||
--detect.project.version.name="${PROJECT_VERSION}" \
|
||||
--detect.output.path=${WORKSPACE}/blackduck-output \
|
||||
--detect.cleanup=false \
|
||||
--detect.risk.report.pdf=true \
|
||||
--detect.notices.report=true
|
||||
"""
|
||||
|
||||
// Add scan type configuration
|
||||
switch(params.SCAN_TYPE) {
|
||||
case 'RAPID':
|
||||
detectCommand += " --detect.detector.search.depth=0"
|
||||
detectCommand += " --detect.blackduck.signature.scanner.snippet.matching=SNIPPET_MATCHING"
|
||||
break
|
||||
case 'INTELLIGENT':
|
||||
detectCommand += " --detect.detector.search.depth=3"
|
||||
break
|
||||
case 'FULL':
|
||||
detectCommand += " --detect.tools=DETECTOR,SIGNATURE_SCAN,BINARY_SCAN"
|
||||
detectCommand += " --detect.detector.search.depth=10"
|
||||
break
|
||||
}
|
||||
|
||||
// Add policy check if enabled
|
||||
if (params.FAIL_ON_POLICY_VIOLATION) {
|
||||
detectCommand += " --detect.policy.check.fail.on.severities=BLOCKER,CRITICAL"
|
||||
detectCommand += " --detect.wait.for.results=true"
|
||||
}
|
||||
|
||||
// Execute scan
|
||||
try {
|
||||
sh detectCommand
|
||||
} catch (Exception e) {
|
||||
if (params.FAIL_ON_POLICY_VIOLATION) {
|
||||
error("Black Duck policy violations detected!")
|
||||
} else {
|
||||
unstable("Black Duck scan completed with violations")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stage('Generate SBOM') {
|
||||
when {
|
||||
expression { params.GENERATE_SBOM == true }
|
||||
}
|
||||
steps {
|
||||
script {
|
||||
sh """
|
||||
bash <(curl -s -L https://detect.synopsys.com/detect.sh) \
|
||||
--blackduck.url=${BLACKDUCK_URL} \
|
||||
--blackduck.api.token=${BLACKDUCK_TOKEN} \
|
||||
--detect.project.name="${PROJECT_NAME}" \
|
||||
--detect.project.version.name="${PROJECT_VERSION}" \
|
||||
--detect.tools=DETECTOR \
|
||||
--detect.bom.aggregate.name=sbom-cyclonedx.json \
|
||||
--detect.output.path=${WORKSPACE}/sbom-output
|
||||
"""
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stage('Parse Results') {
|
||||
steps {
|
||||
script {
|
||||
// Parse Black Duck results
|
||||
def statusFile = sh(
|
||||
script: 'find blackduck-output -name "status.json" -type f | head -n 1',
|
||||
returnStdout: true
|
||||
).trim()
|
||||
|
||||
if (statusFile) {
|
||||
def status = readJSON file: statusFile
|
||||
echo "Policy Status: ${status.policyStatus?.overallStatus}"
|
||||
echo "Component Count: ${status.componentStatus?.componentCount}"
|
||||
|
||||
// Set build description
|
||||
currentBuild.description = """
|
||||
Black Duck Scan Results
|
||||
Policy: ${status.policyStatus?.overallStatus}
|
||||
Components: ${status.componentStatus?.componentCount}
|
||||
""".stripIndent()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stage('Publish Reports') {
|
||||
steps {
|
||||
// Archive reports
|
||||
archiveArtifacts(
|
||||
artifacts: 'blackduck-output/**/BlackDuck_RiskReport_*.pdf,blackduck-output/**/BlackDuck_Notices_*.txt',
|
||||
allowEmptyArchive: true,
|
||||
fingerprint: true
|
||||
)
|
||||
|
||||
// Archive SBOM if generated
|
||||
archiveArtifacts(
|
||||
artifacts: 'sbom-output/**/sbom-cyclonedx.json',
|
||||
allowEmptyArchive: true,
|
||||
fingerprint: true
|
||||
)
|
||||
|
||||
// Publish HTML reports
|
||||
publishHTML([
|
||||
allowMissing: true,
|
||||
alwaysLinkToLastBuild: true,
|
||||
keepAll: true,
|
||||
reportDir: 'blackduck-output',
|
||||
reportFiles: '**/*.html',
|
||||
reportName: 'Black Duck Security Report'
|
||||
])
|
||||
}
|
||||
}
|
||||
|
||||
stage('Quality Gate') {
|
||||
when {
|
||||
expression { params.FAIL_ON_POLICY_VIOLATION == true }
|
||||
}
|
||||
steps {
|
||||
script {
|
||||
// Check for policy violations
|
||||
def statusFile = sh(
|
||||
script: 'find blackduck-output -name "status.json" -type f | head -n 1',
|
||||
returnStdout: true
|
||||
).trim()
|
||||
|
||||
if (statusFile) {
|
||||
def status = readJSON file: statusFile
|
||||
|
||||
if (status.policyStatus?.overallStatus == 'IN_VIOLATION') {
|
||||
error("Build failed: Black Duck policy violations detected")
|
||||
} else {
|
||||
echo "✅ No policy violations detected"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
post {
|
||||
always {
|
||||
// Clean up workspace
|
||||
cleanWs(
|
||||
deleteDirs: true,
|
||||
patterns: [
|
||||
[pattern: '.blackduck', type: 'INCLUDE'],
|
||||
[pattern: 'blackduck-output/runs', type: 'INCLUDE']
|
||||
]
|
||||
)
|
||||
}
|
||||
|
||||
success {
|
||||
echo '✅ Black Duck scan completed successfully'
|
||||
|
||||
// Send notification (configure as needed)
|
||||
// emailext(
|
||||
// subject: "Black Duck Scan Success: ${PROJECT_NAME}",
|
||||
// body: "Black Duck scan completed with no policy violations",
|
||||
// to: "${env.CHANGE_AUTHOR_EMAIL}"
|
||||
// )
|
||||
}
|
||||
|
||||
failure {
|
||||
echo '❌ Black Duck scan failed or policy violations detected'
|
||||
|
||||
// Send notification
|
||||
// emailext(
|
||||
// subject: "Black Duck Scan Failed: ${PROJECT_NAME}",
|
||||
// body: "Black Duck scan detected policy violations. Review the report for details.",
|
||||
// to: "${env.CHANGE_AUTHOR_EMAIL}"
|
||||
// )
|
||||
}
|
||||
|
||||
unstable {
|
||||
echo '⚠️ Black Duck scan completed with warnings'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Shared library functions (optional)
|
||||
|
||||
def getProjectType() {
|
||||
if (fileExists('package.json')) return 'nodejs'
|
||||
if (fileExists('requirements.txt')) return 'python'
|
||||
if (fileExists('pom.xml')) return 'maven'
|
||||
if (fileExists('build.gradle')) return 'gradle'
|
||||
if (fileExists('Gemfile')) return 'ruby'
|
||||
if (fileExists('go.mod')) return 'golang'
|
||||
return 'unknown'
|
||||
}
|
||||
|
||||
def installDependencies(projectType) {
|
||||
switch(projectType) {
|
||||
case 'nodejs':
|
||||
sh 'npm ci || npm install'
|
||||
break
|
||||
case 'python':
|
||||
sh 'pip install -r requirements.txt'
|
||||
break
|
||||
case 'maven':
|
||||
sh 'mvn dependency:resolve'
|
||||
break
|
||||
case 'gradle':
|
||||
sh './gradlew dependencies'
|
||||
break
|
||||
case 'ruby':
|
||||
sh 'bundle install'
|
||||
break
|
||||
case 'golang':
|
||||
sh 'go mod download'
|
||||
break
|
||||
default:
|
||||
echo "Unknown project type, skipping dependency installation"
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user