Skip to content

Commit 8cbaa77

Browse files
committed
Enhance deployment workflow by improving variable handling and adding concurrency support. Updated SSH commands to use environment variables for better readability and error handling. Clarified comments regarding deployment host configuration.
1 parent 501a4ed commit 8cbaa77

1 file changed

Lines changed: 37 additions & 18 deletions

File tree

.github/workflows/build-push-deploy.yml

Lines changed: 37 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,12 @@
22
# DOCKER_USER, DOCKER_TOKEN - Docker Hub login
33
# DEPLOYMENT_KEY - SSH private key for deploy host
44
# DEPLOYMENT_USER - SSH user on deploy host (e.g. root)
5-
# DEPLOYMENT_HOST, DEPLOYMENT_PORT - deploy server
5+
# DEPLOYMENT_HOST - deploy server hostname or IP only (no user@ prefix)
6+
# DEPLOYMENT_PORT - SSH port (e.g. 22)
67
# SMTP_HOST, SMTP_PORT, SMTP_SECURE, SMTP_USER, SMTP_PASS, SMTP_FROM, SMTP_TO
7-
# Optional vars (defaults in workflow): SMTP_FROM_NAME, NEXT_PUBLIC_SITE_URL
8+
# Optional: SMTP_FROM_NAME. Vars (defaults in workflow): NEXT_PUBLIC_SITE_URL
9+
# Note: ssh-keyscan uses DEPLOYMENT_HOST only; ssh/scp use DEPLOYMENT_USER@DEPLOYMENT_HOST.
10+
# Avoid single/double quotes and newlines in secret values (SMTP_PASS, DOCKER_TOKEN, etc.).
811
name: Build, Push and Deploy
912

1013
env:
@@ -19,6 +22,10 @@ on:
1922
- develop
2023
workflow_dispatch:
2124

