Deploy BobaTalks Flowers Bot on pm2 (EC2 Instance) #133
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: Deploy BobaTalks Flowers Bot on pm2 (EC2 Instance) | |
| on: | |
| push: # runs tests on every push (no deploy) | |
| branches: [main] | |
| schedule: # checks at 09:00 UTC daily - only deploys if new commits | |
| - cron: '0 9 * * *' | |
| workflow_dispatch: # manual deploys always run | |
| jobs: | |
| check-changes: | |
| runs-on: ubuntu-latest | |
| outputs: | |
| should_deploy: ${{ steps.check.outputs.should_deploy }} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 # Fetch full history to check commits | |
| - id: check | |
| name: Check for new commits | |
| run: | | |
| if [ "${{ github.event_name }}" == "workflow_dispatch" ]; then | |
| echo "Manual trigger - will deploy" | |
| echo "should_deploy=true" >> $GITHUB_OUTPUT | |
| elif [ "${{ github.event_name }}" == "push" ]; then | |
| echo "Push event - will test only" | |
| echo "should_deploy=false" >> $GITHUB_OUTPUT | |
| else | |
| # For scheduled runs, check if there are commits in the last 24 hours | |
| COMMITS=$(git log --since="24 hours ago" --oneline | wc -l) | |
| if [ "$COMMITS" -gt 0 ]; then | |
| echo "Found $COMMITS new commit(s) in the last 24 hours - will deploy" | |
| echo "should_deploy=true" >> $GITHUB_OUTPUT | |
| else | |
| echo "No new commits in the last 24 hours - skipping deployment" | |
| echo "should_deploy=false" >> $GITHUB_OUTPUT | |
| fi | |
| fi | |
| test: | |
| needs: check-changes | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-node@v4 | |
| with: { node-version: '20' } | |
| - run: npm ci | |
| - run: npm run build | |
| - run: npm test --if-present | |
| - run: tar czf artifact.tgz dist package.json package-lock.json pm2.config.cjs | |
| - uses: actions/upload-artifact@v4 | |
| if: needs.check-changes.outputs.should_deploy == 'true' | |
| with: { name: build-artifact, path: artifact.tgz } | |
| deploy: | |
| if: needs.check-changes.outputs.should_deploy == 'true' | |
| needs: [check-changes, test] | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/download-artifact@v4 | |
| with: { name: build-artifact, path: . } | |
| - name: Guard | |
| run: | | |
| [ -n "${{ secrets.EC2_HOST }}" ] || { echo "::error::EC2_HOST is empty"; exit 1; } | |
| [ -n "${{ secrets.EC2_SSH_KEY }}" ] || { echo "::error::EC2_SSH_KEY is empty"; exit 1; } | |
| - name: Add known_hosts | |
| run: | | |
| mkdir -p ~/.ssh | |
| ssh-keyscan -H ${{ secrets.EC2_HOST }} >> ~/.ssh/known_hosts | |
| chmod 600 ~/.ssh/known_hosts | |
| - name: Ensure target dir | |
| uses: appleboy/ssh-action@v0.1.10 | |
| with: | |
| host: ${{ secrets.EC2_HOST }} | |
| username: ubuntu | |
| key: ${{ secrets.EC2_SSH_KEY }} # pass key directly | |
| script: mkdir -p ~/bobatalks | |
| - uses: appleboy/scp-action@v0.1.7 | |
| with: | |
| host: ${{ secrets.EC2_HOST }} | |
| username: ubuntu | |
| key: ${{ secrets.EC2_SSH_KEY }} | |
| source: artifact.tgz | |
| target: /home/ubuntu/bobatalks/ | |
| - uses: appleboy/ssh-action@v0.1.10 | |
| with: | |
| host: ${{ secrets.EC2_HOST }} | |
| username: ubuntu | |
| key: ${{ secrets.EC2_SSH_KEY }} | |
| script: | | |
| set -e | |
| cd ~/bobatalks | |
| tar xzf artifact.tgz | |
| # install production deps without running lifecycle scripts (skips husky) | |
| if [ -f package-lock.json ]; then | |
| npm ci --omit=dev --ignore-scripts | |
| else | |
| npm i --omit=dev --ignore-scripts | |
| fi | |
| if ! command -v pm2 >/dev/null 2>&1; then npm i -g pm2; fi | |
| if pm2 describe bobatalks >/dev/null 2>&1; then | |
| pm2 reload bobatalks | |
| else | |
| pm2 start pm2.config.cjs --only bobatalks | |
| fi | |
| pm2 save |