-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path.gitlab-ci.yml
177 lines (170 loc) · 6.79 KB
/
.gitlab-ci.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
# List of stages for jobs, which is executed in order. To define dependencies
# between jobs in the same stage, use the 'needs' keyword.
stages:
- test
- build
- deploy
"Django Unit Tests":
stage: test
rules:
# This job runs on protected branches and on merge requests to master.
# Both should be done because the branch state within the MR and the
# merged result can and often is different if there are other commits
# merged between the executions.
- if: $CI_COMMIT_REF_PROTECTED == "true" # Run on protected branches, or
- if: $CI_PIPELINE_SOURCE == 'merge_request_event' && $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "master" # Run on merge requests to master
changes:
- backend/**/*
image: python:3.8 # version when installing python3 from apt (same as Dockerfile)
services:
# Run required services to test Django
- postgres:16
- name: minio/minio:RELEASE.2023-10-25T06-33-25Z
command: ['server', '/minio']
alias: minio
before_script:
# Install mc so that we can create the community-solutions bucket in minio
- curl https://dl.min.io/client/mc/release/linux-amd64/mc --create-dirs -o mc
- chmod +x ./mc
- ./mc config host add myminio http://minio:9000 minio minio123
- ./mc mb myminio/community-solutions
# Install poppler to get pdftotext binary
- apt update && apt install -y --no-install-recommends poppler-utils
- pip3 install -r backend/requirements.txt
- pip3 install tblib
# Make/copy files (same as Dockerfile definition) to make resources availabe to tests
- mkdir backend/intermediate_pdf_storage
- mv ./frontend/public/exam10.pdf backend
- mv ./frontend/public/static backend
cache:
key:
files:
- backend/requirements.txt
paths:
- backend/.cache/pip
script:
- export SIP_POSTGRES_DB_NAME=$POSTGRES_DB
- export SIP_POSTGRES_DB_USER=$POSTGRES_USER
- export SIP_POSTGRES_DB_PW=$POSTGRES_PASSWORD
- export SIP_POSTGRES_DB_SERVER=postgres
- export SIP_POSTGRES_DB_PORT=5432
- export SIP_S3_FILES_HOST=minio
- export SIP_S3_FILES_PORT=9000
- export SIP_S3_FILES_ACCESS_KEY=minio
- export SIP_S3_FILES_SECRET_KEY=minio123
- export SIP_S3_FILES_BUCKET=community-solutions
- export SIP_S3_FILES_USE_SSL=false
- cd backend
- python3 manage.py test --parallel # parallel speeds up by approx 4x.
variables:
# Set the pip cache directory to a directory that we can access and cache
PIP_CACHE_DIR: "$CI_PROJECT_DIR/backend/.cache/pip"
POSTGRES_DB: testdb
POSTGRES_USER: testuser
POSTGRES_PASSWORD: testpw
POSTGRES_HOST_AUTH_METHOD: trust
MINIO_ACCESS_KEY: minio
MINIO_SECRET_KEY: minio123
MINIO_DOMAIN: localhost
"Frontend Typecheck & Lint":
stage: test
rules:
# No need to run on protected branches because the frontend build is
# executed when building the Docker image anyway. But in MRs, we won't
# build any Docker images so we should test the frontend.
- if: $CI_PIPELINE_SOURCE == 'merge_request_event' && $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "master" # Run on merge requests to master
changes:
- frontend/**/*
image: node:20-alpine # version when installing python3 from apt (same as Dockerfile)
before_script:
- cd frontend
- echo 'yarn-offline-mirror ".yarn-cache/"' >> .yarnrc
- echo 'yarn-offline-mirror-pruning true' >> .yarnrc
cache:
key:
files:
- frontend/yarn.lock
paths:
- frontend/.yarn-cache/
script:
- yarn --ignore-engines
- yarn run tsc
- yarn run eslint 'src/**/*.{js,jsx,ts,tsx}'
"Build production image":
stage: build
rules:
- if: $CI_COMMIT_REF_PROTECTED == "true"
image:
name: gcr.io/kaniko-project/executor:debug
entrypoint: [""]
script:
# Because we can't use Docker within Kubernetes CI workers (which is what
# Tardis GitLab uses), we intead use Kaniko to build our image
- /kaniko/executor
--context "${CI_PROJECT_DIR}"
--dockerfile "${CI_PROJECT_DIR}/Dockerfile"
--destination "${CI_REGISTRY_IMAGE}:latest"
--destination "${CI_REGISTRY_IMAGE}:${CI_COMMIT_SHORT_SHA}"
--build-arg git_branch="${CI_COMMIT_REF_NAME}"
--build-arg git_commit="${CI_COMMIT_SHA}"
--cache=true
--cache-copy-layers=true
--snapshot-mode=redo
--use-new-run
"Deploy":
stage: deploy
rules:
# Run on commits to the protected branches. This uses project-level secrets.
# The job would also run if you fork the repository and commit to its
# protected branch, but that is OK because in that case the job will use the
# forked project's CI variables.
- if: $CI_COMMIT_REF_PROTECTED == "true"
environment: production
before_script:
# Install curl so we can make requests to the Kubernetes API
- apt-get update && apt-get install -y curl
script:
# The service account token should have the permissions for deployment and
# replicaset get and patch.
#
# --fail is crucial
# It sets the exit code to 22 on error, stopping the script.
# --silent is optional for making the output cleaner
# --output is for not printing the API response as it may contain some
# confidential information. To debug any errors, use the command locally.
# --insecure is required
# This is to access the k8s endpoint without a valid client-side
# certificate as otherwise cURL will complain about self-signed
# server-side certs.
# --location
# Makes it follow redirects and isn't necessary but doesn't hurt to have
# --request PATCH and the --data-raw
# The request modifies a harmless annotation on the deployment, which has
# the same overall effect as restarting the deployment:
# `kubectl rollout restart deployment`.
# The restart causes the deployment to pull the latest image from the
# GitLab registry and restart the pods. If the pods don't successfully
# start up (due to a critical failure), the previous deployment stays.
- echo "Initiating Rollout on Production Kubernetes..."
- >
curl "${PRODUCTION_K8S_DEPLOYMENT_URL}?fieldManager=kubectl-rollout" \
--fail \
--silent \
--output /dev/null \
--header "Content-Type: application/strategic-merge-patch+json" \
--header "Authorization: Bearer $(echo "$PRODUCTION_K8S_SA_TOKEN" | base64 -d)" \
--insecure \
--location \
--request PATCH \
--data-raw "{
\"spec\": {
\"template\": {
\"metadata\": {
\"annotations\": {
\"kubectl.kubernetes.io/restartedAt\": \"$(date -u +"%Y-%m-%dT%H:%M:%SZ")\"
}
}
}
}
}"
- echo "Rollout complete."