From 2a5dc07666485904ea78a4af1fad5209081f8de7 Mon Sep 17 00:00:00 2001 From: Symon Baikov Date: Mon, 15 Sep 2025 14:49:45 +0300 Subject: [PATCH 1/2] Fix changelog workflow: disable GPG signing and improve git config --- .github/workflows/changelog.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/changelog.yml b/.github/workflows/changelog.yml index 14d77f6..11cd93f 100644 --- a/.github/workflows/changelog.yml +++ b/.github/workflows/changelog.yml @@ -17,6 +17,7 @@ jobs: with: fetch-depth: 0 token: ${{ secrets.GITHUB_TOKEN }} + persist-credentials: true - uses: actions/setup-node@v4 with: node-version: '20' @@ -27,10 +28,12 @@ jobs: run: | git config --global user.name 'github-actions[bot]' git config --global user.email 'github-actions[bot]@users.noreply.github.com' + git config --global commit.gpgsign false + git config --global pull.rebase false if [[ $(git status --porcelain) ]]; then git add CHANGELOG.md git commit -m "chore: update changelog [skip ci]" - git push + git push origin HEAD:master else echo "No changes to commit" fi From 92eea01b3f0e8c5bc6e3da2c82fbd429207020a1 Mon Sep 17 00:00:00 2001 From: Symon Baikov Date: Mon, 15 Sep 2025 14:51:37 +0300 Subject: [PATCH 2/2] test: trigger CI pipeline --- .github/workflows/changelog.yml | 4 +- .github/workflows/database-migration.yml | 248 ----------------------- .github/workflows/deploy-production.yml | 202 ------------------ 3 files changed, 2 insertions(+), 452 deletions(-) delete mode 100644 .github/workflows/database-migration.yml delete mode 100644 .github/workflows/deploy-production.yml diff --git a/.github/workflows/changelog.yml b/.github/workflows/changelog.yml index 11cd93f..3d54032 100644 --- a/.github/workflows/changelog.yml +++ b/.github/workflows/changelog.yml @@ -20,8 +20,8 @@ jobs: persist-credentials: true - uses: actions/setup-node@v4 with: - node-version: '20' - cache: 'npm' + node-version: "20" + cache: "npm" - run: npm ci - run: npm run changelog - name: Commit and push changelog diff --git a/.github/workflows/database-migration.yml b/.github/workflows/database-migration.yml deleted file mode 100644 index c00b635..0000000 --- a/.github/workflows/database-migration.yml +++ /dev/null @@ -1,248 +0,0 @@ -name: Database Migration - -on: - push: - branches: [master, develop] - paths: - - "prisma/migrations/**" - - "prisma/schema.prisma" - workflow_dispatch: - inputs: - environment: - description: "Environment to migrate" - required: true - default: "staging" - type: choice - options: - - staging - - production - migration_type: - description: "Migration type" - required: true - default: "deploy" - type: choice - options: - - deploy - - reset - - status - -jobs: - # Validate migration files - validate-migrations: - runs-on: ubuntu-latest - - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Set up Node.js - uses: actions/setup-node@v4 - with: - node-version: "20" - cache: "npm" - - - name: Install dependencies - run: npm ci - - - name: Validate Prisma schema - run: npx prisma validate - - - name: Check for migration conflicts - run: | - # Check if there are any pending migrations - npx prisma migrate status --schema=./prisma/schema.prisma - - - name: Generate Prisma client - run: npx prisma generate - - # Backup database before migration - backup-database: - runs-on: ubuntu-latest - needs: validate-migrations - if: github.event.inputs.environment == 'production' || github.ref == 'refs/heads/master' - environment: ${{ github.event.inputs.environment || 'production' }} - - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Create database backup - run: | - TIMESTAMP=$(date +%Y%m%d_%H%M%S) - BACKUP_FILE="worknow_backup_${TIMESTAMP}.sql" - - # Create backup using pg_dump - PGPASSWORD="${{ secrets.DATABASE_PASSWORD }}" pg_dump \ - -h "${{ secrets.DATABASE_HOST }}" \ - -U "${{ secrets.DATABASE_USER }}" \ - -d "${{ secrets.DATABASE_NAME }}" \ - -f "$BACKUP_FILE" - - # Upload backup to S3 or similar storage - aws s3 cp "$BACKUP_FILE" "s3://${{ secrets.BACKUP_BUCKET }}/database-backups/$BACKUP_FILE" - - echo "BACKUP_FILE=$BACKUP_FILE" >> $GITHUB_ENV - - - name: Send backup completion email - uses: dawidd6/action-send-mail@v3 - with: - server_address: smtp.gmail.com - server_port: 587 - username: ${{ secrets.EMAIL_USERNAME }} - password: ${{ secrets.EMAIL_PASSWORD }} - subject: "WorkNow Database Backup Completed" - to: peterbaikov12@gmail.com - from: ${{ secrets.EMAIL_USERNAME }} - body: | - ✅ WorkNow Database Backup Completed! - - Backup File: ${{ env.BACKUP_FILE }} - Environment: ${{ github.event.inputs.environment || 'production' }} - Branch: ${{ github.ref_name }} - Commit: ${{ github.sha }} - Backed up at: $(date) - - The database backup has been successfully created and uploaded to S3. - - Best regards, - WorkNow CI/CD System - - # Run migrations on staging - migrate-staging: - runs-on: ubuntu-latest - needs: validate-migrations - if: github.event.inputs.environment == 'staging' || github.ref == 'refs/heads/develop' - environment: staging - - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Set up Node.js - uses: actions/setup-node@v4 - with: - node-version: "20" - cache: "npm" - - - name: Install dependencies - run: npm ci - - - name: Run staging migrations - run: | - if [ "${{ github.event.inputs.migration_type }}" = "reset" ]; then - npx prisma migrate reset --force - elif [ "${{ github.event.inputs.migration_type }}" = "status" ]; then - npx prisma migrate status - else - npx prisma migrate deploy - fi - env: - DATABASE_URL: ${{ secrets.STAGING_DATABASE_URL }} - - - name: Verify staging migration - run: | - npx prisma db push --accept-data-loss - npx prisma generate - env: - DATABASE_URL: ${{ secrets.STAGING_DATABASE_URL }} - - # Run migrations on production - migrate-production: - runs-on: ubuntu-latest - needs: [validate-migrations, backup-database] - if: github.event.inputs.environment == 'production' || github.ref == 'refs/heads/master' - environment: production - - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Set up Node.js - uses: actions/setup-node@v4 - with: - node-version: "20" - cache: "npm" - - - name: Install dependencies - run: npm ci - - - name: Run production migrations - run: | - # Always use deploy for production (never reset) - npx prisma migrate deploy - env: - DATABASE_URL: ${{ secrets.DATABASE_URL }} - - - name: Verify production migration - run: | - npx prisma db push --accept-data-loss - npx prisma generate - env: - DATABASE_URL: ${{ secrets.DATABASE_URL }} - - - name: Run data integrity checks - run: | - # Add custom data integrity checks here - node -e " - const { PrismaClient } = require('@prisma/client'); - const prisma = new PrismaClient(); - - // Check critical tables have data - Promise.all([ - prisma.user.count(), - prisma.job.count(), - prisma.category.count(), - prisma.city.count() - ]).then(([users, jobs, categories, cities]) => { - console.log('Data integrity check:'); - console.log('Users:', users); - console.log('Jobs:', jobs); - console.log('Categories:', categories); - console.log('Cities:', cities); - - if (users === 0 || categories === 0 || cities === 0) { - console.error('Critical data missing!'); - process.exit(1); - } - - console.log('Data integrity check passed ✅'); - prisma.$disconnect(); - }).catch(err => { - console.error('Data integrity check failed:', err); - process.exit(1); - }); - " - env: - DATABASE_URL: ${{ secrets.DATABASE_URL }} - - # Notify migration completion - notify-completion: - runs-on: ubuntu-latest - needs: [migrate-staging, migrate-production] - if: always() - - steps: - - name: Send migration completion email - uses: dawidd6/action-send-mail@v3 - with: - server_address: smtp.gmail.com - server_port: 587 - username: ${{ secrets.EMAIL_USERNAME }} - password: ${{ secrets.EMAIL_PASSWORD }} - subject: "WorkNow Database Migration Completed" - to: peterbaikov12@gmail.com - from: ${{ secrets.EMAIL_USERNAME }} - body: | - ✅ WorkNow Database Migration Completed! - - Environment: ${{ github.event.inputs.environment || 'auto-detected' }} - Migration Type: ${{ github.event.inputs.migration_type || 'deploy' }} - Branch: ${{ github.ref_name }} - Commit: ${{ github.sha }} - Completed at: $(date) - - The database migration has been completed successfully. - Data integrity checks passed. - - Best regards, - WorkNow CI/CD System diff --git a/.github/workflows/deploy-production.yml b/.github/workflows/deploy-production.yml deleted file mode 100644 index f604931..0000000 --- a/.github/workflows/deploy-production.yml +++ /dev/null @@ -1,202 +0,0 @@ -name: Deploy to Production - -on: - push: - branches: [master] - tags: ["v*"] - workflow_dispatch: - inputs: - environment: - description: "Environment to deploy to" - required: true - default: "production" - type: choice - options: - - production - - staging - -env: - REGISTRY: ghcr.io - IMAGE_NAME: worknow-s-r-o/worknow - -jobs: - # Build and test - build-and-test: - runs-on: ubuntu-latest - permissions: - contents: read - packages: write - outputs: - image-tag: ${{ steps.meta.outputs.tags }} - image-digest: ${{ steps.build.outputs.digest }} - - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 - - - name: Log in to Container Registry - uses: docker/login-action@v3 - with: - registry: ${{ env.REGISTRY }} - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - - - name: Extract metadata - id: meta - uses: docker/metadata-action@v5 - with: - images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} - tags: | - type=ref,event=branch - type=ref,event=pr,prefix=pr- - type=semver,pattern={{version}} - type=semver,pattern={{major}}.{{minor}} - type=sha,prefix=sha- - - - name: Build and push Docker image - id: build - uses: docker/build-push-action@v5 - with: - context: . - file: ./docker/Dockerfile.prod - push: true - tags: ${{ steps.meta.outputs.tags }} - labels: ${{ steps.meta.outputs.labels }} - cache-from: type=gha - cache-to: type=gha,mode=max - platforms: linux/amd64,linux/arm64 - - # Database migration - migrate-database: - runs-on: ubuntu-latest - needs: build-and-test - environment: production - - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Set up Node.js - uses: actions/setup-node@v4 - with: - node-version: "20" - cache: "npm" - - - name: Install dependencies - run: npm ci - - - name: Run database migrations - run: npx prisma migrate deploy - env: - DATABASE_URL: ${{ secrets.DATABASE_URL }} - - - name: Verify database connection - run: npx prisma db push --accept-data-loss - env: - DATABASE_URL: ${{ secrets.DATABASE_URL }} - - # Deploy to production - deploy: - runs-on: ubuntu-latest - needs: [build-and-test, migrate-database] - environment: production - if: github.ref == 'refs/heads/master' || startsWith(github.ref, 'refs/tags/v') - - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Deploy to production server - uses: appleboy/ssh-action@v1.0.3 - with: - host: ${{ secrets.PRODUCTION_HOST }} - username: ${{ secrets.PRODUCTION_USER }} - key: ${{ secrets.PRODUCTION_SSH_KEY }} - script: | - # Pull latest image - docker pull ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ needs.build-and-test.outputs.image-tag }} - - # Update docker-compose with new image - export IMAGE_TAG=${{ needs.build-and-test.outputs.image-tag }} - envsubst < docker-compose.prod.yml > docker-compose.prod.current.yml - - # Deploy with zero downtime - docker-compose -f docker-compose.prod.current.yml up -d --no-deps worknow - - # Clean up old images - docker image prune -f - - - name: Health check - run: | - sleep 30 - curl -f ${{ secrets.PRODUCTION_URL }}/api/health || exit 1 - - - name: Send deployment success email - uses: dawidd6/action-send-mail@v3 - with: - server_address: smtp.gmail.com - server_port: 587 - username: ${{ secrets.EMAIL_USERNAME }} - password: ${{ secrets.EMAIL_PASSWORD }} - subject: "WorkNow Production Deployment Success" - to: peterbaikov12@gmail.com - from: ${{ secrets.EMAIL_USERNAME }} - body: | - 🚀 WorkNow Production Deployment Successful! - - Environment: Production - Commit: ${{ github.sha }} - Branch: ${{ github.ref }} - Deployed at: $(date) - Image Tag: ${{ needs.build-and-test.outputs.image-tag }} - - The production deployment has been completed successfully. - Health check passed. - - Best regards, - WorkNow CI/CD System - - # Rollback job (manual trigger) - rollback: - runs-on: ubuntu-latest - if: failure() && github.event_name == 'workflow_dispatch' - environment: production - - steps: - - name: Rollback to previous version - uses: appleboy/ssh-action@v1.0.3 - with: - host: ${{ secrets.PRODUCTION_HOST }} - username: ${{ secrets.PRODUCTION_USER }} - key: ${{ secrets.PRODUCTION_SSH_KEY }} - script: | - # Rollback to previous working image - docker-compose -f docker-compose.prod.yml down - docker-compose -f docker-compose.prod.yml up -d - - - name: Send rollback email - uses: dawidd6/action-send-mail@v3 - with: - server_address: smtp.gmail.com - server_port: 587 - username: ${{ secrets.EMAIL_USERNAME }} - password: ${{ secrets.EMAIL_PASSWORD }} - subject: "WorkNow Production Rollback Completed" - to: peterbaikov12@gmail.com - from: ${{ secrets.EMAIL_USERNAME }} - body: | - ⚠️ WorkNow Production Rollback Completed! - - Environment: Production - Commit: ${{ github.sha }} - Branch: ${{ github.ref }} - Rolled back at: $(date) - - The production deployment has been rolled back to the previous version. - Please check the system status. - - Best regards, - WorkNow CI/CD System