littleshop/.gitea/workflows/build-and-deploy.yml
SysAdmin 47e43d4ff8 ci: Migrate from GitLab CI/CD to Gitea Actions with CT109 pre-production
**Migration Complete:**
- Removed GitLab CI/CD configuration (.gitlab-ci.yml)
- Created Gitea Actions workflows (.gitea/workflows/)
- Disabled automatic production deployment (manual only)
- Added pre-production deployment to CT109 Docker container

**New Workflows:**
- build-and-deploy.yml: Main CI/CD pipeline with CT109 deployment
- rollback.yml: Manual rollback capability
- README.md: Comprehensive workflow documentation

**Pre-Production Environment (CT109):**
- Host: 10.0.0.51
- User: sysadmin
- Port: 22
- Deploys on push to development/main branches
- Access URL: http://ct109.local:5100

**Documentation:**
- CI_CD_MIGRATION_GITEA.md: Complete migration guide
- CI_CD_CT109_PREPRODUCTION.md: CT109 deployment architecture
- GITEA_SECRETS_SETUP_GUIDE.md: Secrets configuration instructions

**Git Remote Updated:**
- Migrated from GitLab (gitlab.silverlabs.uk) to Gitea (git.silverlabs.uk)
- Using token authentication for push/pull operations

**Next Steps:**
1. Push code to Gitea to create repository
2. Add CT109 secrets via Gitea UI (CT109_HOST, CT109_SSH_PORT, CT109_USER, CT109_SSH_KEY)
3. Test pre-production deployment workflow

🚀 Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-14 19:10:14 +00:00

369 lines
13 KiB
YAML

