-
-
Notifications
You must be signed in to change notification settings - Fork 564
222 lines (184 loc) · 8.31 KB
/
check_required_files.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
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
#/
# @license Apache-2.0
#
# Copyright (c) 2022 The Stdlib Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#/
# Workflow name:
name: check_required_files
# Workflow triggers:
on:
# Trigger the workflow when a PR review is requested:
pull_request_target:
types: [review_requested]
# Workflow jobs:
jobs:
# Define a job for checking that pull requests contain the required files...
check_required_files:
# Define a display name:
name: 'Check Required Files'
# Define the type of virtual host machine:
runs-on: ubuntu-latest
# Define the sequence of job steps...
steps:
# Checkout the repository:
- name: 'Checkout repository'
uses: actions/checkout@v3
with:
# Specify whether to remove untracked files before checking out the repository:
clean: true
# Refers to the development branch:
ref: 'develop'
# Refers to the repository name of the pull request:
repository: ${{ github.event.pull_request.head.repo.full_name }}
# Limit clone depth to the most recent commit:
fetch-depth: 1
# Specify whether to download Git-LFS files:
lfs: false
timeout-minutes: 10
# Check if the review is requested from the `stdlib-bot` user:
- name: 'Check if review is requested from stdlib-bot'
id: check-reviewers
run: |
# Get the list of reviewers:
reviewers=$(jq -r '.pull_request.requested_reviewers | .[] | .login' "$GITHUB_EVENT_PATH")
# Check if the list of reviewers contains the `stdlib-bot` user:
if [[ $reviewers == *"stdlib-bot"* ]]; then
echo "is_stdlib_bot=true" >> $GITHUB_OUTPUT
else
echo "is_stdlib_bot=false" >> $GITHUB_OUTPUT
fi
# Configure git:
- name: 'Configure git'
if: steps.check-reviewers.outputs.is_stdlib_bot == 'true'
run: |
git config --local user.email "noreply@stdlib.io"
git config --local user.name "stdlib-bot"
git fetch --all
# Get list of added files:
- name: 'Get list of added files'
if: steps.check-reviewers.outputs.is_stdlib_bot == 'true'
id: added-files
run: |
page=1
files=""
while true; do
new_files=$(curl -s -H "Accept: application/vnd.github.v3+json" -H "Authorization: Bearer ${{ secrets.STDLIB_BOT_GITHUB_TOKEN }}" "https://api.github.com/repos/stdlib-js/stdlib/pulls/${{ github.event.pull_request.number }}/files?page=$page&per_page=100" | jq -r '.[] | select(.status == "added") | .filename')
if [ -z "$new_files" ]; then
break
fi
files="$files $new_files"
page=$((page+1))
done
files=$(echo "$files" | tr '\n' ' ' | sed 's/ $//')
echo "files=${files}" >> $GITHUB_OUTPUT
# Check whether the pull request contains a new `README.md` file; if not, exit with a non-zero exit code:
- name: 'Exit if pull request does not contain a new README.md file'
if: steps.check-reviewers.outputs.is_stdlib_bot == 'true'
run: |
if [[ ! "${{ steps.added-files.outputs.files }}" =~ "README.md" ]]; then
echo "Pull request does not contain a new README.md file."
exit 1
fi
# Check whether the pull request contains files which are required to be present for all packages:
- name: 'Check whether the pull request contains files which are required to be present for all packages'
if: steps.check-reviewers.outputs.is_stdlib_bot == 'true'
id: check-required-files
run: |
# Define a list of required files:
required_files=(
"package.json"
"README.md"
"docs/repl.txt"
"docs/types/index.d.ts"
"docs/types/test.ts"
"lib/index.js"
"lib/main.js"
"benchmark/benchmark.js"
"examples/index.js"
"test/test.js"
)
# Get path of first added `README.md` file:
readme_path=$(echo "${{ steps.added-files.outputs.files }}" | tr ' ' '\n' | grep -E 'README.md$' | head -n 1)
if grep -q '## CLI' "${readme_path}"; then
required_files+=("bin/cli")
required_files+=("docs/usage.txt")
required_files+=("etc/cli_opts.json")
required_files+=("test/test.cli.js")
fi
if grep -q '## C APIs' "${readme_path}"; then
required_files+=("manifest.json")
required_files+=("binding.gyp")
required_files+=("include.gypi")
required_files+=("src/Makefile")
required_files+=("include/stdlib")
fi
if grep -q '### Examples\n\n```c' "${readme_path}"; then
required_files+=("examples/c/example.c")
required_files+=("examples/c/Makefile")
required_files+=("benchmark/c/Makefile")
required_files+=("benchmark/c/benchmark.c")
fi
# Define a list of missing files:
missing_files=()
# Define a string with a Markdown list of checkboxes for all files:
checkbox_list=""
# Iterate over the list of required files:
for file in "${required_files[@]}"; do
# Check whether the file is present in the pull request:
if [[ ! "${{ steps.added-files.outputs.files }}" =~ "${file}" ]]; then
# If not, add the file to the list of missing files:
missing_files+=("${file}")
# Add a non-ticked checkbox for the file to the Markdown list of checkboxes:
checkbox_list+="- [ ] ${file}"
else
# Add a ticked checkbox for the file to the Markdown list of checkboxes:
checkbox_list+="- [x] ${file}"
fi
# Add a newline to the Markdown list of checkboxes:
checkbox_list+="
"
done
# Add the list of missing and required files to the workflow output:
echo "missing_files=${missing_files[*]}" >> $GITHUB_OUTPUT
echo "required_files=${required_files[*]}" >> $GITHUB_OUTPUT
body=""
if [[ "${#missing_files[@]}" -eq 0 ]]; then
body="Hi @${{ github.event.pull_request.user.login }}, thank you for your contribution!
:tada: Your pull request contains all required files for the new package: :tada:
${checkbox_list}
-- stdlib-bot"
else
body="Hi @${{ github.event.pull_request.user.login }}, thank you for your contribution! Your pull request contains a new package, but is missing some of the required files.
Use the following checklist to keep track of the required files and which ones are still missing:
${checkbox_list}
Please add the missing files to the pull request.
-- stdlib-bot"
fi
# Add the comment body to the workflow output after escaping to preserve newlines:
body="${body//'%'/'%25'}"
body="${body//$'\n'/'%0A'}"
body="${body//$'\r'/'%0D'}"
echo "comment-body=${body}" >> $GITHUB_OUTPUT
shell: bash
timeout-minutes: 10
# Create a comment on the pull request informing the user whether the pull request is missing required files:
- name: 'Create a comment on the pull request informing the user whether the pull request is missing required files'
if: steps.check-reviewers.outputs.is_stdlib_bot == 'true'
uses: peter-evans/create-or-update-comment@v1
with:
# Specify the issue or pull request number:
issue-number: ${{ github.event.pull_request.number }}
# Specify the comment body:
body: ${{ steps.check-required-files.outputs.comment-body }}