forked from skyportal/skyportal
-
Notifications
You must be signed in to change notification settings - Fork 0
258 lines (219 loc) · 8.03 KB
/
test_migrations.yaml
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
name: Test Skyportal Migrations
on:
# Run only if potential changes in database schema
pull_request:
paths:
- "baselayer"
- "skyportal/models.py"
- "alembic/versions/**"
jobs:
test:
name: Test SkyPortal migrations
runs-on: ubuntu-latest
timeout-minutes: 90
env:
# We only check migrations from this point onward, since we know
# this specific commit to have migration integrity.
#
# This commit can be updated from time to time, if necessary
# (e.g., to get access to a newer data loader or dependencies).
# Pick any commit known to have passed the migration tests on
# CI, or which has deployed successfully.
MIGRATION_REFERENCE: 880cd56716015e33df22af1d256717ce98d7eb84
services:
postgres:
image: postgres
env:
POSTGRES_USER: skyportal
POSTGRES_PASSWORD: anything
ports:
- 5432:5432
# needed because the postgres container does not provide a
# healthcheck
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
steps:
- uses: actions/setup-python@v1
with:
python-version: "3.8"
- name: Checkout master
uses: actions/checkout@v2
with:
fetch-depth: 0
ref: master
submodules: true
- uses: actions/cache@v2
with:
path: |
~/.npm
key: ${{ runner.os }}-npm-${{ hashFiles('package.json') }}
- uses: actions/cache@v2
with:
path: |
~/.cache/pip
key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements*.txt') }}
- name: Install system dependencies
run: |
curl -sL https://deb.nodesource.com/setup_14.x | sudo -E bash -
sudo apt install -y wget nodejs unzip firefox nginx
pip install --upgrade pip
pip install wheel numpy
export NPM_PACKAGES="${HOME}/.npm-packages"
export PATH=${NPM_PACKAGES}/bin:$PATH
export NODE_PATH="$NPM_PACKAGES/lib/node_modules:$NODE_PATH"
sudo npm -g install [email protected]
which python; python --version
echo npm $(npm --version)
echo node $(node --version)
nginx -v
firefox --version
- name: Install SkyPortal dependencies
run: |
export PYTHONPATH=$PYTHONPATH:$(pwd)
make dependencies
pip install black
- name: Save current Alembic head on master
run: |
# Get the head line from Alembic history output
head=$( PYTHONPATH=. alembic history | grep '(head)' )
# Split by space; index 2 should be latest revision
tokens=($head)
current_head=${tokens[2]}
echo ${current_head}
echo "CURRENT_HEAD=${current_head}" >> $GITHUB_ENV
- name: Checkout migration reference commit
uses: actions/checkout@v2
with:
fetch-depth: 0
ref: ${{ env.MIGRATION_REFERENCE }}
submodules: true
- name: Write SkyPortal configs
run: |
cat << EOF > config.yaml
database:
database: skyportal
host: localhost
port: 5432
user: skyportal
password: anything
EOF
- name: Initialize SkyPortal
run: |
# Usually, we create databases on the local machine, so
# `createdb` just works out of the box. However, when doing
# this on a server, as in our case, we need to specify extra
# options.
#
# db_init should not complain if the databases exist already
#
echo "localhost:5432:*:skyportal:anything" > ~/.pgpass
chmod 600 ~/.pgpass
createdb -h localhost -U skyportal skyportal_test
psql -U skyportal -h localhost -c "GRANT ALL PRIVILEGES ON DATABASE skyportal_test TO skyportal;" skyportal_test
make db_init
pip list --format=columns
npm ls --depth 0
# Stamp Alembic HEAD
PYTHONPATH=. alembic -x config=config.yaml stamp head
- name: Test loading demo data
run: |
make run &
sleep 10 && make load_demo_data
kill %1
- name: Checkout PR branch
uses: actions/checkout@v2
with:
fetch-depth: 0
submodules: true
clean: false
- name: Check for migration branching
run: |
# Make sure latest revision on master is included in Alembic history
n_current_head=$( PYTHONPATH=. alembic history | grep -c $CURRENT_HEAD )
if [[ $n_current_head -eq 0 ]]
then
cat << EOF
The current head Alembic revision on master is not present in this branch's
Alembic history. Please merge in the latest commit from master into this PR.
EOF
exit 1
else
echo "Alembic history includes the latest on master."
fi
# Make sure there are not multiple heads to the Alembic history
num_heads=$( PYTHONPATH=. alembic history | grep -c '(head)' )
if [[ $num_heads -ne 1 ]]
then
cat << EOF
There is more than one head revision in this branch's Alembic history.
Please resolve the branching revisions.
EOF
exit 1
else
echo "Alembic history has no conflicts in branch."
fi
- name: Run migration
run: |
# Update to latest dependencies
make dependencies
PYTHONPATH=. alembic -x config=config.yaml upgrade head
PYTHONPATH=. alembic current
- name: Check migration completeness with Alembic
run: |
# Try generating a new migration
PYTHONPATH=. alembic -x config=config.yaml revision --autogenerate -m "Test migration"
# The generated migration should be empty if the migration script provided in the PR
# completely encompasses the changes in the database.
pass_lines=$( cat alembic/versions/*test_migration.py | grep -c pass ) || true
if [[ $pass_lines -ne 2 ]]
then
echo "Additional migrations needed: see the alembic-difference artifact."
exit 1
else
echo "All migrations included in script."
fi
- name: Create a fresh database
run: |
# Make new configs
cat << EOF > config.yaml
database:
database: skyportal2
host: localhost
port: 5432
user: skyportal
password: anything
EOF
createdb -h localhost -U skyportal skyportal2
psql -U skyportal -h localhost -c "GRANT ALL PRIVILEGES ON DATABASE skyportal2 TO skyportal;" skyportal2
make db_init
make run &
sleep 10 && make load_demo_data
kill %1
PYTHONPATH=. alembic -x config=config.yaml stamp head
- name: Compare databases with migra
run: |
pip install migra
# SQL needed to go from migrated database to fresh database
migra --unsafe postgresql://skyportal:anything@localhost:5432/skyportal postgresql://skyportal:anything@localhost:5432/skyportal2 > migra.sql || true
if [[ $(cat migra.sql | wc -l) -ne 0 ]]
then
echo "Differences found between migrated database and fresh database. See the migra-difference artifact."
exit 1
else
echo "Migrated database and fresh database match."
fi
- name: Upload the Alembic diff
uses: actions/upload-artifact@v2
if: ${{ always() }}
with:
name: alembic-difference
path: alembic/versions/**test_migration.py
- name: Upload migra diff
uses: actions/upload-artifact@v2
if: ${{ always() }}
with:
name: migra-difference
path: migra.sql