Files
AFC-Demo/.gitea/workflows/deploy-synology.yml
T
cbazzaandClaude 23475f650f
Build and Deploy to Synology NAS / test (push) Successful in 1h1m38s
Build and Deploy to Synology NAS / build (push) Successful in 2h34m26s
Build and Deploy to Synology NAS / deploy (push) Failing after 3m41s
Build and Deploy to Synology NAS / notify (push) Failing after 14m7s
fix: downgrade artifact actions to v3 for Gitea compatibility
- Changed upload-artifact from v4 to v3
- Changed download-artifact from v4 to v3
- Gitea Actions does not support artifact v4 API (GHES compatibility issue)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-18 08:13:10 +01:00

232 lines
7.2 KiB
YAML

name: Build and Deploy to Synology NAS
on:
push:
branches:
- main
- develop
pull_request:
branches:
- main
env:
DOCKER_IMAGE: laravel-app
DOCKER_REGISTRY: ${{ secrets.SYNOLOGY_HOST }}:5000 # Synology Docker Registry Port
jobs:
# Job 1: Run Tests
test:
runs-on: ubuntu-latest
steps:
- name: Checkout Code
uses: actions/checkout@v4
with:
fetch-depth: 1
- name: Validate Conventional Commit (subject line only)
id: validate
run: |
SUBJECT="$(git log -1 --pretty=%s)"
echo "Commit subject: $SUBJECT"
if echo "$SUBJECT" | grep -Eq '^(feat|fix|docs|style|refactor|perf|test|chore|build|ci|revert)(\(.+\))?: .+'; then
echo "valid=true" >> "$GITHUB_OUTPUT"
else
echo "valid=false" >> "$GITHUB_OUTPUT"
fi
- name: Setup PHP
if: ${{ steps.validate.outputs.valid == 'true' }}
uses: shivammathur/setup-php@v2
with:
php-version: '8.4'
extensions: mbstring, xml, ctype, json, bcmath, pdo, pdo_sqlite
coverage: none
- name: Install Composer Dependencies
if: ${{ steps.validate.outputs.valid == 'true' }}
run: composer install --prefer-dist --no-progress --no-suggest
- name: Setup Node.js
if: ${{ steps.validate.outputs.valid == 'true' }}
uses: actions/setup-node@v4
with:
node-version: '20'
- name: Install NPM Dependencies
if: ${{ steps.validate.outputs.valid == 'true' }}
run: npm ci
- name: Build Frontend Assets
if: ${{ steps.validate.outputs.valid == 'true' }}
run: npm run build
- name: Run Tests
if: ${{ steps.validate.outputs.valid == 'true' }}
run: php artisan test --exclude-group=backend-db
# Job 2: Build and Push Docker Image
build:
runs-on: ubuntu-latest
needs: test
if: github.event_name == 'push'
steps:
- name: Checkout Code
uses: actions/checkout@v4
- name: Validate Conventional Commit
id: validate
run: |
SUBJECT="$(git log -1 --pretty=%s)"
echo "Commit subject: $SUBJECT"
if echo "$SUBJECT" | grep -Eq '^(feat|fix|docs|style|refactor|perf|test|chore|build|ci|revert)(\(.+\))?: .+'; then
echo "valid=true" >> "$GITHUB_OUTPUT"
else
echo "valid=false" >> "$GITHUB_OUTPUT"
fi
- name: Stop if not a Conventional Commit
if: ${{ steps.validate.outputs.valid != 'true' }}
run: |
echo "Latest commit is not a valid Conventional Commit. Skipping build."
exit 0
- name: Set up Docker Buildx
if: ${{ steps.validate.outputs.valid == 'true' }}
uses: docker/setup-buildx-action@v3
- name: Determine Docker Tag
id: docker_tag
if: ${{ steps.validate.outputs.valid == 'true' }}
run: |
if [ "${{ github.ref_name }}" == "main" ]; then
echo "tag=latest" >> "$GITHUB_OUTPUT"
echo "env=production" >> "$GITHUB_OUTPUT"
else
echo "tag=${{ github.ref_name }}" >> "$GITHUB_OUTPUT"
echo "env=staging" >> "$GITHUB_OUTPUT"
fi
- name: Build Docker Image
if: ${{ steps.validate.outputs.valid == 'true' }}
uses: docker/build-push-action@v6
with:
context: .
file: ./Dockerfile
push: false
load: true
tags: ${{ env.DOCKER_IMAGE }}:${{ steps.docker_tag.outputs.tag }}
- name: Save Docker Image
if: ${{ steps.validate.outputs.valid == 'true' }}
run: |
docker save ${{ env.DOCKER_IMAGE }}:${{ steps.docker_tag.outputs.tag }} | gzip > laravel-app.tar.gz
- name: Upload Docker Image Artifact
if: ${{ steps.validate.outputs.valid == 'true' }}
uses: actions/upload-artifact@v3
with:
name: docker-image
path: laravel-app.tar.gz
retention-days: 1
# Job 3: Deploy to Synology NAS
deploy:
runs-on: ubuntu-latest
needs: build
if: github.event_name == 'push' && (github.ref_name == 'main' || github.ref_name == 'develop')
steps:
- name: Checkout Code
uses: actions/checkout@v4
- name: Download Docker Image Artifact
uses: actions/download-artifact@v3
with:
name: docker-image
- name: Determine Environment
id: env
run: |
if [ "${{ github.ref_name }}" == "main" ]; then
echo "env=production" >> "$GITHUB_OUTPUT"
else
echo "env=staging" >> "$GITHUB_OUTPUT"
fi
- name: Setup SSH
run: |
mkdir -p ~/.ssh
echo "${{ secrets.SYNOLOGY_SSH_KEY }}" > ~/.ssh/synology_key
chmod 600 ~/.ssh/synology_key
ssh-keyscan -H ${{ secrets.SYNOLOGY_HOST }} >> ~/.ssh/known_hosts
- name: Copy Files to Synology
run: |
# Transfer Docker Image
scp -i ~/.ssh/synology_key laravel-app.tar.gz \
${{ secrets.SYNOLOGY_USER }}@${{ secrets.SYNOLOGY_HOST }}:/volume1/docker/laravel-app/
# Transfer Docker Compose file
scp -i ~/.ssh/synology_key docker-compose.synology.yml \
${{ secrets.SYNOLOGY_USER }}@${{ secrets.SYNOLOGY_HOST }}:/volume1/docker/laravel-app/
# Transfer deployment script
scp -i ~/.ssh/synology_key scripts/deploy-synology.sh \
${{ secrets.SYNOLOGY_USER }}@${{ secrets.SYNOLOGY_HOST }}:/volume1/docker/laravel-app/
- name: Deploy on Synology
run: |
ssh -i ~/.ssh/synology_key \
${{ secrets.SYNOLOGY_USER }}@${{ secrets.SYNOLOGY_HOST }} \
"cd /volume1/docker/laravel-app && chmod +x deploy-synology.sh && ./deploy-synology.sh"
- name: Health Check
run: |
sleep 10 # Wait for container to start
# Check if the app is responding
SYNOLOGY_IP="${{ secrets.SYNOLOGY_HOST }}"
MAX_RETRIES=30
RETRY_COUNT=0
while [ $RETRY_COUNT -lt $MAX_RETRIES ]; do
if curl -f -s http://$SYNOLOGY_IP:8080/health > /dev/null 2>&1; then
echo "✅ Application is healthy!"
exit 0
fi
echo "⏳ Waiting for application to be ready... ($RETRY_COUNT/$MAX_RETRIES)"
sleep 5
RETRY_COUNT=$((RETRY_COUNT + 1))
done
echo "❌ Health check failed after $MAX_RETRIES attempts"
exit 1
- name: Cleanup
if: always()
run: |
rm -f ~/.ssh/synology_key
ssh -i ~/.ssh/synology_key \
${{ secrets.SYNOLOGY_USER }}@${{ secrets.SYNOLOGY_HOST }} \
"rm -f /volume1/docker/laravel-app/laravel-app.tar.gz" || true
# Job 4: Notify on Success/Failure (optional)
notify:
runs-on: ubuntu-latest
needs: [test, build, deploy]
if: always()
steps:
- name: Deployment Status
run: |
if [ "${{ needs.deploy.result }}" == "success" ]; then
echo "✅ Deployment to Synology NAS successful!"
echo "🌐 Application available at: http://${{ secrets.SYNOLOGY_HOST }}:8080"
else
echo "❌ Deployment failed. Check the logs for details."
exit 1
fi