-
Notifications
You must be signed in to change notification settings - Fork 674
109 lines (89 loc) · 3.92 KB
/
check-security-alerts.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
name: Check security alerts
on:
schedule:
- cron: "30 1 * * *"
workflow_dispatch:
jobs:
check:
runs-on: ubuntu-latest
steps:
- uses: actions/github-script@v6
with:
github-token: ${{ secrets.ACTIVE_TOKEN }}
script: |
if (!'${{secrets.SECURITY_ISSUE_REPO}}')
return;
const { owner, repo } = context.repo;
const state = 'open';
const dependabotLabel = 'dependabot';
const codeqlLabel = 'codeql';
const securityLabel = 'security notification';
async function getDependabotAlerts () {
const dependabotListAlertsUrl = `https://api.github.com/repos/${ owner }/${ repo }/dependabot/alerts?state=${ state }`;
const dependabotRequestOptions = {
headers: { 'Authorization': 'Bearer ${{ secrets.ACTIVE_TOKEN }}' }
}
const response = await fetch(dependabotListAlertsUrl, dependabotRequestOptions);
const data = await response.json();
// If data isn't arry somethig goes wrong
if (Array.isArray(data))
return data;
return [];
}
async function getCodeqlAlerts () {
// When CodeQL is turned of it throws error
try {
const { data } = await github.rest.codeScanning.listAlertsForRepo({ owner, repo, state });
return data;
} catch (_) {
return [];
}
}
async function createIssue ({owner, repo, labels, originRepo, summary, description, link, package = ''}) {
const title = `[${originRepo}] ${summary}`;
const body = ''
+ `#### Repository: \`${ originRepo }\`\n`
+ (!!package ? `#### Package: \`${ package }\`\n` : '')
+ `#### Description:\n`
+ `${ description }\n`
+ `#### Link: ${ link }`
return github.rest.issues.create({ owner, repo, title, body, labels });
}
function needCreateIssue (alert) {
return !issueDictionary[alert.html_url]
&& Date.now() - new Date(alert.created_at) <= 1000 * 60 * 60 * 24;
}
const dependabotAlerts = await getDependabotAlerts();
const codeqlAlerts = await getCodeqlAlerts();
const {data: existedIssues} = await github.rest.issues.listForRepo({ owner, repo, labels: [securityLabel], state });
const issueDictionary = existedIssues.reduce((res, issue) => {
const alertUrl = issue.body.match(/Link:\s*(https.*\d*)/)?.[1];
if (alertUrl)
res[alertUrl] = issue;
return res;
}, {})
dependabotAlerts.forEach(alert => {
if (!needCreateIssue(alert))
return;
createIssue({ owner,
repo: '${{ secrets.SECURITY_ISSUE_REPO }}',
labels: [dependabotLabel, securityLabel],
originRepo: repo,
summary: alert.security_advisory.summary,
description: alert.security_advisory.description,
link: alert.html_url,
package: alert.dependency.package.name
})
});
codeqlAlerts.forEach(alert => {
if (!needCreateIssue(alert))
return;
createIssue({ owner,
repo: '${{ secrets.SECURITY_ISSUE_REPO }}',
labels: [codeqlLabel, securityLabel],
originRepo: repo,
summary: alert.rule.description,
description: alert.most_recent_instance.message.text,
link: alert.html_url,
})
});