test #193
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: CI/CD Pipeline | |
| on: | |
| push: | |
| branches: | |
| - main | |
| pull_request: | |
| branches: | |
| - main | |
| workflow_dispatch: | |
| jobs: | |
| build-and-deploy: | |
| runs-on: ubuntu-latest | |
| services: | |
| mysql: | |
| image: mysql:8.0 | |
| env: | |
| MYSQL_DATABASE: ${{ secrets.DATABASE }} | |
| MYSQL_USER: ${{ secrets.USER }} | |
| MYSQL_PASSWORD: ${{ secrets.PASSWORD }} | |
| MYSQL_ROOT_PASSWORD: ${{ secrets.PASSWORD }} | |
| ports: | |
| - 33306:3306 | |
| options: >- | |
| --health-cmd "mysqladmin ping --silent" | |
| --health-interval 20s | |
| --health-timeout 10s | |
| --health-retries 10 | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v2 | |
| with: | |
| fetch-depth: 0 | |
| - name: Set up Node.js | |
| uses: actions/setup-node@v2 | |
| with: | |
| node-version: "16" | |
| # Add caching for dependencies | |
| - name: Cache dependencies | |
| uses: actions/cache@v2 | |
| with: | |
| path: | | |
| **/node_modules | |
| key: ${{ runner.os }}-modules-${{ hashFiles('**/package-lock.json') }} | |
| # Add caching for build outputs | |
| - name: Cache build outputs | |
| uses: actions/cache@v2 | |
| with: | |
| path: | | |
| client/dist | |
| server/public | |
| key: ${{ runner.os }}-build-${{ github.sha }} | |
| # Install server dependencies | |
| - name: Install server dependencies | |
| working-directory: ./server | |
| run: npm install | |
| # Start the Express backend | |
| - name: Start Express backend | |
| working-directory: ./server | |
| run: npm start & | |
| # Wait for Express server | |
| - name: Wait for Express server | |
| run: | | |
| echo "Waiting for Express server to be ready..." | |
| for i in {1..10}; do | |
| if curl -s http://localhost:${{ secrets.PORT }}; then | |
| echo "Express server is ready!" | |
| break | |
| fi | |
| echo "Waiting for Express server..." | |
| sleep 5 | |
| done | |
| # Run server tests | |
| - name: Test server | |
| working-directory: ./server | |
| env: | |
| PORT: ${{ secrets.PORT }} | |
| USER: ${{ secrets.USER }} | |
| HOST: 127.0.0.1 | |
| DATABASE: ${{ secrets.DATABASE }} | |
| PASSWORD: ${{ secrets.PASSWORD }} | |
| DBPORT: 33306 | |
| JWT_SECRET: ${{ secrets.JWT_SECRET }} | |
| run: npm test | |
| # Install and build frontend | |
| - name: Install and build client | |
| working-directory: ./client | |
| env: | |
| VITE_REACT_APP_CLIENT_ID: ${{ secrets.VITE_REACT_APP_CLIENT_ID }} | |
| VITE_REACT_APP_MEALS_API_ID: ${{ secrets.VITE_REACT_APP_MEALS_API_ID }} | |
| VITE_REACT_APP_MEALS_API_KEY: ${{ secrets.VITE_REACT_APP_MEALS_API_KEY }} | |
| VITE_REACT_APP_GEOCODING_API_KEY: ${{ secrets.VITE_REACT_APP_GEOCODING_API_KEY }} | |
| run: | | |
| npm install | |
| npm run build | |
| # Prepare deployment | |
| - name: Prepare for deployment | |
| run: | | |
| mkdir -p server/public | |
| cp -r client/dist/* server/public/ | |
| # Debug: List contents of directories | |
| - name: Debug - List directories | |
| run: | | |
| echo "Contents of server/public:" | |
| ls -la server/public | |
| echo "Contents of client/dist:" | |
| ls -la client/dist | |
| # Deploy to Heroku | |
| - name: Deploy to Heroku | |
| if: github.ref == 'refs/heads/main' && success() | |
| env: | |
| HEROKU_API_KEY: ${{ secrets.HEROKU_API_KEY }} | |
| run: | | |
| # Enable error logging | |
| set -x | |
| # Ensure the public directory exists and copy files | |
| mkdir -p server/public | |
| cp -r client/dist/* server/public/ | |
| # Configure Git | |
| git config --global user.email "[email protected]" | |
| git config --global user.name "CI/CD Pipeline" | |
| # Stage and commit the built files | |
| git add server/public -f | |
| git commit -m "Update frontend build [skip ci]" || echo "No changes to commit" | |
| # Install Heroku CLI if not already installed | |
| if ! command -v heroku &> /dev/null; then | |
| curl https://cli-assets.heroku.com/install.sh | sh | |
| fi | |
| # Add Heroku remote | |
| heroku git:remote -a gymero | |
| # Push to Heroku | |
| git push https://heroku:${{ secrets.HEROKU_API_KEY }}@git.heroku.com/gymero.git HEAD:main --force | |
| # If deployment fails, show Heroku logs | |
| if [ $? -ne 0 ]; then | |
| heroku logs --tail --app gymero | |
| exit 1 | |
| # Post-deployment verification | |
| - name: Verify deployment | |
| if: github.ref == 'refs/heads/main' && success() | |
| run: | | |
| echo "Waiting for deployment to stabilize..." | |
| sleep 30 | |
| curl --fail https://gymero.live || exit 1 | |
| # Debug MySQL logs if needed | |
| - name: MySQL Logs | |
| if: failure() | |
| run: docker logs $(docker ps -q --filter "ancestor=mysql:8.0") | |
| # Cleanup | |
| - name: Cleanup | |
| if: always() | |
| run: | | |
| rm -rf server/public/* | |
| git reset --hard HEAD |