Skip to content

Merge pull request #478 from mattjala/filter_path #338

Merge pull request #478 from mattjala/filter_path

Merge pull request #478 from mattjala/filter_path #338

name: Security and Dependency Scanning
on:
push:
pull_request:
branches: [ master ]
schedule:
# Run security scan weekly on Sundays at 3 AM UTC
- cron: '0 3 * * 0'
permissions:
contents: read
security-events: write
actions: read
env:
MAVEN_OPTS: >-
-Xmx2g
-Xms1g
-XX:+UseParallelGC
-Djava.awt.headless=true
jobs:
dependency-check:
name: Dependency Vulnerability Scan
runs-on: ubuntu-latest
timeout-minutes: 20
steps:
- name: Checkout Code
uses: actions/checkout@v4
- name: Set up JDK 21
uses: actions/setup-java@v4
with:
java-version: '21'
distribution: 'temurin'
- name: Cache Maven Dependencies
uses: actions/cache@v4
with:
path: ~/.m2/repository
key: ${{ runner.os }}-maven-security-${{ hashFiles('**/pom.xml') }}
restore-keys: |
${{ runner.os }}-maven-security-
${{ runner.os }}-maven-
- name: Cache OWASP Database
uses: actions/cache@v4
with:
path: ~/.m2/repository/org/owasp/dependency-check-data
key: ${{ runner.os }}-owasp-db-${{ github.run_number }}
restore-keys: |
${{ runner.os }}-owasp-db-
- name: Set up build.properties
run: |
cat > build.properties << EOF
hdf5.lib.dir=/usr/lib/x86_64-linux-gnu
hdf5.plugin.dir=/usr/lib/x86_64-linux-gnu/hdf5/plugins
hdf.lib.dir=/usr/lib/x86_64-linux-gnu
platform.hdf.lib=/usr/lib/x86_64-linux-gnu
ci.build=true
security.scan=true
EOF
- name: OWASP Dependency Check
run: |
echo "::group::OWASP Dependency Vulnerability Check"
mvn org.owasp:dependency-check-maven:check \
-Dformat=ALL \
-DfailBuildOnCVSS=7 \
-DsuppressFile=.owasp-suppressions.xml \
-B || echo "Dependency check completed with findings"
echo "::endgroup::"
- name: Parse Dependency Check Results
id: dependency-results
run: |
if [ -f target/dependency-check-report.json ]; then
# Count vulnerabilities by severity
HIGH_VULNS=$(jq '.dependencies[].vulnerabilities[]? | select(.severity == "HIGH")' target/dependency-check-report.json | jq -s length)
MEDIUM_VULNS=$(jq '.dependencies[].vulnerabilities[]? | select(.severity == "MEDIUM")' target/dependency-check-report.json | jq -s length)
LOW_VULNS=$(jq '.dependencies[].vulnerabilities[]? | select(.severity == "LOW")' target/dependency-check-report.json | jq -s length)
echo "high_vulnerabilities=${HIGH_VULNS:-0}" >> $GITHUB_OUTPUT
echo "medium_vulnerabilities=${MEDIUM_VULNS:-0}" >> $GITHUB_OUTPUT
echo "low_vulnerabilities=${LOW_VULNS:-0}" >> $GITHUB_OUTPUT
echo "Vulnerability Summary:"
echo "- High: ${HIGH_VULNS:-0}"
echo "- Medium: ${MEDIUM_VULNS:-0}"
echo "- Low: ${LOW_VULNS:-0}"
else
echo "No dependency check report found"
echo "high_vulnerabilities=0" >> $GITHUB_OUTPUT
echo "medium_vulnerabilities=0" >> $GITHUB_OUTPUT
echo "low_vulnerabilities=0" >> $GITHUB_OUTPUT
fi
- name: Upload Dependency Check Report
uses: actions/upload-artifact@v4
if: always()
with:
name: dependency-check-report-${{ github.run_number }}
path: |
target/dependency-check-report.html
target/dependency-check-report.json
target/dependency-check-report.xml
retention-days: 30
- name: Create Security Summary
run: |
echo "## 🔒 Security Scan Summary" >> $GITHUB_STEP_SUMMARY
echo "| Severity | Count |" >> $GITHUB_STEP_SUMMARY
echo "|----------|-------|" >> $GITHUB_STEP_SUMMARY
echo "| High | ${{ steps.dependency-results.outputs.high_vulnerabilities }} |" >> $GITHUB_STEP_SUMMARY
echo "| Medium | ${{ steps.dependency-results.outputs.medium_vulnerabilities }} |" >> $GITHUB_STEP_SUMMARY
echo "| Low | ${{ steps.dependency-results.outputs.low_vulnerabilities }} |" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "📊 **Report**: Available in build artifacts" >> $GITHUB_STEP_SUMMARY
codeql-analysis:
name: CodeQL Security Analysis
runs-on: ubuntu-latest
timeout-minutes: 30
strategy:
fail-fast: false
matrix:
language: [ 'java' ]
steps:
- name: Checkout Code
uses: actions/checkout@v4
- name: Initialize CodeQL
uses: github/codeql-action/init@v3
with:
languages: ${{ matrix.language }}
config-file: ./.github/codeql/codeql-config.yml
- name: Set up JDK 21
uses: actions/setup-java@v4
with:
java-version: '21'
distribution: 'temurin'
- name: Cache Maven Dependencies
uses: actions/cache@v4
with:
path: ~/.m2/repository
key: ${{ runner.os }}-maven-codeql-${{ hashFiles('**/pom.xml') }}
restore-keys: |
${{ runner.os }}-maven-
- name: Cache HDF Libraries
id: cache-hdf
uses: actions/cache@v4
with:
path: |
${{ github.workspace }}/hdf4
${{ github.workspace }}/hdf5
key: ${{ runner.os }}-hdf-github-${{ github.run_id }}
restore-keys: |
${{ runner.os }}-hdf-github-
- name: Download and Install HDF4 from GitHub
if: steps.cache-hdf.outputs.cache-hit != 'true'
run: |
HDF4_VERSION="4.3.1"
echo "Downloading HDF4 ${HDF4_VERSION} release..."
PATTERN="hdf${HDF4_VERSION}-ubuntu-2404_gcc.tar.gz"
echo "Using pattern $PATTERN"
gh release download hdf${HDF4_VERSION} \
--repo HDFGroup/hdf4 \
--pattern "$PATTERN" \
--clobber
# Extract outer tar.gz (creates hdf4/ directory)
tar -zxvf *-ubuntu-2404_gcc.tar.gz
[ -d hdf4 ] || mv hdf4-* hdf4
# Extract inner tar.gz into hdf4/ directory
cd "${{ github.workspace }}/hdf4"
tar -zxvf HDF-${HDF4_VERSION}-Linux.tar.gz --strip-components 1
# Set HDF4 library path
HDF4LIB_PATH=${{ github.workspace }}/hdf4/HDF_Group/HDF/${HDF4_VERSION}
echo "HDF4LIB_PATH=$HDF4LIB_PATH" >> $GITHUB_ENV
echo "HDF4 installed to: $HDF4LIB_PATH"
ls -la "$HDF4LIB_PATH"
env:
GH_TOKEN: ${{ github.token }}
- name: Download and Install HDF5 from GitHub
if: steps.cache-hdf.outputs.cache-hit != 'true'
run: |
HDF5_VERSION="2.0.0"
echo "Downloading HDF5 ${HDF5_VERSION} release..."
PATTERN="hdf5-${HDF5_VERSION}-ubuntu-2404_gcc.tar.gz"
gh release download ${HDF5_VERSION} \
--repo HDFGroup/hdf5 \
--pattern "$PATTERN" \
--clobber
# Extract outer tar.gz (creates hdf5/ directory)
tar -zxvf $PATTERN
[ -d hdf5 ] || mv hdf5-* hdf5
# Extract inner tar.gz into hdf5/ directory
cd "${{ github.workspace }}/hdf5"
tar -zxvf HDF5-${HDF5_VERSION}-Linux.tar.gz --strip-components 1
# Set HDF5 library path
HDF5LIB_PATH=${{ github.workspace }}/hdf5/HDF_Group/HDF5/${HDF5_VERSION}
echo "HDF5LIB_PATH=$HDF5LIB_PATH" >> $GITHUB_ENV
echo "HDF5 installed to: $HDF5LIB_PATH"
ls -la "$HDF5LIB_PATH"
env:
GH_TOKEN: ${{ github.token }}
- name: Set Environment Variables from Cache
if: steps.cache-hdf.outputs.cache-hit == 'true'
run: |
HDF4DIR=${{ github.workspace }}/hdf4/HDF_Group/HDF/
FILE_NAME_HDF=$(ls $HDF4DIR | head -1)
echo "HDF4LIB_PATH=$HDF4DIR$FILE_NAME_HDF" >> $GITHUB_ENV
HDF5DIR=${{ github.workspace }}/hdf5/HDF_Group/HDF5/
FILE_NAME_HDF5=$(ls $HDF5DIR | head -1)
echo "HDF5LIB_PATH=$HDF5DIR$FILE_NAME_HDF5" >> $GITHUB_ENV
echo "Using cached HDF libraries:"
echo "HDF4: $HDF4DIR$FILE_NAME_HDF"
echo "HDF5: $HDF5DIR$FILE_NAME_HDF5"
- name: Install HDF JARs to Local Maven Repository
run: |
echo "Installing HDF JARs to local Maven repository..."
# Copy JARs to repository directory
mkdir -p repository/lib
cp ${{ env.HDF4LIB_PATH }}/lib/*.jar repository/lib/ 2>/dev/null || echo "No HDF4 JARs found"
cp ${{ env.HDF5LIB_PATH }}/lib/*.jar repository/lib/ 2>/dev/null || echo "No HDF5 JARs found"
# List available JARs
echo "JARs in repository/lib:"
ls -la repository/lib/*.jar 2>/dev/null || echo "No JARs found"
# Install jarhdf5
if [ -f repository/lib/jarhdf5-*.jar ]; then
JAR_FILE=$(ls repository/lib/jarhdf5-*.jar | head -1)
mvn install:install-file -Dfile="$JAR_FILE" \
-DgroupId=jarhdf5 -DartifactId=jarhdf5 -Dversion=2.0.0 \
-Dpackaging=jar -DgeneratePom=true
echo "Installed: $JAR_FILE"
fi
# Install jarhdf
if [ -f repository/lib/jarhdf-*.jar ]; then
JAR_FILE=$(ls repository/lib/jarhdf-*.jar | head -1)
mvn install:install-file -Dfile="$JAR_FILE" \
-DgroupId=jarhdf -DartifactId=jarhdf -Dversion=4.3.1 \
-Dpackaging=jar -DgeneratePom=true
echo "Installed: $JAR_FILE"
fi
# Install fits
if [ -f repository/lib/fits.jar ]; then
mvn install:install-file -Dfile=repository/lib/fits.jar \
-DgroupId=fits -DartifactId=fits -Dversion=1.0.0 \
-Dpackaging=jar -DgeneratePom=true
echo "Installed: fits.jar"
fi
# Install netcdf
if [ -f repository/lib/netcdf.jar ]; then
mvn install:install-file -Dfile=repository/lib/netcdf.jar \
-DgroupId=netcdf -DartifactId=netcdf -Dversion=1.0.0 \
-Dpackaging=jar -DgeneratePom=true
echo "Installed: netcdf.jar"
fi
# Install SWTBot JARs for UI testing (test scope dependencies)
if [ -f repository/lib/org.eclipse.swtbot.swt.finder.jar ]; then
mvn install:install-file -Dfile=repository/lib/org.eclipse.swtbot.swt.finder.jar \
-DgroupId=org.eclipse.local -DartifactId=org.eclipse.swtbot.swt.finder -Dversion=4.2.1 \
-Dpackaging=jar -DgeneratePom=true
echo "Installed: org.eclipse.swtbot.swt.finder.jar"
fi
if [ -f repository/lib/org.eclipse.swtbot.nebula.nattable.finder.jar ]; then
mvn install:install-file -Dfile=repository/lib/org.eclipse.swtbot.nebula.nattable.finder.jar \
-DgroupId=org.eclipse.local -DartifactId=org.eclipse.swtbot.nebula.nattable.finder -Dversion=4.2.1 \
-Dpackaging=jar -DgeneratePom=true
echo "Installed: org.eclipse.swtbot.nebula.nattable.finder.jar"
fi
- name: Set up build.properties
run: |
cat > build.properties << EOF
# HDF5 Configuration
hdf5.lib.dir=${{ env.HDF5LIB_PATH }}/lib
hdf5.plugin.dir=${{ env.HDF5LIB_PATH }}/lib/plugin
# HDF4 Configuration
hdf.lib.dir=${{ env.HDF4LIB_PATH }}/lib
# Platform Configuration
platform.hdf.lib=${{ env.HDF5LIB_PATH }}/lib
# CI-specific settings
ci.build=true
EOF
echo "Generated build.properties:"
cat build.properties
- name: Build for CodeQL Analysis
run: |
echo "::group::Building repository module"
# Build repository module (needed for dependencies) but don't install it
mvn compile -pl repository -B -Ddependency-check.skip=true
echo "::endgroup::"
echo "::group::Building for CodeQL analysis"
mvn clean compile -B -DskipTests
echo "::endgroup::"
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v3
with:
category: "/language:${{matrix.language}}"
license-check:
name: License Compliance Check
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- name: Checkout Code
uses: actions/checkout@v4
- name: Set up JDK 21
uses: actions/setup-java@v4
with:
java-version: '21'
distribution: 'temurin'
- name: Cache Maven Dependencies
uses: actions/cache@v4
with:
path: ~/.m2/repository
key: ${{ runner.os }}-maven-license-${{ hashFiles('**/pom.xml') }}
- name: Set up build.properties
run: |
cat > build.properties << EOF
hdf5.lib.dir=/usr/lib/x86_64-linux-gnu
hdf5.plugin.dir=/usr/lib/x86_64-linux-gnu/hdf5/plugins
hdf.lib.dir=/usr/lib/x86_64-linux-gnu
platform.hdf.lib=/usr/lib/x86_64-linux-gnu
ci.build=true
EOF
- name: Generate License Report
run: |
echo "::group::License Analysis"
# Generate dependency tree with licenses
mvn dependency:tree -B > dependency-tree.txt
# Use license plugin if available
mvn license:aggregate-third-party-report -B || echo "License plugin not configured"
echo "::endgroup::"
- name: Check for Prohibited Licenses
run: |
echo "::group::License Compliance Check"
# List of prohibited license patterns (case-insensitive)
PROHIBITED_LICENSES="GPL-2.0|GPL-3.0|AGPL|SSPL|BUSL"
if [ -f dependency-tree.txt ]; then
# Check for prohibited licenses in dependency tree
if grep -iE "$PROHIBITED_LICENSES" dependency-tree.txt; then
echo "❌ Prohibited licenses found!"
echo "PROHIBITED_LICENSES_FOUND=true" >> $GITHUB_ENV
else
echo "✅ No prohibited licenses detected"
echo "PROHIBITED_LICENSES_FOUND=false" >> $GITHUB_ENV
fi
fi
echo "::endgroup::"
- name: Upload License Reports
uses: actions/upload-artifact@v4
if: always()
with:
name: license-reports-${{ github.run_number }}
path: |
dependency-tree.txt
target/generated-sources/license/THIRD-PARTY.txt
retention-days: 30
- name: License Compliance Summary
run: |
echo "## 📜 License Compliance Summary" >> $GITHUB_STEP_SUMMARY
if [ "$PROHIBITED_LICENSES_FOUND" = "true" ]; then
echo "❌ **Status**: Prohibited licenses detected" >> $GITHUB_STEP_SUMMARY
echo "⚠️ Review required before merging" >> $GITHUB_STEP_SUMMARY
else
echo "✅ **Status**: No prohibited licenses found" >> $GITHUB_STEP_SUMMARY
fi
echo "" >> $GITHUB_STEP_SUMMARY
echo "📋 **Reports**: Available in build artifacts" >> $GITHUB_STEP_SUMMARY
- name: Fail on Prohibited Licenses
if: env.PROHIBITED_LICENSES_FOUND == 'true'
run: |
echo "Build failed due to prohibited licenses"
exit 1