Skip to content

fix: pin trivy-action and setup-trivy to commit SHAs #6387

fix: pin trivy-action and setup-trivy to commit SHAs

fix: pin trivy-action and setup-trivy to commit SHAs #6387

Workflow file for this run

---
name: CI
on: # yamllint disable-line rule:truthy
pull_request:
branches: ["*"]
push:
branches: ["main"]
concurrency:
group: ci-${{ github.workflow }}-${{ github.actor }}-${{ github.sha }}
cancel-in-progress: true
jobs:
static-analysis:
name: Prospector Static Analysis
runs-on: ubuntu-22.04
env:
DJANGO_SETTINGS_MODULE: onadata.settings.github_actions_test
strategy:
fail-fast: false
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup python
uses: actions/setup-python@v5
with:
python-version: "3.10"
architecture: "x64"
cache: "pip"
cache-dependency-path: |
requirements/base.pip
requirements/dev.pip
requirements/azure.pip
- name: Update apt sources
run: sudo apt-get update
- name: Install APT requirements
run: sudo apt-get install -y --no-install-recommends libjpeg-dev zlib1g-dev software-properties-common ghostscript libxslt1-dev binutils libproj-dev gdal-bin memcached libmemcached-dev libxml2-dev libxslt-dev
- name: Install Pip requirements
env:
ONADEPLOY_GH_TOKEN: ${{ secrets.ONADEPLOY_GH_TOKEN }}
run: |
git config --global \
url."https://x-access-token:${ONADEPLOY_GH_TOKEN}@github.com/".insteadOf \
"https://github.com/"
git config --global --add \
url."https://x-access-token:${ONADEPLOY_GH_TOKEN}@github.com/".insteadOf \
"ssh://git@github.com/"
pip install -U pip
pip install --upgrade wheel setuptools
pip install -r requirements/base.pip
pip install -r requirements/dev.pip
pip install -r requirements/azure.pip
pip install PyYAML django-redis ${{ secrets.ECR_OPTIONAL_PACKAGES }}
- name: Install linting tools
run: pip install prospector==1.14.1 pylint==3.3.4
- name: Run Prospector
run: prospector -X -s veryhigh onadata
unit-tests:
strategy:
fail-fast: false
matrix:
test_path:
- [
" Django Unit Tests (Libraries, Main, RestServices, SMS Support, Viewer, Messaging)",
"python manage.py test onadata/libs onadata/apps/main onadata/apps/restservice onadata/apps/sms_support onadata/apps/viewer onadata/apps/messaging --noinput --timing --settings=onadata.settings.github_actions_test --verbosity=2 --parallel=4",
]
- [
"Django Unit Tests API",
"python manage.py test onadata/apps/api --noinput --timing --settings=onadata.settings.github_actions_test --verbosity=2 --parallel=4",
]
- [
"Django Unit Tests Logger",
"python manage.py test onadata/apps/logger --noinput --timing --settings=onadata.settings.github_actions_test --verbosity=2 --parallel=4",
]
name: "${{ matrix.test_path[0] }}"
runs-on: ubuntu-22.04
needs: static-analysis
env:
DJANGO_SETTINGS_MODULE: onadata.settings.github_actions_test
services:
postgres:
image: postgis/postgis:15-3.5
env:
POSTGRES_PASSWORD: onadata
POSTGRES_DB: onadata
POSTGRES_USER: onadata
ports:
- 5432:5432
# Set health checks to wait until postgres has started
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Java
uses: actions/setup-java@v4
with:
distribution: "adopt"
java-version: "8"
- name: Setup python
uses: actions/setup-python@v5
with:
python-version: "3.10"
architecture: "x64"
cache: "pip"
cache-dependency-path: |
requirements/base.pip
requirements/dev.pip
requirements/azure.pip
- name: Update apt sources
run: sudo apt-get update
- name: Install APT requirements
run: sudo apt-get install -y --no-install-recommends libjpeg-dev zlib1g-dev software-properties-common ghostscript libxslt1-dev binutils libproj-dev gdal-bin memcached libmemcached-dev libxml2-dev libxslt-dev
- name: Install Pip requirements
env:
ONADEPLOY_GH_TOKEN: ${{ secrets.ONADEPLOY_GH_TOKEN }}
run: |
git config --global \
url."https://x-access-token:${ONADEPLOY_GH_TOKEN}@github.com/".insteadOf \
"https://github.com/"
git config --global --add \
url."https://x-access-token:${ONADEPLOY_GH_TOKEN}@github.com/".insteadOf \
"ssh://git@github.com/"
pip install -U pip
pip install --upgrade wheel setuptools
pip install -r requirements/base.pip
pip install -r requirements/dev.pip
pip install -r requirements/azure.pip
pip install PyYAML django-redis ${{ secrets.ECR_OPTIONAL_PACKAGES }}
- name: Run tests
run: |
${{ matrix.test_path[1] }}
security-check:
name: Trivy Security Checks
runs-on: ubuntu-24.04
steps:
- name: Check if repository is public
id: check_visibility
run: echo "IS_PUBLIC_REPO=$(if [ ${{ github.event.repository.private }} = false ]; then echo true; else echo false; fi)" >> $GITHUB_ENV
- name: Checkout code
uses: actions/checkout@v4
- name: Update apt sources
run: sudo apt-get update
- name: Docker meta
id: meta
uses: docker/metadata-action@v5
with:
images: onaio/onadata
tags: |
type=ref,event=branch
type=ref,event=pr
- name: Build Docker image
uses: docker/build-push-action@v6
with:
context: .
file: ./docker/onadata-uwsgi/Dockerfile.ubuntu
platforms: linux/amd64
push: false
tags: ${{ steps.meta.outputs.tags }}
cache-from: type=registry,ref=${{ steps.meta.outputs.tags }}
cache-to: type=inline
secrets: |
ONADEPLOY_GH_TOKEN=${{ secrets.ONADEPLOY_GH_TOKEN }}
build-args: |
optional_packages=PyYAML django-redis ${{ secrets.ECR_OPTIONAL_PACKAGES }}
- name: Install Trivy
uses: aquasecurity/setup-trivy@3fb12ec12f41e471780db15c232d5dd185dcb514 # v0.2.6
if: github.event_name == 'pull_request' || github.event_name == 'push'
with:
version: v0.69.1
cache: true
- name: Configure Trivy VEX Hub with DHI advisories
if: github.event_name == 'pull_request' || github.event_name == 'push'
run: |
mkdir -p ~/.trivy/vex
cat > ~/.trivy/vex/repository.yaml << 'EOF'
repositories:
- name: default
url: https://github.com/aquasecurity/vexhub
enabled: true
- name: dhi-vex
url: https://github.com/docker-hardened-images/advisories
enabled: true
EOF
trivy vex repo download
- name: Run Trivy vulnerability scanner
uses: aquasecurity/trivy-action@57a97c7e7821a5776cebc9bb87c984fa69cba8f1 # v0.35.0
if: github.event_name == 'pull_request' || github.event_name == 'push'
with:
version: "v0.69.1"
image-ref: ${{ steps.meta.outputs.tags }}
format: sarif
ignore-unfixed: false
severity: "CRITICAL,HIGH"
scanners: "vuln"
output: "trivy_results.sarif"
trivy-config: trivy.yaml
- name: Cache Trivy HTML template
id: cache-template
uses: actions/cache@v4
if: github.event_name == 'pull_request' || github.event_name == 'push'
with:
path: html.tpl
key: trivy-html-template-v1
- name: Download Trivy HTML template
if: >-
(github.event_name == 'pull_request' || github.event_name == 'push')
&& steps.cache-template.outputs.cache-hit != 'true'
run: |
url="https://raw.githubusercontent.com"
url+="/aquasecurity/trivy/main/contrib/html.tpl"
wget -q "$url" -O html.tpl
- name: Run Trivy vulnerability scanner (HTML report)
uses: aquasecurity/trivy-action@57a97c7e7821a5776cebc9bb87c984fa69cba8f1 # v0.35.0
if: github.event_name == 'pull_request' || github.event_name == 'push'
with:
version: "v0.69.1"
image-ref: ${{ steps.meta.outputs.tags }}
format: "template"
template: "@html.tpl"
ignore-unfixed: false
severity: "CRITICAL,HIGH"
scanners: "vuln"
output: "trivy_results.html"
trivy-config: trivy.yaml
- name: Upload Trivy SARIF as artifact
uses: actions/upload-artifact@v4
if: github.event_name == 'pull_request' || github.event_name == 'push'
with:
name: trivy-sarif-results
path: trivy_results.sarif
retention-days: 30
- name: Upload Trivy HTML report as artifact
uses: actions/upload-artifact@v4
if: github.event_name == 'pull_request' || github.event_name == 'push'
with:
name: trivy-html-report
path: trivy_results.html
retention-days: 30
- name: Upload vulnerability scan results
uses: github/codeql-action/upload-sarif@v4
if: (github.event_name == 'push' || github.event_name == 'pull_request') && env.IS_PUBLIC_REPO == 'true'
with:
sarif_file: "trivy_results.sarif"
- name: Create summary of trivy issues
if: github.event_name == 'push' || github.event_name == 'pull_request'
run: |
summary=$(jq -r '.runs[0].tool.driver.rules as $rules | [.runs[0].results[] | $rules[.ruleIndex].properties.tags[] | select(. == "HIGH" or . == "CRITICAL" or . == "MEDIUM" or . == "LOW" or . == "UNKNOWN")] | group_by(.) | map({Severity: .[0], Count: length}) | .[] | [.Severity, .Count] | join(": ")' trivy_results.sarif | awk 'NR > 1 { printf(" | ") } {printf "%s",$0}')
if [ -z "$summary" ]
then
summary="0 Issues"
fi
echo "SUMMARY=$summary" >> $GITHUB_ENV
- name: Extract detailed vulnerabilities
if: github.event_name == 'push' || github.event_name == 'pull_request'
run: |
details=$(jq -r '
.runs[0].tool.driver.rules as $rules |
[.runs[0].results[] |
. as $result |
$rules[.ruleIndex] as $rule |
($rule.properties.tags[] |
select(. == "CRITICAL" or . == "HIGH")) as $severity |
{
result: $result,
rule: $rule,
severity: $severity
}
] |
sort_by(if .severity == "CRITICAL" then 0 else 1 end) |
.[0:10] |
map(
.result as $result |
.rule as $rule |
.severity as $severity |
($result.locations[0].message.text | split(":")[0] |
if contains("site-packages/") then
split("site-packages/")[1]
elif contains("usr/lib/") then
split("usr/lib/")[1]
else
(split("/") | .[-4:] | join("/"))
end) as $location |
($result.message.text |
capture("Package: (?<pkg>[^\n]+)") | .pkg) as $package |
($result.message.text |
capture("Installed Version: (?<ver>[^\n]+)") |
.ver) as $installed |
($result.message.text |
capture("Fixed Version: ?(?<fix>[^\n]*)") |
.fix) as $rawfixed |
(if $rawfixed == "" then "Not available"
else $rawfixed end) as $fixed |
(if $severity == "CRITICAL" then "🔴"
elif $severity == "HIGH" then "🟠"
else "⚪" end) as $icon |
"\($icon) *\($result.ruleId)* (\($severity))\n" +
"Package: `\($package)@\($installed)`\n" +
"Location: `\($location)`\n" +
"Fixed: `\($fixed)`\n" +
"<\($rule.helpUri)|View Details>\n"
) | join("\n")
' trivy_results.sarif)
if [ -z "$details" ]
then
details="No vulnerabilities found in the scanned severity levels."
fi
# Escape for GitHub Actions environment
echo "DETAILS<<EOF" >> $GITHUB_ENV
echo "$details" >> $GITHUB_ENV
echo "EOF" >> $GITHUB_ENV
- name: Send Slack Notification
uses: slackapi/slack-github-action@v1.23.0
if: github.event_name == 'push' || github.event_name == 'pull_request'
with:
payload: |
{
"text": "Trivy scan results for ${{ github.head_ref || github.base_ref || env.version }}",
"blocks": [
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "[Ona Data] Trivy scan results for ${{ github.head_ref || github.base_ref || env.version }}: ${{ env.SUMMARY }}"
}
},
{
"type": "divider"
},
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "🔍 *Found Vulnerabilities (Top 10):*"
}
},
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": ${{ toJSON(env.DETAILS) }}
}
},
{
"type": "divider"
},
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "📊 *View Full Reports:*\n• <https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}|Download HTML Report>\n• <https://github.com/${{ github.repository }}/security/code-scanning?query=branch:${{ github.head_ref || github.base_ref || env.version }}+is:open++|GitHub Code Scanning>"
}
}
]
}
env:
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
SLACK_WEBHOOK_TYPE: INCOMING_WEBHOOK