Fix cron trigger limit: Move triggers to production-only, document st… #28
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 | |
| # Triggers: Run on pull requests and pushes to any branch | |
| on: | |
| pull_request: | |
| branches: [main, develop] | |
| push: | |
| branches-ignore: [] # Run on all branches | |
| # Environment variables available to all jobs | |
| env: | |
| NODE_VERSION: '20' | |
| jobs: | |
| # Job 1: Quality Checks - Runs first and must pass | |
| quality-check: | |
| name: Quality Checks | |
| runs-on: ubuntu-latest | |
| 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' | |
| cache-dependency-path: '**/package-lock.json' | |
| - name: Install dependencies | |
| run: npm ci | |
| - name: TypeScript type checking | |
| run: npm run type-check | |
| - name: ESLint code quality check | |
| run: npm run lint:ci | |
| - name: Prettier format check | |
| run: npm run format:check | |
| - name: Run tests with coverage | |
| run: npm run test:ci | |
| env: | |
| VITE_API_BASE_URL: https://solar-mining-api-dev.christopher-k.workers.dev | |
| - name: Upload coverage reports | |
| uses: codecov/codecov-action@v3 | |
| with: | |
| file: ./coverage/lcov.info | |
| flags: unittests | |
| name: codecov-umbrella | |
| - name: Claude Code Analysis | |
| if: github.event_name == 'pull_request' | |
| uses: anthropics/claude-code-action@beta | |
| with: | |
| github_token: ${{ secrets.GITHUB_TOKEN }} | |
| anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }} | |
| continue-on-error: true | |
| # Job 2: Build - Only runs if quality checks pass | |
| build: | |
| name: Build Application | |
| runs-on: ubuntu-latest | |
| needs: quality-check | |
| 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' | |
| cache-dependency-path: '**/package-lock.json' | |
| - name: Install dependencies | |
| run: npm ci | |
| - name: Build client application | |
| run: npm run build:client | |
| - name: Build workers (dry-run) | |
| run: | | |
| if [ "${{ github.ref }}" = "refs/heads/main" ]; then | |
| echo "Building for production environment..." | |
| npm run build:workers | |
| else | |
| echo "Building for staging environment..." | |
| npm run build:workers:dev | |
| fi | |
| - name: Upload build artifacts | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: build-artifacts | |
| path: | | |
| dist/ | |
| .wrangler/ | |
| retention-days: 7 | |
| # Job 3: Deploy to Staging - Runs on any branch except main | |
| deploy-staging: | |
| name: Deploy to Staging | |
| runs-on: ubuntu-latest | |
| needs: build | |
| if: github.event_name == 'pull_request' || github.ref != 'refs/heads/main' | |
| environment: | |
| name: staging | |
| # URL handled automatically by Cloudflare Pages preview deployments | |
| 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' | |
| cache-dependency-path: '**/package-lock.json' | |
| - name: Install dependencies | |
| run: npm ci | |
| - name: Build client application | |
| run: npm run build:client | |
| - name: Deploy API Worker to staging | |
| run: npm run deploy:api:dev | |
| env: | |
| CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }} | |
| CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} | |
| - name: Deploy Calculations Worker to staging | |
| run: npm run deploy:calculations:dev | |
| env: | |
| CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }} | |
| CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} | |
| - name: Deploy Data Worker to staging | |
| run: npm run deploy:data:dev | |
| env: | |
| CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }} | |
| CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} | |
| - name: Deploy Pages to staging | |
| run: npm run pages:deploy | |
| env: | |
| CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }} | |
| CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} | |
| # Job 4: Deploy to Production - Only on main branch with approval | |
| deploy-production: | |
| name: Deploy to Production | |
| runs-on: ubuntu-latest | |
| needs: build | |
| if: github.ref == 'refs/heads/main' && github.event_name == 'push' | |
| environment: | |
| name: production | |
| url: https://solar-mining-calculator.pages.dev | |
| 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' | |
| cache-dependency-path: '**/package-lock.json' | |
| - name: Install dependencies | |
| run: npm ci | |
| - name: Build client application | |
| run: npm run build:client | |
| - name: Deploy API Worker to production | |
| run: npm run deploy:api | |
| env: | |
| CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }} | |
| CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} | |
| VITE_API_BASE_URL: https://solar-mining-api.christopher-k.workers.dev | |
| - name: Deploy Calculations Worker to production | |
| run: npm run deploy:calculations | |
| env: | |
| CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }} | |
| CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} | |
| - name: Deploy Data Worker to production | |
| run: npm run deploy:data | |
| env: | |
| CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }} | |
| CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} | |
| - name: Deploy Pages to production | |
| run: npm run pages:deploy | |
| env: | |
| CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }} | |
| CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} | |