-
Notifications
You must be signed in to change notification settings - Fork 36
306 lines (265 loc) · 11.3 KB
/
test.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
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
name: Tests
on:
push:
pull_request:
jobs:
changes:
name: Check if back-end or front-end files changed
# Don't run this for pushes generated by push.yml on weblate-localization
# branch → prevents an infinite loop of actions triggering actions
#
# Also, "push" event is not triggered for forks, so need to listen for
# pull_requests, but only for external ones, so as not to run the action
# twice
if: |
github.event.head_commit.committer.name != 'Hosted Weblate' &&
github.event.head_commit.committer.name != 'github-actions' &&
(
github.event_name != 'pull_request' ||
github.event.pull_request.head.repo.fork == true
)
runs-on: ubuntu-latest
outputs:
backend_changed: ${{ steps.back-end-check.outputs.changed }}
frontend: ${{ steps.filter.outputs.frontend }}
frontend_changes: ${{ steps.filter.outputs.frontend_files }}
steps:
- uses: actions/checkout@v4
- name: Find all changed files
uses: dorny/paths-filter@v3
id: filter
with:
base: ${{ github.ref }}
list-files: escape
filters: |
frontend:
- 'specifyweb/frontend/**'
backend:
- '**'
- name: Check if any non-front-end files changed
id: back-end-check
run: |
changed_files=`echo "${{steps.filter.outputs.backend_files}}" | tr " " "\n" | grep -v 'specifyweb/frontend/' || echo ""`
echo "Changed back-end files: ${changed_files}"
echo "changed=$([[ -z "${changed_files}" ]] && echo "" || echo "1")" >> $GITHUB_OUTPUT
test-back-end:
name: Run back-end tests
needs: changes
if: needs.changes.outputs.backend_changed
runs-on: ubuntu-latest
services:
mariadb:
image: mariadb:latest
ports:
- 3306
env:
MYSQL_USER: MasterUser
MYSQL_PASSWORD: MasterPassword
MYSQL_DATABASE: test_SpecifyDB
MYSQL_ROOT_PASSWORD: password
options:
--health-cmd="mariadb-admin ping" --health-interval=5s
--health-timeout=2s --health-retries=3
steps:
- uses: actions/checkout@v4
- name: Get Specify 6 from cache
id: cache-specify6
uses: actions/cache@v3
with:
path: Specify6
key: specify6.8.02-cache
- name: Install Specify 6
if: steps.cache-specify6.outputs.cache-hit != 'true'
run: |
wget https://update.specifysoftware.org/6802/Specify_unix_64.sh
sh Specify_unix_64.sh -q -dir ./Specify6
- name:
Patch Specify datamodel (Sam, you made the Attachment.origFilename too
long)
run:
sed -i 's/name="origFilename"
type="java.lang.String"/name="origFilename" type="text"/'
./Specify6/config/specify_datamodel.xml
- name: Install ubuntu dependencies
run: |
sudo apt update
sudo apt install -y libmysqlclient-dev libsasl2-dev libldap2-dev libssl-dev
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v4
with:
python-version: 3.8
- name: Install python dependencies
run: |
python -m pip install --upgrade pip
python -m venv ve
ve/bin/pip install -r requirements.txt
- name: Install testing python dependencies
run: ve/bin/pip install -r requirements-testing.txt
- name: Create settings file
run: |
echo "THICK_CLIENT_LOCATION = '${{ github.workspace }}/Specify6'" >> specifyweb/settings/local_specify_settings.py
echo "DATABASE_HOST = '127.0.0.1'" >> specifyweb/settings/local_specify_settings.py
echo "DATABASE_PORT = ${{ job.services.mariadb.ports[3306] }}" >> specifyweb/settings/local_specify_settings.py
- name: Need these files to be present
run:
make specifyweb/settings/build_version.py
specifyweb/settings/secret_key.py
- name: Verify MariaDB connection
env:
PORT: ${{ job.services.mariadb.ports[3306] }}
run: |
while ! mysqladmin ping -h"127.0.0.1" -P"$PORT" --silent; do
sleep 1
done
- name: Run Mypy type checker
run: VIRTUAL_ENV=./ve make typecheck
# - name: Delete existing test database (if any). Use if database is corrupted
# env:
# PORT: ${{ job.services.mariadb.ports[3306] }}
# run: |
# mysql -h 127.0.0.1 -P $PORT -u MasterUser -p'MasterPassword' -e 'DROP DATABASE IF EXISTS test_SpecifyDB;';
# mysql -h 127.0.0.1 -P $PORT -u MasterUser -p'MasterPassword' -e 'SHOW DATABASES;'
- name: Run test suite
run: ./ve/bin/python manage.py test --verbosity=3 --keepdb
# run: ./ve/bin/python manage.py test --verbosity=3 --noinput
test-front-end:
name: Run front-end tests
needs: changes
if: ${{ needs.changes.outputs.frontend == 'true' }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
# Using a Personal Access Token from an admin account to bypass branch
# protection rules and allow direct pushes to production. Inspirited
# by: https://github.com/community/community/discussions/13836
token: ${{ secrets.TESTS_PUSH_TO_GITHUB }}
- uses: actions/setup-node@v4
with:
node-version-file: specifyweb/frontend/js_src/package.json
cache: 'npm'
cache-dependency-path: specifyweb/frontend/js_src/package-lock.json
- name: Build frontend
run: make frontend
# See https://jestjs.io/docs/troubleshooting#tests-are-extremely-slow-on-docker-andor-continuous-integration-ci-server
- name: Get number of CPU cores
id: cpu-cores
uses: SimenB/github-actions-cpu-cores@v1
- name: Run JS test suite
working-directory: specifyweb/frontend/js_src
run: |
npm run typecheck && \
npm run unitTests -- --maxWorkers ${{ steps.cpu-cores.outputs.count }}
- name: Clone branch that stores localization strings
# Listen for changes to production branch
if:
github.ref == format('refs/heads/{0}',
github.event.repository.default_branch)
id: weblate
uses: actions/checkout@v3
with:
path: weblate-localization
ref: weblate-localization
fetch-depth: 0
- name: Localization Tests
working-directory: specifyweb/frontend/js_src
run: |
npm run localizationTests -- --emit ../../../weblate-localization/strings
- name: Sync localization strings with Weblate (only on production branch)
if:
github.ref == format('refs/heads/{0}',
github.event.repository.default_branch)
working-directory: weblate-localization
run: |
git add strings
if git diff-index --quiet HEAD --; then
echo "Localization strings are unchanged"
else
git config --local user.name "github-actions"
git config --local user.email "41898282+github-actions[bot]@users.noreply.github.com"
# Set the committer to the name and email of the person who
# triggered the action
git commit \
--author '${{ github.event.head_commit.author.name }} <${{ github.event.head_commit.author.email }}>' \
-m 'Sync localization strings with Weblate' \
-m "Triggered by ${{ github.sha }} on branch ${{ github.ref }}"
git push
fi
# This step must be run after pushing to github or else it will fail in
# cases when new components are to be created (Weblate requires files to
# be pushed before component can be created)
- name: Make sure Weblate settings are up to date
# Only run this step if previous step was not skipped
if: steps.weblate.outcome == 'success'
working-directory: specifyweb/frontend/js_src
env:
WEBLATE_API_TOKEN: ${{ secrets.WEBLATE_API_TOKEN }}
run: npm run validateWeblate
- name: Cleanup localization outfiles
working-directory: specifyweb/frontend/js_src
run: rm -rf ./localization-strings
- name: Get relative path of all changed files
working-directory: specifyweb/frontend/js_src
id: changed
run: |
# Strip specifyweb/frontend/js_src/ from every file name
changed_files=`sed 's/specifyweb\/frontend\/js_src\///g' <<< "${{ needs.changes.outputs.frontend_changes }}"`
# Convert to array
IFS=' ' read -r -a split_files <<< "$changed_files"
# Exclude files that were removed
for file in "${split_files[@]}"; do
if [ ! -e "$file" ]; then
echo "File was removed: $file"
split_files=("${split_files[@]/$file}")
fi
done
# Convert back to string
changed="${split_files[*]}"
echo "Changed front-end files: ${changed}"
echo "changed=${changed}" >> $GITHUB_OUTPUT
- name: Run ESLint auto fixes
# Don't run this for production branch. Reasons:
# - ESLint auto fixes may break code. Don't want it to break production
# code
# - This would have already run on the feature branch by the time code
# is pushed into production.
# - There shouldn't be many direct pushes to production anyway
if:
github.ref != format('refs/heads/{0}',
github.event.repository.default_branch)
working-directory: specifyweb/frontend/js_src
run: |
# TODO: Once most errors are fixed remove "set +e" to not ignore errors
set +e
npx eslint --fix --color `echo "${{steps.changed.outputs.changed}}" | tr " " "\n"`
set -e
- name: Reformat all code with Prettier
if: steps.changed.outputs.changed
working-directory: specifyweb/frontend/js_src
run: |
npx prettier --write --minify `echo "${{steps.changed.outputs.changed}}" | tr " " "\n"` || true
- name: Commit linted files (if made any changes)
working-directory: specifyweb/frontend/js_src
# Creates a new commit. Amending an existing commit is a bad idea
# because:
# - Would require original committer to force pull. May cause merge
# conflicts
# - Changes that require linting might have been made over several
# commits. If you amend the last commit, than the fixes for all
# commits would be in the last commit.
run: |
git add .
if git diff-index --quiet HEAD --; then
echo "Linters did not detect any issues. Good job!"
else
git config --local user.name "github-actions"
git config --local user.email "41898282+github-actions[bot]@users.noreply.github.com"
# Set the committer to the name and email of the person who
# triggered the action
git commit \
--author '${{ github.event.head_commit.author.name }} <${{ github.event.head_commit.author.email }}>' \
-m 'Lint code with ESLint and Prettier' \
-m "Triggered by ${{ github.sha }} on branch ${{ github.ref }}"
git push
fi