name: CI/CD Pipeline (Simple) on: push: branches: [ main, production ] pull_request: branches: [ main, production ] env: NODE_VERSION: '20' DOCKER_IMAGE: portfolio-app CONTAINER_NAME: portfolio-app jobs: # Single job that does everything for non-production branches test-and-build: runs-on: ubuntu-latest if: github.ref != 'refs/heads/production' steps: - name: Checkout code uses: actions/checkout@v3 - name: Setup Node.js uses: actions/setup-node@v3 with: node-version: ${{ env.NODE_VERSION }} cache: 'npm' - name: Install dependencies run: npm ci - name: Run linting run: npm run lint - name: Run tests run: npm run test - name: Build application run: npm run build - name: Run security scan run: | echo "🔍 Running npm audit..." npm audit --audit-level=high || echo "⚠️ Some vulnerabilities found, but continuing..." # Production deployment pipeline production: runs-on: ubuntu-latest if: github.ref == 'refs/heads/production' steps: - name: Checkout code uses: actions/checkout@v3 - name: Setup Node.js uses: actions/setup-node@v3 with: node-version: ${{ env.NODE_VERSION }} cache: 'npm' - name: Install dependencies run: npm ci - name: Run linting run: npm run lint - name: Run tests run: npm run test - name: Build application run: npm run build - name: Run security scan run: | echo "🔍 Running npm audit..." npm audit --audit-level=high || echo "⚠️ Some vulnerabilities found, but continuing..." - name: Build Docker image run: | docker build -t ${{ env.DOCKER_IMAGE }}:latest . docker tag ${{ env.DOCKER_IMAGE }}:latest ${{ env.DOCKER_IMAGE }}:$(date +%Y%m%d-%H%M%S) - name: Stop existing services run: | docker-compose -f docker-compose.workflow.yml down || true - name: Verify secrets before deployment run: | echo "🔍 Verifying secrets..." if [ -z "${{ secrets.NEXT_PUBLIC_BASE_URL }}" ]; then echo "❌ NEXT_PUBLIC_BASE_URL secret is missing!" exit 1 fi if [ -z "${{ secrets.MY_EMAIL }}" ]; then echo "❌ MY_EMAIL secret is missing!" exit 1 fi if [ -z "${{ secrets.ADMIN_BASIC_AUTH }}" ]; then echo "❌ ADMIN_BASIC_AUTH secret is missing!" exit 1 fi echo "✅ All required secrets are present" - name: Start services with Docker Compose run: | docker-compose -f docker-compose.workflow.yml up -d env: NEXT_PUBLIC_BASE_URL: ${{ secrets.NEXT_PUBLIC_BASE_URL }} MY_EMAIL: ${{ secrets.MY_EMAIL }} MY_INFO_EMAIL: ${{ secrets.MY_INFO_EMAIL }} MY_PASSWORD: ${{ secrets.MY_PASSWORD }} MY_INFO_PASSWORD: ${{ secrets.MY_INFO_PASSWORD }} ADMIN_BASIC_AUTH: ${{ secrets.ADMIN_BASIC_AUTH }} - name: Wait for container to be ready run: | sleep 10 timeout 60 bash -c 'until curl -f http://localhost:3000/api/health; do sleep 2; done' - name: Health check run: | curl -f http://localhost:3000/api/health echo "✅ Deployment successful!" - name: Cleanup old images run: | docker image prune -f docker system prune -f