Merge branch 'main' of https://github.com/cs-internship/CS-Queue-Bot #41
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 | |
| env: | |
| IS_ACT: "false" | |
| on: | |
| push: | |
| branches: | |
| - main | |
| - feature/** | |
| pull_request: | |
| branches: | |
| - main | |
| permissions: | |
| contents: write | |
| jobs: | |
| test: | |
| name: 🧪 Run Tests and Coverage | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Setup Node.js 18 | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: 18 | |
| cache: "npm" | |
| - name: Install dependencies | |
| run: npm ci | |
| # - name: Run ESLint | |
| # run: npm run lint | |
| - name: Run tests and generate summary | |
| run: | | |
| npm test --silent | tee test-output.txt | |
| echo "### ✅ Test Results" >> $GITHUB_STEP_SUMMARY | |
| echo "\`\`\`" >> $GITHUB_STEP_SUMMARY | |
| cat test-output.txt >> $GITHUB_STEP_SUMMARY | |
| echo "\`\`\`" >> $GITHUB_STEP_SUMMARY | |
| - name: Upload coverage report | |
| if: ${{ env.IS_ACT != 'true' }} | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: jest-coverage | |
| path: coverage/ | |
| release: | |
| name: 🚀 Version & Release | |
| runs-on: ubuntu-latest | |
| needs: test | |
| if: github.ref == 'refs/heads/main' | |
| outputs: | |
| released: ${{ steps.get_tag.outputs.released }} | |
| tag: ${{ steps.get_tag.outputs.tag }} | |
| steps: | |
| - name: Checkout repository (full history & tags) | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| fetch-tags: true | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: 18 | |
| cache: "npm" | |
| - name: Install dependencies | |
| run: npm ci | |
| - name: Semantic Release | |
| id: semantic_release | |
| if: ${{ env.IS_ACT != 'true' }} | |
| uses: cycjimmy/semantic-release-action@v4 | |
| with: | |
| extra_plugins: | | |
| @semantic-release/changelog | |
| @semantic-release/git | |
| @semantic-release/github | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GH_PAT }} | |
| - name: Get created tag | |
| id: get_tag | |
| if: ${{ always() }} | |
| run: | | |
| if [ "${IS_ACT}" = "true" ]; then | |
| echo "tag=local-test" >> $GITHUB_OUTPUT | |
| echo "released=true" >> $GITHUB_OUTPUT | |
| else | |
| git fetch --tags || true | |
| TAGS=$(git tag --points-at HEAD || true) | |
| TAG=$(echo "$TAGS" | head -n1 | tr -d '\r\n') | |
| if [ -n "$TAG" ]; then | |
| echo "tag=$TAG" >> $GITHUB_OUTPUT | |
| echo "released=true" >> $GITHUB_OUTPUT | |
| else | |
| echo "tag=" >> $GITHUB_OUTPUT | |
| echo "released=false" >> $GITHUB_OUTPUT | |
| fi | |
| fi | |
| deploy: | |
| name: 📦 Deploy to Render | |
| runs-on: ubuntu-latest | |
| needs: release | |
| if: needs.release.outputs.released == 'true' | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: 18 | |
| cache: "npm" | |
| - name: Install dependencies | |
| run: npm ci | |
| - name: Deploy to Render | |
| if: ${{ env.IS_ACT != 'true' }} | |
| env: | |
| RENDER_API_KEY: ${{ secrets.RENDER_API_KEY }} | |
| RENDER_SERVICE_ID: ${{ secrets.RENDER_SERVICE_ID }} | |
| run: | | |
| RESPONSE=$(curl -s -o response.json -w "%{http_code}" \ | |
| -X POST "https://api.render.com/v1/services/${RENDER_SERVICE_ID}/deploys" \ | |
| -H "Accept: application/json" \ | |
| -H "Authorization: Bearer ${RENDER_API_KEY}" \ | |
| -d '') | |
| if [ "$RESPONSE" != "200" ] && [ "$RESPONSE" != "201" ]; then | |
| echo "❌ Render deploy failed with status $RESPONSE" | |
| cat response.json | |
| exit 1 | |
| fi | |
| notify-release: | |
| name: 📢 Telegram Notification (only on new tag) | |
| runs-on: ubuntu-latest | |
| needs: [release, deploy] | |
| if: needs.release.outputs.released == 'true' | |
| steps: | |
| - name: Checkout repository (full history and tags) | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| fetch-tags: true | |
| - name: Send Telegram notification | |
| env: | |
| IS_ACT: ${{ env.IS_ACT }} | |
| TELEGRAM_BOT_TOKEN: ${{ secrets.TELEGRAM_BOT_TOKEN }} | |
| TELEGRAM_CHAT_ID: ${{ secrets.TELEGRAM_CHAT_ID }} | |
| ACTION_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} | |
| RELEASE_TAG: ${{ needs.release.outputs.tag }} | |
| run: | | |
| if [ "${IS_ACT}" = "true" ]; then | |
| TAG="local-test" | |
| else | |
| TAG="${RELEASE_TAG}" | |
| fi | |
| LAST_AUTHOR="${GITHUB_ACTOR}" | |
| AUTHOR_LINK="https://github.com/${LAST_AUTHOR}" | |
| DATE=$(date +"%Y-%m-%d %H:%M:%S UTC") | |
| escape_md() { | |
| echo "$1" | sed -E 's/([_*\[\]()~`>#+=|{}.!-])/\\\1/g' | |
| } | |
| eTAG=$(escape_md "$TAG") | |
| eAuthor=$(escape_md "$LAST_AUTHOR") | |
| eAuthorLink="$AUTHOR_LINK" | |
| eActionRun="$ACTION_RUN_URL" | |
| eDate=$(escape_md "$DATE") | |
| MESSAGE="🚀 *New release published!*\n"\ | |
| "🏷️ *Version:* ${eTAG}\n"\ | |
| "👤 *Author:* [${eAuthor}](${eAuthorLink})\n"\ | |
| "🕓 *Date:* ${eDate}\n"\ | |
| "🔗 [View GitHub Action Run](${eActionRun})" | |
| curl -s -X POST "https://api.telegram.org/bot${TELEGRAM_BOT_TOKEN}/sendMessage" \ | |
| -d "chat_id=${TELEGRAM_CHAT_ID}" \ | |
| -d "text=$MESSAGE" \ | |
| -d "parse_mode=MarkdownV2" | |
| notify-error: | |
| name: 📢 Telegram Error Notification | |
| runs-on: ubuntu-latest | |
| needs: [test, release, deploy] | |
| if: ${{ failure() }} | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - name: Send Telegram error notification | |
| env: | |
| TELEGRAM_BOT_TOKEN: ${{ secrets.TELEGRAM_BOT_TOKEN }} | |
| TELEGRAM_CHAT_ID: ${{ secrets.TELEGRAM_CHAT_ID }} | |
| GITHUB_ACTOR: ${{ github.actor }} | |
| GITHUB_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} | |
| run: | | |
| AUTHOR_LINK="https://github.com/${LAST_AUTHOR}" | |
| FAILED_STEPS=() | |
| if [ "${{ needs.test.result }}" = "failure" ]; then | |
| FAILED_STEPS+=("Tests") | |
| fi | |
| if [ "${{ needs.release.result }}" = "failure" ]; then | |
| FAILED_STEPS+=("Release") | |
| fi | |
| if [ "${{ needs.deploy.result }}" = "failure" ]; then | |
| FAILED_STEPS+=("Deploy") | |
| fi | |
| if [ ${#FAILED_STEPS[@]} -eq 0 ]; then | |
| echo "No failed steps detected. Exiting." | |
| exit 0 | |
| fi | |
| FAILED_LIST=$(IFS=','; echo "${FAILED_STEPS[*]}") | |
| escape_md() { | |
| echo "$1" | sed -E 's/([_*\[\]()~`>#+=|{}.!-])/\\\1/g' | |
| } | |
| eFailedList=$(escape_md "$FAILED_LIST") | |
| eActor=$(escape_md "$GITHUB_ACTOR") | |
| eAuthorLink="$AUTHOR_LINK" | |
| eRunURL="$GITHUB_RUN_URL" | |
| eDate=$(escape_md "$(date +"%Y-%m-%d %H:%M:%S")") | |
| MESSAGE="❌ *Pipeline Error Detected*\n"\ | |
| "⚠️ Failed Steps: *${eFailedList}*\n"\ | |
| "🕓 Date: ${eDate}\n"\ | |
| "👤 Triggered by: [${eActor}](${eAuthorLink})\n"\ | |
| "🔗 Run URL: [View Run](${eRunURL})" | |
| curl -s -X POST "https://api.telegram.org/bot${TELEGRAM_BOT_TOKEN}/sendMessage" \ | |
| -d "chat_id=${TELEGRAM_CHAT_ID}" \ | |
| -d "text=$MESSAGE" \ | |
| -d "parse_mode=MarkdownV2" |