CF worker runtime workflow fixes. #17
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 to Cloudflare Pages (Runtime) | |
| on: | |
| push: | |
| branches: ['main'] | |
| workflow_dispatch: | |
| permissions: | |
| contents: read | |
| concurrency: | |
| group: cloudflare-pages-runtime-${{ github.ref_name }} | |
| cancel-in-progress: true | |
| jobs: | |
| deploy-runtime: | |
| name: 🏗 Build and Deploy Runtime | |
| runs-on: ubuntu-latest | |
| env: | |
| FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true | |
| steps: | |
| - name: 🔍 Checkout repository | |
| uses: actions/checkout@v5 | |
| with: | |
| submodules: 'recursive' | |
| - name: 🔒 Verify Google services secret exists | |
| run: | | |
| if [ -z "${{ secrets.GOOGLE_SERVICES_JSON_BASE64 }}" ]; then | |
| echo "❌ GOOGLE_SERVICES_JSON_BASE64 secret is missing" | |
| exit 1 | |
| fi | |
| - name: 🔒 Verify env file secret exists | |
| run: | | |
| if [ -z "${{ secrets.ENV_FILE_CONTENT }}" ]; then | |
| echo "❌ ENV_FILE_CONTENT secret is missing" | |
| exit 1 | |
| fi | |
| - name: 📁 Set Google services environment variable | |
| run: | | |
| echo "$GOOGLE_SERVICES_JSON_BASE64" | base64 -d > /tmp/google-services.json | |
| if ! jq -c . /tmp/google-services.json > /tmp/google-services.compact.json; then | |
| echo "❌ GOOGLE_SERVICES_JSON_BASE64 did not decode to valid JSON" | |
| exit 1 | |
| fi | |
| printf 'GOOGLE_SERVICES_JSON=%s\n' "$(cat /tmp/google-services.compact.json)" >> "$GITHUB_ENV" | |
| env: | |
| GOOGLE_SERVICES_JSON_BASE64: ${{ secrets.GOOGLE_SERVICES_JSON_BASE64 }} | |
| - name: ⚙️ Create .env file | |
| run: | | |
| printf '%s\n' "${{ secrets.ENV_FILE_CONTENT }}" > .env | |
| echo "" >> .env | |
| - name: 📦 Install pnpm | |
| run: npm install -g pnpm@10 | |
| - name: ⚙️ Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: '24' | |
| cache: 'pnpm' | |
| - name: 📥 Install dependencies | |
| run: pnpm install --frozen-lockfile | |
| - name: 🔧 Generate Prisma client | |
| run: pnpm prisma generate | |
| - name: 🏗 Build Next.js for runtime | |
| env: | |
| NEXT_OUTPUT_MODE: standalone | |
| run: pnpm build | |
| - name: 🏗 Build Cloudflare Pages output (functions + static) | |
| run: pnpm dlx @cloudflare/next-on-pages@1 | |
| - name: 🔎 Verify Cloudflare Pages project exists | |
| env: | |
| CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }} | |
| CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} | |
| PROJECT_NAME: ${{ secrets.CLOUDFLARE_PAGES_PROJECT_NAME_RUNTIME }} | |
| run: | | |
| RESPONSE=$(curl -fsSL \ | |
| -H "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \ | |
| -H "Content-Type: application/json" \ | |
| "https://api.cloudflare.com/client/v4/accounts/$CLOUDFLARE_ACCOUNT_ID/pages/projects") | |
| COUNT=$(printf '%s' "$RESPONSE" | jq '.result | length') | |
| MATCH=$(printf '%s' "$RESPONSE" | jq --arg name "$PROJECT_NAME" 'any(.result[]?; .name == $name)') | |
| echo "Pages projects visible in this account: $COUNT" | |
| if [ "$MATCH" != "true" ]; then | |
| echo "Configured Pages project was not found in the provided Cloudflare account." | |
| echo "Verify CLOUDFLARE_ACCOUNT_ID points to the same account that owns the Pages project." | |
| echo "Visible project names:" | |
| printf '%s' "$RESPONSE" | jq -r '.result[]?.name' | |
| exit 1 | |
| fi | |
| echo "Configured Pages project exists in the target account." | |
| - name: 🚀 Deploy runtime app to Cloudflare Pages | |
| uses: cloudflare/wrangler-action@v3 | |
| with: | |
| apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }} | |
| accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} | |
| command: >- | |
| pages deploy .vercel/output/static | |
| --project-name=${{ secrets.CLOUDFLARE_PAGES_PROJECT_NAME_RUNTIME }} | |
| --branch=${{ github.ref_name }} | |
| --commit-hash=${{ github.sha }} | |
| --functions=.vercel/output/functions |