1515 type : string
1616
1717jobs :
18+ prepare :
19+ name : Resolve Release Ref
20+ runs-on : ubuntu-latest
21+ outputs :
22+ image_tag : ${{ steps.vars.outputs.image_tag }}
23+ deploy_ref : ${{ steps.vars.outputs.deploy_ref }}
24+ steps :
25+ - name : Resolve image tag and deploy ref
26+ id : vars
27+ run : |
28+ if [ "${{ github.event_name }}" = "release" ]; then
29+ image_tag='${{ github.event.release.tag_name }}'
30+ deploy_ref='${{ github.event.release.tag_name }}'
31+ else
32+ image_tag='${{ github.event.inputs.image_tag }}'
33+ deploy_ref='${{ github.event.inputs.deploy_ref }}'
34+ fi
35+
36+ if [ -z "$image_tag" ]; then
37+ echo "IMAGE_TAG is empty" >&2
38+ exit 1
39+ fi
40+
41+ if [ -z "$deploy_ref" ]; then
42+ echo "DEPLOY_REF is empty" >&2
43+ exit 1
44+ fi
45+
46+ echo "image_tag=$image_tag" >> "$GITHUB_OUTPUT"
47+ echo "deploy_ref=$deploy_ref" >> "$GITHUB_OUTPUT"
48+
1849 test :
1950 name : Tests
2051 runs-on : ubuntu-latest
52+ needs : [ prepare ]
2153 steps :
2254 - uses : actions/checkout@v3
55+ with :
56+ ref : ${{ needs.prepare.outputs.deploy_ref }}
2357
2458 - name : Set up Python 3.11
2559 uses : actions/setup-python@v4
@@ -57,39 +91,15 @@ jobs:
5791 build :
5892 name : Build Image
5993 runs-on : ubuntu-latest
60- needs : [ test ]
94+ needs : [ prepare, test ]
6195 outputs :
62- image_tag : ${{ steps.vars .outputs.image_tag }}
63- deploy_ref : ${{ steps.vars .outputs.deploy_ref }}
96+ image_tag : ${{ needs.prepare .outputs.image_tag }}
97+ deploy_ref : ${{ needs.prepare .outputs.deploy_ref }}
6498 steps :
6599 - name : " Checkout repository"
66100 uses : actions/checkout@v3
67101 with :
68- ref : ${{ github.event_name == 'release' && github.event.release.tag_name || github.event.inputs.deploy_ref }}
69-
70- - name : Resolve image tag
71- id : vars
72- run : |
73- if [ "${{ github.event_name }}" = "release" ]; then
74- image_tag='${{ github.event.release.tag_name }}'
75- deploy_ref='${{ github.event.release.tag_name }}'
76- else
77- image_tag='${{ github.event.inputs.image_tag }}'
78- deploy_ref='${{ github.event.inputs.deploy_ref }}'
79- fi
80-
81- if [ -z "$image_tag" ]; then
82- echo "IMAGE_TAG is empty" >&2
83- exit 1
84- fi
85-
86- if [ -z "$deploy_ref" ]; then
87- echo "DEPLOY_REF is empty" >&2
88- exit 1
89- fi
90-
91- echo "image_tag=$image_tag" >> "$GITHUB_OUTPUT"
92- echo "deploy_ref=$deploy_ref" >> "$GITHUB_OUTPUT"
102+ ref : ${{ needs.prepare.outputs.deploy_ref }}
93103
94104 - name : " Set up QEMU"
95105 uses : docker/setup-qemu-action@v3
@@ -110,7 +120,7 @@ jobs:
110120 with :
111121 images : ghcr.io/procollab-github/api
112122 tags : |
113- type=raw,value=${{ steps.vars .outputs.image_tag }}
123+ type=raw,value=${{ needs.prepare .outputs.image_tag }}
114124 - name : Build and push container
115125 uses : docker/build-push-action@v5
116126 with :
@@ -124,7 +134,7 @@ jobs:
124134 deploy :
125135 name : Deploy
126136 runs-on : ubuntu-latest
127- needs : [ build ]
137+ needs : [ prepare, build ]
128138 steps :
129139 - name : Deploy to server
130140 uses : garygrossgarten/github-action-ssh@release
@@ -135,8 +145,8 @@ jobs:
135145 command : |
136146 set -eu
137147
138- export IMAGE_TAG="${{ needs.build .outputs.image_tag }}"
139- export DEPLOY_REF="${{ needs.build .outputs.deploy_ref }}"
148+ export IMAGE_TAG="${{ needs.prepare .outputs.image_tag }}"
149+ export DEPLOY_REF="${{ needs.prepare .outputs.deploy_ref }}"
140150 echo "Deploying IMAGE_TAG=${IMAGE_TAG} from DEPLOY_REF=${DEPLOY_REF}"
141151
142152 if [ "$(id -un)" = "app" ]; then
@@ -150,10 +160,6 @@ jobs:
150160 fi
151161
152162 cd /home/app/procollab-backend
153- docker container prune -f
154- docker image prune -a -f
155- docker compose -f docker-compose.prod-ci.yml -p prod pull
156-
157163 rm -f .env
158164 touch .env
159165
@@ -175,7 +181,9 @@ jobs:
175181
176182 chmod 600 .env
177183 docker compose -f docker-compose.prod-ci.yml -p prod config >/dev/null
184+ docker compose -f docker-compose.prod-ci.yml -p prod pull
178185
186+ docker compose -f docker-compose.prod-ci.yml -p prod run --rm web python manage.py migrate
179187 docker compose -f docker-compose.prod-ci.yml -p prod up -d --remove-orphans
180188 if [ "$(id -u)" -eq 0 ]; then
181189 nginx -t
@@ -186,16 +194,44 @@ jobs:
186194 fi
187195
188196 for attempt in $(seq 1 24); do
189- root_status="$(curl -k - s -o /dev/null -w '%{http_code}' https://api.procollab.ru/ || true)"
190- admin_status="$(curl -k - s -o /dev/null -w '%{http_code}' https://api.procollab.ru/admin/login/ || true)"
197+ root_status="$(curl -s -o /dev/null -w '%{http_code}' https://api.procollab.ru/ || true)"
198+ admin_status="$(curl -s -o /dev/null -w '%{http_code}' https://api.procollab.ru/admin/login/ || true)"
191199
192200 if [ "$root_status" = "401" ] && [ "$admin_status" = "200" ]; then
193201 echo "Smoke check passed on attempt ${attempt}"
194- exit 0
202+ break
203+ fi
204+
205+ sleep 5
206+ done
207+
208+ if [ "$root_status" != "401" ] || [ "$admin_status" != "200" ]; then
209+ echo "Smoke check failed: /=${root_status} /admin/login/=${admin_status}" >&2
210+ exit 1
211+ fi
212+
213+ celery_status=""
214+ celery_ping=""
215+ for attempt in $(seq 1 24); do
216+ celery_status="$(docker inspect -f '{{.State.Status}}' api_celery 2>/dev/null || true)"
217+ if [ "$celery_status" = "running" ]; then
218+ celery_ping="$(docker compose -f docker-compose.prod-ci.yml -p prod exec -T celerys sh -lc 'celery -A procollab inspect ping -d \"celery@$(hostname)\"' 2>&1 || true)"
219+ printf '%s\n' "$celery_ping"
220+ if printf '%s\n' "$celery_ping" | grep -q 'pong'; then
221+ echo "Celery check passed on attempt ${attempt}"
222+ break
223+ fi
195224 fi
196225
197226 sleep 5
198227 done
199228
200- echo "Smoke check failed: /=${root_status} /admin/login/=${admin_status}"
201- exit 1
229+ if [ "$celery_status" != "running" ]; then
230+ echo "Celery container is not running: ${celery_status}" >&2
231+ exit 1
232+ fi
233+
234+ printf '%s\n' "$celery_ping" | grep -q 'pong' || {
235+ echo "Celery ping failed" >&2
236+ exit 1
237+ }
0 commit comments