Updated Readme & Added Workflow #1
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: Elevate CI/CD Pipeline | |
on: | |
push: | |
branches: [main, develop] | |
pull_request: | |
branches: [main] | |
# Add write permissions for the GITHUB_TOKEN | |
permissions: | |
contents: read | |
actions: write | |
pull-requests: write | |
checks: write | |
env: | |
NODE_VERSION: '24' | |
CACHE_KEY: npm-cache-v1 | |
jobs: | |
# Quality checks and build | |
quality-checks: | |
runs-on: ubuntu-latest | |
outputs: | |
cache-hit: ${{ steps.cache.outputs.cache-hit }} | |
steps: | |
- name: Checkout code | |
uses: actions/checkout@v4 | |
- name: Setup Node.js | |
uses: actions/setup-node@v4 | |
with: | |
node-version: ${{ env.NODE_VERSION }} | |
cache: 'npm' | |
- name: Cache dependencies | |
id: cache | |
uses: actions/cache@v4 | |
with: | |
path: node_modules | |
key: ${{ runner.os }}-${{ env.CACHE_KEY }}-${{ hashFiles('**/package-lock.json') }} | |
- name: Install dependencies | |
if: steps.cache.outputs.cache-hit != 'true' | |
run: npm ci | |
- name: Type check | |
run: | | |
if [ -f "tsconfig.json" ]; then | |
npx tsc --noEmit | |
else | |
echo "No TypeScript config found, skipping type check" | |
fi | |
- name: Run tests | |
run: | | |
if npm run test --if-present; then | |
echo "Tests completed successfully" | |
else | |
echo "No tests found or tests skipped" | |
fi | |
- name: Build project | |
run: npm run build | |
- name: Upload build artifacts | |
uses: actions/upload-artifact@v4 | |
with: | |
name: build-files-${{ github.run_id }} | |
path: dist/ | |
retention-days: 1 | |
# Security and performance audits | |
security-audit: | |
runs-on: ubuntu-latest | |
needs: quality-checks | |
steps: | |
- name: Checkout code | |
uses: actions/checkout@v4 | |
- name: Setup Node.js | |
uses: actions/setup-node@v4 | |
with: | |
node-version: ${{ env.NODE_VERSION }} | |
cache: 'npm' | |
- name: Install dependencies | |
run: npm ci | |
- name: Security audit | |
run: | | |
echo "Running npm audit..." | |
npm audit --audit-level moderate || true | |
- name: Check for high/critical vulnerabilities | |
run: | | |
# Check if jq is available, if not install it | |
if ! command -v jq &> /dev/null; then | |
sudo apt-get update && sudo apt-get install -y jq | |
fi | |
HIGH_VULNS=$(npm audit --audit-level high --json 2>/dev/null | jq '.metadata.vulnerabilities.high // 0' || echo "0") | |
CRITICAL_VULNS=$(npm audit --audit-level critical --json 2>/dev/null | jq '.metadata.vulnerabilities.critical // 0' || echo "0") | |
echo "High vulnerabilities: $HIGH_VULNS" | |
echo "Critical vulnerabilities: $CRITICAL_VULNS" | |
if [ "$HIGH_VULNS" -gt 0 ] || [ "$CRITICAL_VULNS" -gt 0 ]; then | |
echo "High or critical vulnerabilities found!" | |
npm audit --audit-level high | |
exit 1 | |
else | |
echo "No high or critical vulnerabilities found" | |
fi | |
# Vercel deployment | |
deploy-vercel: | |
runs-on: ubuntu-latest | |
needs: [quality-checks, security-audit] | |
if: always() && needs.quality-checks.result == 'success' && (needs.security-audit.result == 'success' || needs.security-audit.result == 'skipped') | |
outputs: | |
preview-url: ${{ steps.vercel-preview.outputs.preview-url }} | |
production-url: ${{ steps.vercel-production.outputs.preview-url }} | |
steps: | |
- name: Checkout code | |
uses: actions/checkout@v4 | |
- name: Deploy to Vercel (Preview) | |
id: vercel-preview | |
if: github.event_name == 'pull_request' | |
uses: amondnet/vercel-action@v25 | |
with: | |
vercel-token: ${{ secrets.VERCEL_TOKEN }} | |
vercel-org-id: ${{ secrets.VERCEL_ORG_ID }} | |
vercel-project-id: ${{ secrets.VERCEL_PROJECT_ID }} | |
working-directory: ./ | |
scope: ${{ secrets.VERCEL_ORG_ID }} | |
alias-domains: | | |
pr-${{ github.event.number }}-elevatehabits.vercel.app | |
- name: Deploy to Vercel (Production) | |
id: vercel-production | |
if: github.ref == 'refs/heads/main' && github.event_name == 'push' | |
uses: amondnet/vercel-action@v25 | |
with: | |
vercel-token: ${{ secrets.VERCEL_TOKEN }} | |
vercel-org-id: ${{ secrets.VERCEL_ORG_ID }} | |
vercel-project-id: ${{ secrets.VERCEL_PROJECT_ID }} | |
vercel-args: '--prod' | |
working-directory: ./ | |
scope: ${{ secrets.VERCEL_ORG_ID }} | |
- name: Comment PR with preview URL | |
if: github.event_name == 'pull_request' && steps.vercel-preview.outputs.preview-url | |
uses: actions/github-script@v7 | |
with: | |
script: | | |
const deploymentUrl = '${{ steps.vercel-preview.outputs.preview-url }}'; | |
const comment = `## 🚀 Preview Deployment | |
Your changes have been deployed to Vercel: | |
**Preview URL:** ${deploymentUrl} | |
--- | |
*Deployed from commit: ${{ github.sha }}*`; | |
github.rest.issues.createComment({ | |
issue_number: context.issue.number, | |
owner: context.repo.owner, | |
repo: context.repo.repo, | |
body: comment | |
}); | |
# Post-deployment checks | |
post-deploy-checks: | |
runs-on: ubuntu-latest | |
needs: [deploy-vercel] | |
if: always() && needs.deploy-vercel.result == 'success' | |
steps: | |
- name: Health check Vercel deployment | |
run: | | |
echo "Performing post-deployment health checks..." | |
# Health check for preview deployment | |
if [ "${{ github.event_name }}" == "pull_request" ] && [ -n "${{ needs.deploy-vercel.outputs.preview-url }}" ]; then | |
echo "Checking preview deployment..." | |
PREVIEW_URL="${{ needs.deploy-vercel.outputs.preview-url }}" | |
if curl -f "$PREVIEW_URL" > /dev/null 2>&1; then | |
echo "✅ Preview deployment is healthy: $PREVIEW_URL" | |
else | |
echo "⚠️ Preview deployment health check failed: $PREVIEW_URL" | |
fi | |
fi | |
# Health check for production deployment | |
if [ "${{ github.ref }}" == "refs/heads/main" ] && [ "${{ github.event_name }}" == "push" ] && [ -n "${{ needs.deploy-vercel.outputs.production-url }}" ]; then | |
echo "Checking production deployment..." | |
PROD_URL="${{ needs.deploy-vercel.outputs.production-url }}" | |
if curl -f "$PROD_URL" > /dev/null 2>&1; then | |
echo "✅ Production deployment is healthy: $PROD_URL" | |
else | |
echo "⚠️ Production deployment health check failed: $PROD_URL" | |
fi | |
fi | |
echo "Health checks completed" | |
- name: Notify deployment status | |
if: github.event_name == 'push' && github.ref == 'refs/heads/main' | |
run: | | |
echo "🚀 Production deployment completed successfully!" | |
echo "Vercel Status: ${{ needs.deploy-vercel.result }}" | |
echo "Deployment URL: ${{ needs.deploy-vercel.outputs.production-url }}" | |
- name: Create deployment summary | |
run: | | |
echo "## 🚀 Deployment Summary" >> $GITHUB_STEP_SUMMARY | |
echo "" >> $GITHUB_STEP_SUMMARY | |
echo "**Repository:** ${{ github.repository }}" >> $GITHUB_STEP_SUMMARY | |
echo "**Commit:** ${{ github.sha }}" >> $GITHUB_STEP_SUMMARY | |
echo "**Branch:** ${{ github.ref_name }}" >> $GITHUB_STEP_SUMMARY | |
echo "**Trigger:** ${{ github.event_name }}" >> $GITHUB_STEP_SUMMARY | |
echo "" >> $GITHUB_STEP_SUMMARY | |
if [ "${{ github.event_name }}" == "pull_request" ]; then | |
echo "### Preview Deployment" >> $GITHUB_STEP_SUMMARY | |
echo "- **Platform:** Vercel" >> $GITHUB_STEP_SUMMARY | |
echo "- **Status:** ${{ needs.deploy-vercel.result }}" >> $GITHUB_STEP_SUMMARY | |
if [ -n "${{ needs.deploy-vercel.outputs.preview-url }}" ]; then | |
echo "- **URL:** [${{ needs.deploy-vercel.outputs.preview-url }}](${{ needs.deploy-vercel.outputs.preview-url }})" >> $GITHUB_STEP_SUMMARY | |
fi | |
else | |
echo "### Production Deployment" >> $GITHUB_STEP_SUMMARY | |
echo "- **Platform:** Vercel" >> $GITHUB_STEP_SUMMARY | |
echo "- **Status:** ${{ needs.deploy-vercel.result }}" >> $GITHUB_STEP_SUMMARY | |
if [ -n "${{ needs.deploy-vercel.outputs.production-url }}" ]; then | |
echo "- **URL:** [${{ needs.deploy-vercel.outputs.production-url }}](${{ needs.deploy-vercel.outputs.production-url }})" >> $GITHUB_STEP_SUMMARY | |
fi | |
fi | |
echo "" >> $GITHUB_STEP_SUMMARY | |
echo "---" >> $GITHUB_STEP_SUMMARY | |
echo "*Workflow completed at $(date)*" >> $GITHUB_STEP_SUMMARY | |
# Cleanup job | |
cleanup: | |
runs-on: ubuntu-latest | |
needs: [deploy-vercel, post-deploy-checks] | |
if: always() | |
steps: | |
- name: Cleanup notification | |
run: | | |
echo "🧹 Cleanup job completed" | |
echo "Build artifacts will be automatically cleaned up after retention period" | |
echo "Manual cleanup can be done through GitHub UI if needed" | |
- name: Workflow completion | |
run: | | |
echo "✅ Elevate CI/CD Pipeline completed" | |
echo "Overall Status:" | |
echo "- Quality Checks: Completed" | |
echo "- Security Audit: Completed" | |
echo "- Vercel Deployment: ${{ needs.deploy-vercel.result }}" | |
echo "- Post-deploy Checks: ${{ needs.post-deploy-checks.result }}" |