-
Notifications
You must be signed in to change notification settings - Fork 0
190 lines (160 loc) · 5.94 KB
/
fetch-vulnerabilities.yml
File metadata and controls
190 lines (160 loc) · 5.94 KB
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
name: Fetch Vulnerabilities (v3.0)
on:
schedule:
# 北京时间每天 10:00(UTC 02:00)
- cron: '0 2 * * *'
workflow_dispatch:
inputs:
full_refresh:
description: '全量刷新'
required: false
default: 'false'
type: boolean
years:
description: '年份列表(空则使用配置默认)'
required: false
default: ''
type: string
push:
branches:
- main
paths:
- 'app/config.yaml'
- 'app/**/*.py'
- '.github/workflows/fetch-vulnerabilities.yml'
concurrency:
group: fetch-vulnerabilities-${{ github.ref }}
cancel-in-progress: true
env:
TZ: Asia/Shanghai
PYTHON_VERSION: '3.11'
DATA_DIR: public/data
jobs:
fetch-vulnerabilities:
name: Fetch Vulnerabilities
runs-on: ubuntu-latest
timeout-minutes: 30
permissions:
contents: write
packages: read
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0
token: ${{ secrets.GITHUB_TOKEN }}
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: ${{ env.PYTHON_VERSION }}
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r app/requirements.txt
- name: Restore caches
uses: actions/cache@v4
with:
path: |
.cache/fkie/
.cache/osv/
key: ${{ runner.os }}-vuln-cache-${{ hashFiles('app/config.yaml') }}-${{ github.run_id }}
restore-keys: |
${{ runner.os }}-vuln-cache-${{ hashFiles('app/config.yaml') }}-
${{ runner.os }}-vuln-cache-
- name: Determine refresh mode
id: mode
run: |
# 判断刷新模式
# 1. workflow_dispatch 输入优先
# 2. 每月 1 日自动全量
# 3. 其他日期增量更新
if [[ "${{ inputs.full_refresh }}" == "true" ]]; then
echo "mode=full" >> $GITHUB_OUTPUT
echo "🔧 手动触发:全量刷新"
elif [[ "$(date +%d)" == "01" ]]; then
echo "mode=full" >> $GITHUB_OUTPUT
echo "📅 每月 1 日:全量刷新"
else
echo "mode=incremental" >> $GITHUB_OUTPUT
echo "⚡ 日常更新:增量模式"
fi
# 处理年份参数
if [[ -n "${{ inputs.years }}" ]]; then
YEARS="--years ${{ inputs.years }}"
else
YEARS=""
fi
echo "years=${YEARS}" >> $GITHUB_OUTPUT
- name: Fetch vulnerabilities
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
echo "🚀 开始获取漏洞数据($(date +'%Y-%m-%d %H:%M:%S %Z'))"
echo "📋 数据源: fkie-cad (NVD) + OSV.dev"
MODE="${{ steps.mode.outputs.mode }}"
YEARS="${{ steps.mode.outputs.years }}"
# 重试机制
for i in 1 2 3; do
echo "🔄 第 $i 次尝试..."
if [[ "$MODE" == "full" ]]; then
CMD="python app/main.py $YEARS --log-level INFO"
else
CMD="python app/main.py --incremental --log-level INFO"
fi
if eval $CMD; then
echo "✅ 漏洞数据获取成功"
exit 0
else
echo "❌ 第 $i 次尝试失败"
fi
if [ $i -lt 3 ]; then
echo "⏳ 等待 30 秒后重试..."
sleep 30
fi
done
echo "❌ 达到最大重试次数"
exit 1
- name: Commit and push data
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git rm -r --cached .cache/ 2>/dev/null || true
git rm -r --cached cache/ 2>/dev/null || true
git add ${{ env.DATA_DIR }}/
CHANGED=$(git diff --cached --name-only | wc -l)
if [[ "$CHANGED" -eq 0 ]]; then
echo "ℹ️ 数据无变化,跳过提交"
exit 0
fi
TOTAL=$(jq -r '.total_count // 0' ${{ env.DATA_DIR }}/index.json 2>/dev/null || echo 0)
TIMESTAMP=$(date +'%Y-%m-%d %H:%M:%S %Z')
MODE="${{ steps.mode.outputs.mode }}"
git commit -m "chore(data): update vulnerabilities — ${TIMESTAMP}" \
-m "Total: ${TOTAL} vulnerabilities" \
-m "Mode: ${MODE}" \
-m "Sources: fkie-cad + OSV.dev"
git pull --rebase origin ${{ github.ref_name }} || true
git push origin HEAD:${{ github.ref_name }} --force-with-lease
echo "✅ 成功推送 ${CHANGED} 个文件"
- name: Summary
if: always()
run: |
STATUS="${{ job.status }}"
TOTAL=$(jq -r '.total_count // "N/A"' ${{ env.DATA_DIR }}/index.json 2>/dev/null || echo "N/A")
MODE="${{ steps.mode.outputs.mode }}"
echo "## 漏洞数据同步结果" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "| 项目 | 值 |" >> $GITHUB_STEP_SUMMARY
echo "|------|-----|" >> $GITHUB_STEP_SUMMARY
echo "| 状态 | ${STATUS} |" >> $GITHUB_STEP_SUMMARY
echo "| 漏洞总数 | ${TOTAL} |" >> $GITHUB_STEP_SUMMARY
echo "| 刷新模式 | ${MODE} |" >> $GITHUB_STEP_SUMMARY
echo "| 数据来源 | fkie-cad + OSV.dev |" >> $GITHUB_STEP_SUMMARY
echo "| 执行时间 | $(date +'%Y-%m-%d %H:%M:%S %Z') |" >> $GITHUB_STEP_SUMMARY
- name: Upload artifacts on failure
if: failure()
uses: actions/upload-artifact@v4
with:
name: debug-${{ github.run_id }}
path: public/
retention-days: 7