Skip to content

Commit 8e21a63

Browse files
author
testcafe-build-bot
committed
🔄 synced local '.github/workflows/' with remote 'workflows/'
1 parent 2f9439a commit 8e21a63

1 file changed

Lines changed: 107 additions & 0 deletions

File tree

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
name: Check security alerts
2+
3+
on:
4+
schedule:
5+
- cron: "30 1 * * *"
6+
workflow_dispatch:
7+
8+
jobs:
9+
check:
10+
runs-on: ubuntu-latest
11+
steps:
12+
- uses: actions/github-script@v6
13+
with:
14+
github-token: ${{ secrets.ACTIVE_TOKEN }}
15+
script: |
16+
if (!'${{secrets.SECURITY_ISSUE_REPO}}')
17+
return;
18+
19+
const { owner, repo } = context.repo;
20+
const state = 'open';
21+
const dependabotLabel = 'dependabot';
22+
const codeqlLabel = 'codeql';
23+
const securityLabel = 'security';
24+
25+
async function getDependabotAlerts () {
26+
const dependabotListAlertsUrl = `https://api.github.com/repos/${ owner }/${ repo }/dependabot/alerts?state=${ state }`;
27+
const dependabotRequestOptions = {
28+
headers: { 'Authorization': 'Bearer ${{ secrets.ACTIVE_TOKEN }}' }
29+
}
30+
31+
const response = await fetch(dependabotListAlertsUrl, dependabotRequestOptions);
32+
const data = await response.json();
33+
34+
// If data isn't arry somethig goes wrong
35+
if (Array.isArray(data))
36+
return data;
37+
38+
return [];
39+
}
40+
41+
async function getCodeqlAlerts () {
42+
// When CodeQL is turned of it throws error
43+
try {
44+
const { data } = await github.rest.codeScanning.listAlertsForRepo({ owner, repo, state });
45+
46+
return data;
47+
} catch (_) {
48+
return [];
49+
}
50+
}
51+
52+
async function createIssue ({owner, repo, labels, summary, description, link, package = ''}) {
53+
const title = `[${repo}] ${summary}`;
54+
const body = ''
55+
+ `#### Repository: \`${ repo }\`\n`
56+
+ (!!package ? `#### Package: \`${ package }\`\n` : '')
57+
+ `#### Description:\n`
58+
+ `${ description }\n`
59+
+ `#### Link: ${ link }`
60+
61+
return github.rest.issues.create({ owner, repo, title, body, labels });
62+
}
63+
64+
function needCreateIssue (alert) {
65+
return !issueDictionary[alert.html_url]
66+
&& Date.now() - new Date(alert.updated_at) <= 1000 * 60 * 60 * 24;
67+
}
68+
69+
const dependabotAlerts = await getDependabotAlerts();
70+
const codeqlAlerts = await getCodeqlAlerts();
71+
const {data: existedIssues} = await github.rest.issues.listForRepo({ owner, repo, labels: [securityLabel], state });
72+
73+
const issueDictionary = existedIssues.reduce((res, issue) => {
74+
const alertUrl = issue.body.match(/Link:\s*(https.*\d*)/)?.[1];
75+
76+
if (alertUrl)
77+
res[alertUrl] = issue;
78+
79+
return res;
80+
}, {})
81+
82+
dependabotAlerts.forEach(alert => {
83+
if (!needCreateIssue(alert))
84+
return;
85+
86+
createIssue({ owner,
87+
repo: '${{ secrets.SECURITY_ISSUE_REPO }}',
88+
labels: [dependabotLabel, securityLabel],
89+
summary: alert.security_advisory.summary,
90+
description: alert.security_advisory.description,
91+
link: alert.html_url,
92+
package: alert.dependency.package.name
93+
})
94+
});
95+
96+
codeqlAlerts.forEach(alert => {
97+
if (!needCreateIssue(alert))
98+
return;
99+
100+
createIssue({ owner,
101+
repo: '${{ secrets.SECURITY_ISSUE_REPO }}',
102+
labels: [codeqlLabel, securityLabel],
103+
summary: alert.rule.description,
104+
description: alert.most_recent_instance.message.text,
105+
link: alert.html_url,
106+
})
107+
});

0 commit comments

Comments
 (0)