25+
concurrency:
26+
group: deploy-${{ github.ref }}
27+
cancel-in-progress: false
28+
2229
jobs:
2330
build-and-push:
2431
runs-on: ubuntu-latest
@@ -34,16 +41,16 @@ jobs:
3441
- name: Configure variables
3542
id: conf
3643
run: |
37-
echo "branch=$(echo ${GITHUB_REF#refs/heads/})" >> $GITHUB_OUTPUT
38-
echo "sha_short=$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT
44+
echo "branch=$(echo ${GITHUB_REF#refs/heads/})" >> "$GITHUB_OUTPUT"
45+
echo "sha_short=$(git rev-parse --short HEAD)" >> "$GITHUB_OUTPUT"
3946
4047
- name: Set job outputs
4148
id: set-outputs
4249
run: |
43-
echo "sha_short=${{ steps.conf.outputs.sha_short }}" >> $GITHUB_OUTPUT
44-
echo "branch=${{ steps.conf.outputs.branch }}" >> $GITHUB_OUTPUT
45-
echo "image_tag=${{ steps.conf.outputs.branch }}-${{ steps.conf.outputs.sha_short }}" >> $GITHUB_OUTPUT
46-
echo "full_image=${{ env.DOCKER_IMAGE }}:${{ steps.conf.outputs.branch }}-${{ steps.conf.outputs.sha_short }}" >> $GITHUB_OUTPUT
50+
echo "sha_short=${{ steps.conf.outputs.sha_short }}" >> "$GITHUB_OUTPUT"
51+
echo "branch=${{ steps.conf.outputs.branch }}" >> "$GITHUB_OUTPUT"
52+
echo "image_tag=${{ steps.conf.outputs.branch }}-${{ steps.conf.outputs.sha_short }}" >> "$GITHUB_OUTPUT"
53+
echo "full_image=${{ env.DOCKER_IMAGE }}:${{ steps.conf.outputs.branch }}-${{ steps.conf.outputs.sha_short }}" >> "$GITHUB_OUTPUT"
4754
4855
- name: Docker metadata
4956
id: meta
@@ -86,6 +93,10 @@ jobs:
8693
runs-on: ubuntu-latest
8794
needs: build-and-push
8895
if: github.ref == 'refs/heads/main' && needs.build-and-push.result == 'success'
96+
env:
97+
FULL_IMAGE: ${{ needs.build-and-push.outputs.full_image }}
98+
IMAGE_TAG: ${{ needs.build-and-push.outputs.image_tag }}
99+
SHA_SHORT: ${{ needs.build-and-push.outputs.sha_short }}
89100
steps:
90101
- name: Checkout code
91102
uses: actions/checkout@v4
@@ -106,7 +117,7 @@ jobs:
106117
107118
- name: Generate docker-compose.yml from template
108119
run: |
109-
sed -e "s|\${DOCKER_IMAGE}|${{ needs.build-and-push.outputs.full_image }}|g" \
120+
sed -e "s|\${DOCKER_IMAGE}|$FULL_IMAGE|g" \
110121
docker-compose.prod.yaml > /tmp/docker-compose.yml
111122
112123
- name: Copy docker-compose.yml to deployment host
@@ -145,19 +156,22 @@ jobs:
145156
"cd ${{ env.DEPLOYMENT_DIR }} && base64 -d .env.b64 > .env && chmod 600 .env && rm -f .env.b64"
146157
147158
- name: Login to Docker Hub on deployment host
159+
env:
160+
DOCKER_USER: ${{ secrets.DOCKER_USER }}
161+
DOCKER_TOKEN: ${{ secrets.DOCKER_TOKEN }}
148162
run: |
149-
ssh -p ${{ secrets.DEPLOYMENT_PORT }} ${{ secrets.DEPLOYMENT_USER }}@${{ secrets.DEPLOYMENT_HOST }} \
150-
"echo '${{ secrets.DOCKER_TOKEN }}' | docker login ${{ env.DOCKER_REGISTRY }} -u '${{ secrets.DOCKER_USER }}' --password-stdin"
163+
echo "$DOCKER_TOKEN" | ssh -p ${{ secrets.DEPLOYMENT_PORT }} ${{ secrets.DEPLOYMENT_USER }}@${{ secrets.DEPLOYMENT_HOST }} \
164+
"docker login ${{ env.DOCKER_REGISTRY }} -u $DOCKER_USER --password-stdin"
151165
152166
- name: Check existing deployment
153167
id: check-existing
154168
run: |
155169
if ssh -p ${{ secrets.DEPLOYMENT_PORT }} ${{ secrets.DEPLOYMENT_USER }}@${{ secrets.DEPLOYMENT_HOST }} \
156170
"test -f ${{ env.DEPLOYMENT_DIR }}/docker-compose.yml"; then
157-
echo "exists=true" >> $GITHUB_OUTPUT
171+
echo "exists=true" >> "$GITHUB_OUTPUT"
158172
echo "Existing docker-compose.yml found"
159173
else
160-
echo "exists=false" >> $GITHUB_OUTPUT
174+
echo "exists=false" >> "$GITHUB_OUTPUT"
161175
echo "No existing docker-compose.yml found"
162176
fi
163177
@@ -175,8 +189,12 @@ jobs:
175189
176190
- name: Pull Docker image
177191
run: |
192+
if [ -z "$FULL_IMAGE" ]; then
193+
echo "::error::FULL_IMAGE is empty (build-and-push.outputs.full_image was not set)"
194+
exit 1
195+
fi
178196
ssh -p ${{ secrets.DEPLOYMENT_PORT }} ${{ secrets.DEPLOYMENT_USER }}@${{ secrets.DEPLOYMENT_HOST }} \
179-
"docker pull ${{ needs.build-and-push.outputs.full_image }}"
197+
"docker pull $FULL_IMAGE"
180198
181199
- name: Deploy with docker compose
182200
run: |
@@ -192,7 +210,8 @@ jobs:
192210
run: |
193211
ssh -p ${{ secrets.DEPLOYMENT_PORT }} ${{ secrets.DEPLOYMENT_USER }}@${{ secrets.DEPLOYMENT_HOST }} \
194212
"cd ${{ env.DEPLOYMENT_DIR }} && \
195-
if docker compose ps --format json | grep -q '\"State\":\"running\"'; then \
213+
running=\$(docker compose ps --format '{{ '{{' }}.State{{ '}}' }}' 2>/dev/null | grep -c running || true); \
214+
if [ \"\$running\" -gt 0 ]; then \
196215
echo 'Container is running'; \
197216
else \
198217
echo 'Container may not be running properly'; \
@@ -209,8 +228,8 @@ jobs:
209228
- name: Deployment info
210229
run: |
211230
echo "Successfully deployed:"
212-
echo " Image: ${{ needs.build-and-push.outputs.full_image }}"
213-
echo " Tag: ${{ needs.build-and-push.outputs.image_tag }}"
214-
echo " SHA: ${{ needs.build-and-push.outputs.sha_short }}"
231+
echo " Image: $FULL_IMAGE"
232+
echo " Tag: $IMAGE_TAG"
233+
echo " SHA: $SHA_SHORT"
215234
echo " Host: ${{ secrets.DEPLOYMENT_USER }}@${{ secrets.DEPLOYMENT_HOST }}"
216235
echo " Directory: ${{ env.DEPLOYMENT_DIR }}"

0 commit comments

Comments
 (0)