-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy path.gitlab-ci.yml
More file actions
158 lines (146 loc) · 4.84 KB
/
Copy path.gitlab-ci.yml
File metadata and controls
158 lines (146 loc) · 4.84 KB
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
# list of stages for jobs and their order of execution
stages:
- test
- build
- deploy
# specify additional configurations that are applied to all jobs
default:
interruptible: true
workflow:
name: "strange blog - $CI_PIPELINE_SOURCE - $CI_COMMIT_REF_NAME"
rules:
# merge request pipelines
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
# do not create a duplicate branch pipeline when the branch already has an open merge request
- if: '$CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS'
when: never
# normal branch pushes
- if: '$CI_COMMIT_BRANCH'
# everything else is disabled
- when: never
test-job:
stage: test
image: python:3.11-slim
before_script:
- apt-get update
- apt-get install -y --no-install-recommends bash
- rm -rf /var/lib/apt/lists/*
script:
- bash scripts/check_markdown_validity.sh # invoked explicitly with Bash, so no executable permission is required
rules: # specify when to run or skip jobs
# merge request pipelines
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
changes:
- posts/en/**/*.md
- posts/template.md.tmpl
- scripts/check_markdown_validity.sh
- .gitlab-ci.yml
# normal branch pushes
- if: '$CI_COMMIT_BRANCH'
changes:
- posts/en/**/*.md
- posts/template.md.tmpl
- scripts/check_markdown_validity.sh
- .gitlab-ci.yml
build-job:
stage: build
image:
name: docker:24.0.5-cli
services:
- name: docker:24.0.5-dind
alias: docker
variables:
DOCKER_HOST: tcp://docker:2376
DOCKER_TLS_CERTDIR: "/certs"
before_script:
# verify docker daemon and TLS connectivity
- docker info
script:
# build the image using the commit SHA as an immutable tag
- docker build
--pull
--tag "$CI_REGISTRY_IMAGE:$CI_COMMIT_SHA"
.
# authenticate and publish the image only from the default branch (main)
- |
if [ "$CI_COMMIT_BRANCH" = "$CI_DEFAULT_BRANCH" ]; then
echo "$CI_REGISTRY_PASSWORD" | docker login $CI_REGISTRY -u "$CI_REGISTRY_USER" --password-stdin
docker push "$CI_REGISTRY_IMAGE:$CI_COMMIT_SHA"
fi
rules:
# merge request pipelines
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
# normal branch pushes
- if: '$CI_COMMIT_BRANCH'
deploy-job:
stage: deploy
needs: ["build-job"]
image:
name: docker:24.0.5-cli
services:
- name: docker:24.0.5-dind
alias: docker
variables:
DOCKER_HOST: tcp://docker:2376
DOCKER_TLS_CERTDIR: "/certs"
before_script:
# install Docker Compose plugin manually
- apk add --no-cache curl
- mkdir -p /root/.docker/cli-plugins
- curl -SL https://github.com/docker/compose/releases/download/v2.29.1/docker-compose-linux-x86_64 -o /root/.docker/cli-plugins/docker-compose
- chmod +x /root/.docker/cli-plugins/docker-compose
# verify Docker Compose installation
- docker compose version
# verify docker daemon and TLS connectivity
- docker info
# fail early if required variables are missing
- test -n "$POSTGRES_USER"
- test -n "$POSTGRES_PASSWORD"
- test -n "$POSTGRES_DB"
- test -n "$DATABASE_URL"
# authenticate to the registry so that the image can be pulled from it
- echo "$CI_REGISTRY_PASSWORD" | docker login $CI_REGISTRY -u "$CI_REGISTRY_USER" --password-stdin
# create the environment file required by Docker Compose
- |
cat > .env <<EOF
POSTGRES_USER=$POSTGRES_USER
POSTGRES_PASSWORD=$POSTGRES_PASSWORD
POSTGRES_DB=$POSTGRES_DB
DATABASE_URL=$DATABASE_URL
EOF
script:
# deploy exactly the image produced by build-job
- export TAG="$CI_COMMIT_SHA"
# verify the Compose configuration
- docker compose --profile prod config
# pull the image identified by the TAG from the registry
- docker compose --profile prod pull
# start/update the services in detached mode
- docker compose --profile prod up -d
# basic verification
- docker compose --profile prod ps
- |
echo "Waiting for web-prod to become healthy..."
for i in $(seq 1 30); do
STATUS=$(docker inspect --format='{{.State.Health.Status}}' flask-prod 2>/dev/null || true)
echo "web-prod health: $STATUS"
if [ "$STATUS" = "healthy" ]; then
echo "Smoke test passed: web-prod is healthy"
exit 0
fi
if [ "$STATUS" = "unhealthy" ]; then
echo "Smoke test failed: web-prod is unhealthy"
docker compose --profile prod logs --tail=200
exit 1
fi
sleep 2
done
echo "Smoke test failed: timeout waiting for web-prod"
docker compose --profile prod logs --tail=200
exit 1
environment:
name: production
rules:
# only deploy from the default branch (main)
- if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH'
when: manual