Files
static-front/.gitea/workflows/develop.yml
T
Ryan 0381c8b73c
Build & Deploy (develop) / build-and-deploy (push) Successful in 2m11s
refac:updated ci/cd pipeline to create docker images with timestamp and commit sha
2026-09-29 11:05:36 +03:30

107 lines
4.4 KiB
YAML

name: Build & Deploy (develop)
# Runs on:
# - Pull requests targeting develop
# - Direct pushes to develop
# main is intentionally NOT included yet (no prod target configured)
on:
push:
branches:
- develop
pull_request:
branches:
- develop
jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Resolve image tag
id: vars
run: |
# For PRs, gitea.sha is a temporary merge commit — use the real
# PR head commit instead so tags map to actual git history.
FULL_SHA="${{ gitea.event.pull_request.head.sha || gitea.sha }}"
SHORT_SHA="${FULL_SHA:0:7}"
BUILD_TIME=$(date -u +%Y-%m-%d_%H-%M-%S)
echo "sha=${SHORT_SHA}" >> "$GITHUB_OUTPUT"
echo "tag=${BUILD_TIME}-${SHORT_SHA}" >> "$GITHUB_OUTPUT"
- name: Build Docker image (tagged by UTC build time and commit SHA)
run: |
docker build -t robot-market:${{ steps.vars.outputs.tag }} .
- name: Save previous tag for rollback
id: backup
run: |
if [ -f /opt/robot-market-front/.env ]; then
cp /opt/robot-market-front/.env /opt/robot-market-front/.env.previous
echo "available=true" >> "$GITHUB_OUTPUT"
fi
- name: Point compose at this build
run: |
echo "IMAGE_TAG=${{ steps.vars.outputs.tag }}" > /opt/robot-market-front/.env
- name: Deploy via compose
id: deploy
run: |
docker compose --env-file /opt/robot-market-front/.env \
-f /opt/robot-market-front/docker-compose.yml \
up -d --force-recreate
- name: Health check (retries for ~30s)
id: health
run: |
for i in $(seq 1 15); do
if docker exec robot-market node -e "
require('http').get('http://localhost:3000', res => {
process.exit(res.statusCode < 400 ? 0 : 1);
}).on('error', () => process.exit(1));
" 2>/dev/null; then
echo "Container is healthy"
exit 0
fi
echo "Not ready yet, retrying..."
sleep 2
done
echo "Health check failed after 30s"
exit 1
- name: Roll back after deployment or health check failure
if: ${{ failure() && steps.backup.outputs.available == 'true' && (steps.deploy.outcome == 'failure' || steps.health.outcome == 'failure') }}
run: |
if [ -f /opt/robot-market-front/.env.previous ]; then
cp /opt/robot-market-front/.env.previous /opt/robot-market-front/.env
docker compose --env-file /opt/robot-market-front/.env \
-f /opt/robot-market-front/docker-compose.yml \
up -d --force-recreate
echo "Rolled back to previous image."
else
echo "No previous deploy recorded — nothing to roll back to."
fi
- name: Clean up dangling (untagged) layers
run: docker image prune -f
- name: Prune old build-tagged images (keep last 5)
run: |
KEEP=5
CURRENT_TAG=$(grep IMAGE_TAG /opt/robot-market-front/.env 2>/dev/null | cut -d= -f2)
PREVIOUS_TAG=$(grep IMAGE_TAG /opt/robot-market-front/.env.previous 2>/dev/null | cut -d= -f2)
docker images robot-market --format '{{.Tag}} {{.CreatedAt}}' \
| sort -t" " -k2 -r \
| tail -n +$((KEEP + 1)) \
| cut -f1 \
| while read -r tag; do
if [ "$tag" != "$CURRENT_TAG" ] && [ "$tag" != "$PREVIOUS_TAG" ] && [ "$tag" != "<none>" ]; then
echo "Removing old image robot-market:$tag"
docker rmi "robot-market:$tag" 2>/dev/null || true
fi
done