-
Notifications
You must be signed in to change notification settings - Fork 50
153 lines (129 loc) · 6.22 KB
/
update-test-rules.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
name: Add to test-rules Branch
on:
issue_comment:
types: [created]
jobs:
pre-checks:
name: Initial Checks
permissions:
contents: read
issues: read
pull-requests: read
checks: read
runs-on: ubuntu-20.04
# https://docs.github.com/en/webhooks-and-events/webhooks/webhook-events-and-payloads#issue_comment
if: github.event.issue.pull_request && contains(github.event.comment.body, '/update-test-rules')
steps:
# This isn't our only gating, but it's a convenient first restriction.
# The GitHub token can't have expanded permissions like reading private org or team info, so this requires org
# members to be public (most of us are).
# TheModdingInquisition/[email protected] could be used for a team check, but we'd need to create a PAT for it.
- name: Check if commentor is organization member
id: is_organization_member
uses: jamessingleton/[email protected]
with:
organization: sublime-security
username: ${{ github.event.comment.user.login }}
token: ${{ secrets.GITHUB_TOKEN }}
- name: Echo organization member
run: |
echo "[${{ steps.is_organization_member.outputs.result }}]"
- name: Fail if not organization member
if: |
steps.is_organization_member.outputs.result != 'true'
run: exit 1
- name: Fail if PR closed
if: |
github.event.issue.closed_at
run: exit 1
- name: Get PR branch
uses: alessbell/[email protected] # Fork of xt0rted/pull-request-comment-branch, see https://github.com/xt0rted/pull-request-comment-branch/issues/322
id: comment-branch
- name: Wait for Rule Validation Succeed
uses: lewagon/[email protected]
with:
ref: ${{ steps.comment-branch.outputs.head_sha }}
check-name: 'Rule Tests and ID Updated'
repo-token: ${{ secrets.GITHUB_TOKEN }}
wait-interval: 10
add-to-test-branch:
name: Add to test-rules Branch
needs: pre-checks
permissions:
contents: write
issues: read
pull-requests: read
checks: read
runs-on: ubuntu-20.04
environment: test-rules
concurrency: test-rules
steps:
- name: Get PR branch
uses: alessbell/[email protected] # Fork of xt0rted/pull-request-comment-branch, see https://github.com/xt0rted/pull-request-comment-branch/issues/322
id: comment-branch
- name: Checkout PR branch
uses: actions/checkout@v3
with:
repository: ${{ steps.comment-branch.outputs.head_owner }}/${{ steps.comment-branch.outputs.head_repo }}
ref: ${{ steps.comment-branch.outputs.head_ref }}
fetch-depth: 0
path: source
- name: Install yq
uses: mikefarah/[email protected]
- name: Checkout test-rules
uses: actions/checkout@v3
with:
ref: test-rules
path: destination
- name: Synchronize Test Rules
run: |
export pr_num=${{ github.event.issue.number }}
# Delete any files already referencing this PR. If they're no longer included in the PR this will remove them,
# if they're still included we'll add them back below.
files=$(ls destination/**/*.yml) || true
for file in $files; do
file_pr_num=$(yq '.testing_pr' $file)
if [[ "$pr_num" = "$file_pr_num" ]]; then
rm $file
fi
done
# This workflow is trigerred from an issue comment so we don't automatically have context on what changed in the PR
# TODO: We can only retrieve 100 results, we need to add pagination support.
curl -L \
-o pr_files.json \
-H "Accept: application/vnd.github+json" \
-H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}"\
-H "X-GitHub-Api-Version: 2022-11-28" \
https://api.github.com/repos/sublime-security/sublime-rules/pulls/$pr_num/files?per_page=100
# Any files added/changed/modified will be copied to test-rules
files_changed=$(jq -r '.[] | select(.status == "added" or .status == "modified" or .status == "changed") | .filename' pr_files.json)
# Used to testing_sha key in the rule. If the PR is updated multiple times without changing all files, we'll
# always use the latest sha.
export sha=${{ steps.comment-branch.outputs.head_sha }}
# Copy any file that was added/changed/modified to the destination git folder (we could do this with git checkout
# but it doesn't seem any simpler). And then add testing metadata.
# If multiple PRs modify the same file, only one can be tested. This is solveable, but not something we see often.
for file in $files_changed; do
# Skip any LA rules. We'll ignore these downstream anyway, but best to keep the branch clean.
la_count=$(grep -c 'beta.linkanalysis' source/$file || true)
if [[ "$la_count" != '0' ]]; then
echo "Ignoring $file because of linkanalysis usage"
continue
fi
cp source/$file destination/$file
yq -i '.testing_pr = env(pr_num)' destination/$file
yq -i '.testing_sha = env(sha)' destination/$file
done
echo "Sync from PR#$pr_num" > message.txt
echo "" >> message.txt
echo "${{ github.event.issue.title }} by @${{ github.event.issue.user.login }}" >> message.txt
echo "${{ github.event.issue.pull_request.html_url }}" >> message.txt
echo "Source SHA $sha" >> message.txt
echo "Triggered by @${{ github.event.comment.user.login }}" >> message.txt
echo "${{ github.event.comment.body }}" | awk '/\/update-test-rules/ {p=1; next} p && NF' >> message.txt
cd destination
git add -A
git config --global user.name 'Sublime Rule Testing Bot'
git config --global user.email '[email protected]'
git commit --allow-empty -F ../message.txt
git push origin test-rules