44 release :
55 types : [ published ]
66 workflow_dispatch :
7+ inputs :
8+ image_tag :
9+ description : Docker image tag to build and deploy
10+ required : true
11+ type : string
12+ deploy_ref :
13+ description : Git ref or tag to checkout on the server
14+ required : true
15+ type : string
716
817jobs :
918 test :
4958 name : Build Image
5059 runs-on : ubuntu-latest
5160 needs : [ test ]
61+ outputs :
62+ image_tag : ${{ steps.vars.outputs.image_tag }}
63+ deploy_ref : ${{ steps.vars.outputs.deploy_ref }}
5264 steps :
5365 - name : " Checkout repository"
5466 uses : actions/checkout@v3
67+ 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"
5593
5694 - name : " Set up QEMU"
5795 uses : docker/setup-qemu-action@v3
@@ -71,11 +109,8 @@ jobs:
71109 uses : docker/metadata-action@v5
72110 with :
73111 images : ghcr.io/procollab-github/api
74- flavor : latest=true
75112 tags : |
76- type=ref,event=branch
77- type=ref,event=pr
78- type=semver,pattern={{version}}
113+ type=raw,value=${{ steps.vars.outputs.image_tag }}
79114 - name : Build and push container
80115 uses : docker/build-push-action@v5
81116 with :
@@ -98,28 +133,69 @@ jobs:
98133 username : ${{ secrets.SERVER_USER }}
99134 password : ${{ secrets.SERVER_PASSWORD }}
100135 command : |
101- cd /home/app/procollab-backend &&
102- docker container prune -f &&
103- docker image prune -a -f &&
104- docker compose -f docker-compose.prod-ci.yml -p prod pull &&
105-
106- rm -f .env &&
107- touch .env &&
108-
109- echo "DJANGO_SECRET_KEY=${{ secrets.DJANGO_SECRET_KEY }}" >> .env &&
110-
111- echo "DATABASE_NAME=${{ secrets.DATABASE_NAME }}" >> .env &&
112- echo "DATABASE_PASSWORD=${{ secrets.DATABASE_PASSWORD }}" >> .env &&
113- echo "DATABASE_USER=${{ secrets.DATABASE_USER }}" >> .env &&
114- echo "DATABASE_HOST=${{ secrets.DATABASE_HOST }}" >> .env &&
115- echo "DATABASE_PORT=${{ secrets.DATABASE_PORT }}" >> .env &&
116-
117- echo "SELECTEL_ACCOUNT_ID=${{ secrets.SELECTEL_ACCOUNT_ID }}" >> .env &&
118- echo "SELECTEL_CONTAINER_NAME=${{ secrets.SELECTEL_CONTAINER_NAME }}" >> .env &&
119- echo "SELECTEL_CONTAINER_PASSWORD=${{ secrets.SELECTEL_CONTAINER_PASSWORD }}" >> .env &&
120- echo "SELECTEL_CONTAINER_USERNAME=${{ secrets.SELECTEL_CONTAINER_USERNAME }}" >> .env &&
121-
122- echo "EMAIL_USER=${{ secrets.EMAIL_USER }}" >> .env &&
123- echo "UNISENDER_GO_API_KEY=${{ secrets.UNISENDER_GO_API_KEY }}" >> .env &&
124-
125- docker compose -f docker-compose.prod-ci.yml -p prod up -d
136+ set -eu
137+
138+ export IMAGE_TAG="${{ needs.build.outputs.image_tag }}"
139+ export DEPLOY_REF="${{ needs.build.outputs.deploy_ref }}"
140+ echo "Deploying IMAGE_TAG=${IMAGE_TAG} from DEPLOY_REF=${DEPLOY_REF}"
141+
142+ if [ "$(id -un)" = "app" ]; then
143+ git -C /home/app/procollab-backend fetch --all --tags --prune
144+ git -C /home/app/procollab-backend checkout --detach "${DEPLOY_REF}"
145+ git -C /home/app/procollab-backend rev-parse HEAD
146+ else
147+ sudo -u app git -C /home/app/procollab-backend fetch --all --tags --prune
148+ sudo -u app git -C /home/app/procollab-backend checkout --detach "${DEPLOY_REF}"
149+ sudo -u app git -C /home/app/procollab-backend rev-parse HEAD
150+ fi
151+
152+ 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+
157+ rm -f .env
158+ touch .env
159+
160+ echo "DJANGO_SECRET_KEY=${{ secrets.DJANGO_SECRET_KEY }}" >> .env
161+
162+ echo "DATABASE_NAME=${{ secrets.DATABASE_NAME }}" >> .env
163+ echo "DATABASE_PASSWORD=${{ secrets.DATABASE_PASSWORD }}" >> .env
164+ echo "DATABASE_USER=${{ secrets.DATABASE_USER }}" >> .env
165+ echo "DATABASE_HOST=${{ secrets.DATABASE_HOST }}" >> .env
166+ echo "DATABASE_PORT=${{ secrets.DATABASE_PORT }}" >> .env
167+
168+ echo "SELECTEL_ACCOUNT_ID=${{ secrets.SELECTEL_ACCOUNT_ID }}" >> .env
169+ echo "SELECTEL_CONTAINER_NAME=${{ secrets.SELECTEL_CONTAINER_NAME }}" >> .env
170+ echo "SELECTEL_CONTAINER_PASSWORD=${{ secrets.SELECTEL_CONTAINER_PASSWORD }}" >> .env
171+ echo "SELECTEL_CONTAINER_USERNAME=${{ secrets.SELECTEL_CONTAINER_USERNAME }}" >> .env
172+
173+ echo "EMAIL_USER=${{ secrets.EMAIL_USER }}" >> .env
174+ echo "UNISENDER_GO_API_KEY=${{ secrets.UNISENDER_GO_API_KEY }}" >> .env
175+
176+ chmod 600 .env
177+ docker compose -f docker-compose.prod-ci.yml -p prod config >/dev/null
178+
179+ docker compose -f docker-compose.prod-ci.yml -p prod up -d --remove-orphans
180+ if [ "$(id -u)" -eq 0 ]; then
181+ nginx -t
182+ systemctl reload nginx
183+ else
184+ sudo nginx -t
185+ sudo systemctl reload nginx
186+ fi
187+
188+ 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)"
191+
192+ if [ "$root_status" = "401" ] && [ "$admin_status" = "200" ]; then
193+ echo "Smoke check passed on attempt ${attempt}"
194+ exit 0
195+ fi
196+
197+ sleep 5
198+ done
199+
200+ echo "Smoke check failed: /=${root_status} /admin/login/=${admin_status}"
201+ exit 1
0 commit comments