name: Build and Deploy LittleShop
on:
push:
branches:
- main
- development
tags:
- 'v*'
workflow_dispatch:
env:
DOCKER_BUILDKIT: 1
COMPOSE_DOCKER_CLI_BUILD: 1
jobs:
build-littleshop:
name: Build LittleShop Docker Image
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Build LittleShop image
run: |
echo "Building LittleShop Docker image"
docker build --no-cache -t littleshop:${{ github.sha }} .
docker tag littleshop:${{ github.sha }} littleshop:latest
if [[ "${{ github.ref_type }}" == "tag" ]]; then
echo "Tagging as version ${{ github.ref_name }}"
docker tag littleshop:${{ github.sha }} littleshop:${{ github.ref_name }}
fi
- name: Save LittleShop image
run: |
mkdir -p /tmp/docker-images
docker save littleshop:${{ github.sha }} | gzip > /tmp/docker-images/littleshop.tar.gz
- name: Upload LittleShop artifact
uses: actions/upload-artifact@v4
with:
name: littleshop-image
path: /tmp/docker-images/littleshop.tar.gz
retention-days: 1
build-telebot:
name: Build TeleBot Docker Image
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Build TeleBot image
run: |
echo "Building TeleBot Docker image"
docker build --no-cache -t telebot:${{ github.sha }} -f Dockerfile.telebot .
docker tag telebot:${{ github.sha }} telebot:latest
if [[ "${{ github.ref_type }}" == "tag" ]]; then
echo "Tagging as version ${{ github.ref_name }}"
docker tag telebot:${{ github.sha }} telebot:${{ github.ref_name }}
fi
- name: Save TeleBot image
run: |
mkdir -p /tmp/docker-images
docker save telebot:${{ github.sha }} | gzip > /tmp/docker-images/telebot.tar.gz
- name: Upload TeleBot artifact
uses: actions/upload-artifact@v4
with:
name: telebot-image
path: /tmp/docker-images/telebot.tar.gz
retention-days: 1
deploy-production:
name: Deploy to Production VPS (Manual Only)
needs: [build-littleshop, build-telebot]
runs-on: ubuntu-latest
if: false # Disabled - Manual deployment only via workflow_dispatch
environment:
name: production
url: https://admin.dark.side
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Download LittleShop image
uses: actions/download-artifact@v4
with:
name: littleshop-image
path: /tmp/docker-images
- name: Download TeleBot image
uses: actions/download-artifact@v4
with:
name: telebot-image
path: /tmp/docker-images
- name: Load Docker images
run: |
docker load < /tmp/docker-images/littleshop.tar.gz
docker load < /tmp/docker-images/telebot.tar.gz
- name: Set up SSH
run: |
mkdir -p ~/.ssh
chmod 700 ~/.ssh
echo "${{ secrets.VPS_SSH_KEY }}" > ~/.ssh/deploy_key
chmod 600 ~/.ssh/deploy_key
ssh-keyscan -p ${{ secrets.VPS_PORT }} ${{ secrets.VPS_HOST }} >> ~/.ssh/known_hosts 2>/dev/null
- name: Transfer Docker images to VPS
run: |
echo "Copying LittleShop image to VPS..."
docker save littleshop:${{ github.sha }} | \
ssh -i ~/.ssh/deploy_key -p ${{ secrets.VPS_PORT }} ${{ secrets.VPS_USER }}@${{ secrets.VPS_HOST }} \
"docker load"
echo "Copying TeleBot image to VPS..."
docker save telebot:${{ github.sha }} | \
ssh -i ~/.ssh/deploy_key -p ${{ secrets.VPS_PORT }} ${{ secrets.VPS_USER }}@${{ secrets.VPS_HOST }} \
"docker load"
- name: Deploy to VPS
run: |
ssh -i ~/.ssh/deploy_key -p ${{ secrets.VPS_PORT }} ${{ secrets.VPS_USER }}@${{ secrets.VPS_HOST }} bash -s << 'ENDSSH'
set -e
export VERSION="${{ github.sha }}"
# Tag the images
docker tag littleshop:$VERSION localhost:5000/littleshop:$VERSION
docker tag littleshop:$VERSION localhost:5000/littleshop:latest
docker tag telebot:$VERSION localhost:5000/telebot:$VERSION
docker tag telebot:$VERSION localhost:5000/telebot:latest
# Push to local registry
echo "Pushing images to local Docker registry..."
docker push localhost:5000/littleshop:$VERSION || true
docker push localhost:5000/littleshop:latest || true
docker push localhost:5000/telebot:$VERSION || true
docker push localhost:5000/telebot:latest || true
# Navigate to deployment directory
cd /opt/littleshop
# Force stop all littleshop containers
echo "Stopping all littleshop containers..."
docker stop $(docker ps -q --filter "name=littleshop") 2>/dev/null || true
docker rm $(docker ps -aq --filter "name=littleshop") 2>/dev/null || true
# Stop TeleBot container
echo "Stopping TeleBot container..."
docker stop telebot-service 2>/dev/null || true
docker rm telebot-service 2>/dev/null || true
# Stop services with compose
echo "Stopping compose services..."
docker-compose down --remove-orphans || true
# Prune unused Docker networks
echo "Cleaning up Docker networks..."
docker network prune -f || true
# Apply database migrations if they exist
echo "Checking for database migrations..."
if [ -d "LittleShop/Migrations" ] && [ -n "$(ls -A LittleShop/Migrations/*.sql 2>/dev/null)" ]; then
echo "Found migration files, applying to database..."
for migration in LittleShop/Migrations/*.sql; do
migration_name=$(basename "$migration")
echo "Applying migration: $migration_name"
docker run --rm -v littleshop_littleshop_data:/data -v $(pwd)/LittleShop/Migrations:/migrations alpine:latest sh -c "
apk add --no-cache sqlite > /dev/null 2>&1
echo 'Creating backup before migration...'
cp /data/littleshop-production.db /data/littleshop-production.db.backup-\$(date +%Y%m%d-%H%M%S) 2>/dev/null || true
echo 'Applying migration: $migration_name'
sqlite3 /data/littleshop-production.db < /migrations/$migration_name
echo 'Migration applied successfully'
"
done
else
echo "No migration files found, skipping..."
fi
# Start services with new images
echo "Starting services with new images..."
docker-compose up -d
# Start TeleBot with new image
echo "Starting TeleBot with new image..."
docker run -d \
--name telebot-service \
--restart unless-stopped \
--network silverpay_silverpay-network \
-e ASPNETCORE_URLS=http://+:5010 \
-e LittleShop__ApiUrl=http://littleshop:5000 \
-e LittleShop__UseTor=false \
-e Privacy__EnableTor=true \
-e Privacy__TorSocksHost=tor-gateway \
-e Privacy__TorSocksPort=9050 \
localhost:5000/telebot:latest
# Connect TeleBot to LittleShop network
docker network connect littleshop_littleshop-network telebot-service
# Wait for startup
echo "Waiting for services to start..."
sleep 30
# Health check
echo "Running health checks..."
for i in 1 2 3 4 5 6; do
if curl -f -s http://localhost:5100/api/catalog/products > /dev/null 2>&1; then
echo "✅ Deployment successful - health check passed"
exit 0
fi
echo "Health check attempt $i/6 failed, waiting..."
sleep 10
done
echo "❌ Health check failed after deployment"
docker logs littleshop --tail 50
docker logs telebot-service --tail 30
exit 1
ENDSSH
- name: Cleanup
if: always()
run: |
rm -f ~/.ssh/deploy_key
deploy-preproduction:
name: Deploy to Pre-Production (CT109)
needs: [build-littleshop, build-telebot]
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/development' || github.ref == 'refs/heads/main'
environment:
name: pre-production
url: http://ct109.local
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Download LittleShop image
uses: actions/download-artifact@v4
with:
name: littleshop-image
path: /tmp/docker-images
- name: Download TeleBot image
uses: actions/download-artifact@v4
with:
name: telebot-image
path: /tmp/docker-images
- name: Load Docker images
run: |
docker load < /tmp/docker-images/littleshop.tar.gz
docker load < /tmp/docker-images/telebot.tar.gz
- name: Set up SSH for CT109
run: |
mkdir -p ~/.ssh
chmod 700 ~/.ssh
echo "${{ secrets.CT109_SSH_KEY }}" > ~/.ssh/deploy_key
chmod 600 ~/.ssh/deploy_key
ssh-keyscan -p ${{ secrets.CT109_SSH_PORT }} ${{ secrets.CT109_HOST }} >> ~/.ssh/known_hosts 2>/dev/null
- name: Transfer Docker images to CT109
run: |
echo "Copying LittleShop image to CT109..."
docker save littleshop:${{ github.sha }} | \
ssh -i ~/.ssh/deploy_key -p ${{ secrets.CT109_SSH_PORT }} ${{ secrets.CT109_USER }}@${{ secrets.CT109_HOST }} \
"docker load"
echo "Copying TeleBot image to CT109..."
docker save telebot:${{ github.sha }} | \
ssh -i ~/.ssh/deploy_key -p ${{ secrets.CT109_SSH_PORT }} ${{ secrets.CT109_USER }}@${{ secrets.CT109_HOST }} \
"docker load"
- name: Deploy to CT109
run: |
ssh -i ~/.ssh/deploy_key -p ${{ secrets.CT109_SSH_PORT }} ${{ secrets.CT109_USER }}@${{ secrets.CT109_HOST }} bash -s << 'ENDSSH'
set -e
export VERSION="${{ github.sha }}"
# Tag the images
docker tag littleshop:$VERSION littleshop:latest
docker tag telebot:$VERSION telebot:latest
# Navigate to deployment directory
cd /opt/littleshop || mkdir -p /opt/littleshop && cd /opt/littleshop
# Stop existing containers
echo "Stopping existing containers..."
docker stop littleshop telebot-service 2>/dev/null || true
docker rm littleshop telebot-service 2>/dev/null || true
# Prune unused Docker networks
echo "Cleaning up Docker networks..."
docker network prune -f || true
# Create networks if they don't exist
docker network create littleshop-network 2>/dev/null || true
docker network create silverpay-network 2>/dev/null || true
# Start LittleShop container
echo "Starting LittleShop container..."
docker run -d \
--name littleshop \
--restart unless-stopped \
--network littleshop-network \
-p 5100:5000 \
-v littleshop-data:/app/data \
-e ASPNETCORE_URLS=http://+:5000 \
-e ASPNETCORE_ENVIRONMENT=Development \
littleshop:latest
# Start TeleBot container
echo "Starting TeleBot container..."
docker run -d \
--name telebot-service \
--restart unless-stopped \
--network silverpay-network \
-e ASPNETCORE_URLS=http://+:5010 \
-e LittleShop__ApiUrl=http://littleshop:5000 \
-e LittleShop__UseTor=false \
telebot:latest
# Connect TeleBot to LittleShop network
docker network connect littleshop-network telebot-service
# Wait for startup
echo "Waiting for services to start..."
sleep 15
# Health check
echo "Running health checks..."
for i in 1 2 3 4 5; do
if curl -f -s http://localhost:5100/api/catalog/products > /dev/null 2>&1; then
echo "✅ Pre-production deployment successful - health check passed"
docker ps --filter "name=littleshop" --filter "name=telebot"
exit 0
fi
echo "Health check attempt $i/5 failed, waiting..."
sleep 10
done
echo "❌ Health check failed after deployment"
echo "LittleShop logs:"
docker logs littleshop --tail 50
echo ""
echo "TeleBot logs:"
docker logs telebot-service --tail 30
exit 1
ENDSSH
- name: Cleanup
if: always()
run: |
rm -f ~/.ssh/deploy_key