-
Notifications
You must be signed in to change notification settings - Fork 0
205 lines (171 loc) · 7.27 KB
/
dependency-scan.yml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
name: Dependency Scan
on:
schedule:
- cron: '0 0 * * 1' # Run weekly on Monday at midnight UTC
workflow_dispatch:
inputs:
org_name:
description: 'GitHub Organization Name (optional)'
required: false
repo_list:
description: 'Comma-separated list of repositories (optional)'
required: false
log_level:
description: 'Logging level'
required: false
type: choice
options:
- INFO
- DEBUG
- WARNING
- ERROR
default: 'INFO'
vulnerability_threshold:
description: 'Number of vulnerabilities to trigger issue creation'
required: false
type: number
default: 10
permissions:
security-events: read
contents: write # Needed for committing the report
issues: write # Needed for creating issues
jobs:
scan:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
repository: ${{ github.repository_owner }}/.github # Checkout .github repo
ref: main # Or your default branch
token: ${{ secrets.DEPENDENCY_SCAN_TOKEN }} # Use a PAT or GitHub App token with appropriate permissions!
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.10'
cache: 'pip'
cache-dependency-path: scripts/requirements.txt
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install requests
- name: Generate timestamp
id: timestamp
run: echo "timestamp=$(date +%Y%m%d_%H%M%S)" >> $GITHUB_OUTPUT
- name: Run dependency scan
id: run-scan
env:
GITHUB_TOKEN: ${{ secrets.DEPENDENCY_SCAN_TOKEN }}
ORG_NAME: ${{ github.event.inputs.org_name || github.repository_owner }}
REPO_LIST: ${{ github.event.inputs.repo_list }}
REPORT_FILE: "vulnerability_report_${{ steps.timestamp.outputs.timestamp }}.csv"
run: |
COMMAND="python scripts/dependency_scanner.py \
--token $GITHUB_TOKEN \
--output $REPORT_FILE \
--log-level ${{ github.event.inputs.log_level || 'INFO' }} \
--max-workers ${{ github.event.inputs.max_workers || 10 }} \
--max-retries 3"
if [[ -n "$ORG_NAME" ]]; then
COMMAND="$COMMAND --org $ORG_NAME"
fi
if [[ -n "$REPO_LIST" ]]; then
COMMAND="$COMMAND --repo-list $REPO_LIST"
fi
$COMMAND
echo "report_path=reports/$REPORT_FILE" >> $GITHUB_OUTPUT
- name: Check for No Repositories
id: check-repos
if: success()
run: |
if grep -q "__NO_REPOS__" ${{ steps.run-scan.outputs.report_path }}/../output.txt; then
echo "No repositories found in the organization. Exiting."
exit 1
fi
- name: Process report statistics (inline)
id: stats
if: success() && steps.check-repos.outcome == 'success'
run: |
STATS=$(grep "__STATS_START__" ${{ steps.run-scan.outputs.report_path }}/../output.txt | sed 's/__STATS_START__//' | sed 's/__STATS_END__//')
echo "total_vulnerabilities=$(echo $STATS | cut -d',' -f1 | cut -d'=' -f2)" >> $GITHUB_OUTPUT
echo "processed_repos=$(echo $STATS | cut -d',' -f2 | cut -d'=' -f2)" >> $GITHUB_OUTPUT
echo "Total vulnerabilities found: $(echo $STATS | cut -d',' -f1 | cut -d'=' -f2)"
echo "Processed repos: $(echo $STATS | cut -d',' -f2 | cut -d'=' -f2)"
- name: Create summary issue (using github-script)
if: success() && steps.check-repos.outcome == 'success' && steps.stats.outputs.total_vulnerabilities > inputs.vulnerability_threshold
uses: actions/github-script@v7
with:
script: |
const stats = {
total: '${{ steps.stats.outputs.total_vulnerabilities }}',
processedRepos: '${{ steps.stats.outputs.processed_repos }}',
};
const now = new Date();
const formattedDate = now.toLocaleDateString('en-US', {
year: 'numeric',
month: 'long',
day: 'numeric'
});
const body = `
# Dependency Vulnerability Report Summary
Report generated on: ${now.toISOString()}
## Statistics
- Total vulnerabilities found: ${stats.total}
- Repositories processed: ${stats.processedRepos}
## Details
- Report artifact: [Download report](${context.serverUrl}/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId})
- Workflow run: [View details](${context.serverUrl}/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId})
## Configuration
- Log level: ${{ github.event.inputs.log_level || 'INFO' }}
- Vulnerability threshold: ${{ github.event.inputs.vulnerability_threshold || '10'}}
`;
await github.rest.issues.create({
owner: context.repo.owner,
repo: context.repo.repo,
title: \`⚠️ Dependency Vulnerability Report - \${formattedDate}\`,
body: body,
labels: ['dependency-vulnerability', 'report']
});
- name: Commit and Push Report
if: success() && steps.check-repos.outcome == 'success'
uses: stefanzweifel/git-auto-commit-action@v5
with:
commit_message: "Add dependency vulnerability report: ${{ steps.timestamp.outputs.timestamp }}"
repository: ./ # Commit to the root of the checked-out repo
file_pattern: reports/*.csv
commit_user_name: GitHub Actions
commit_user_email: [email protected]
commit_author: ${{ github.actor }} <${{ github.actor }}@users.noreply.github.com>
push_options: '--force'
token: ${{ secrets.DEPENDENCY_SCAN_TOKEN }}
- name: Notify on failure
if: failure()
uses: actions/github-script@v7
with:
script: |
const body = `
# 🚨 Dependency Vulnerability Report Generation Failed
Workflow run failed at ${new Date().toISOString()}
## Details
- Run ID: \`${context.runId}\`
- Trigger: ${context.eventName}
- Actor: @${context.actor}
## Links
- [View run details](${context.serverUrl}/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId})
- [View workflow file](${context.serverUrl}/${context.repo.owner}/${context.repo.repo}/blob/main/.github/workflows/dependency-scan.yml)
Please check the workflow logs for detailed error information.
`;
await github.rest.issues.create({
owner: context.repo.owner,
repo: context.repo.repo,
title: '🚨 Dependency Vulnerability Report Generation Failed',
body: body,
labels: ['dependency-vulnerability', 'failed']
});
- name: Clean up
if: always()
run: |
echo "No clean up required."
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true