Deploy to Vercel #62
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
| # .github/workflows/deploy-vercel.yml | |
| name: Deploy to Vercel | |
| on: | |
| workflow_run: | |
| workflows: ["E2E Tests"] | |
| types: | |
| - completed | |
| branches: [master] | |
| workflow_dispatch: | |
| jobs: | |
| deploy: | |
| environment: production | |
| runs-on: ubuntu-latest | |
| if: ${{ github.event.workflow_run.conclusion == 'success' || github.event_name == 'workflow_dispatch' }} | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Setup pnpm | |
| uses: pnpm/action-setup@v4 | |
| - name: Generate build timestamp | |
| run: | | |
| mkdir -p lib/generated | |
| echo "// Auto-generated at build time - do not edit" > lib/generated/buildTime.ts | |
| echo "export const BUILD_TIME = '$(date -u +'%Y-%m-%dT%H:%M:%SZ')';" >> lib/generated/buildTime.ts | |
| cat lib/generated/buildTime.ts | |
| - name: Deploy to Vercel (prod, cold build) via CLI | |
| id: vercel | |
| env: | |
| VERCEL_TOKEN: ${{ secrets.VERCEL_TOKEN }} | |
| VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }} | |
| VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PROJECT_ID }} | |
| run: | | |
| set -euo pipefail | |
| RAW_MSG="${{ github.event.head_commit.message || '' }}" | |
| if [ -z "$RAW_MSG" ]; then RAW_MSG="$(git log -1 --pretty=%s 2>/dev/null || true)"; fi | |
| if [ -z "$RAW_MSG" ]; then RAW_MSG="manual deploy"; fi | |
| COMMIT_MSG="$(printf "%s" "$RAW_MSG" | tr '\n' ' ' | tr -d '\r')" | |
| ORG="${{ github.repository_owner }}" | |
| REPO="${{ github.event.repository.name }}" | |
| REF_NAME="${{ github.ref_name }}" | |
| SHA="${{ github.sha }}" | |
| ACTOR="${{ github.actor }}" | |
| DEPLOY_URL="$(npx -y vercel@latest --prod --yes --force \ | |
| -t "$VERCEL_TOKEN" \ | |
| -m githubCommitSha="$SHA" \ | |
| -m githubCommitAuthorName="$ACTOR" \ | |
| -m githubDeployment=1 \ | |
| -m githubOrg="$ORG" \ | |
| -m githubRepo="$REPO" \ | |
| -m githubCommitMessage="$COMMIT_MSG" \ | |
| -m githubCommitRef="$REF_NAME" \ | |
| )" | |
| echo "preview-url=$DEPLOY_URL" >> "$GITHUB_OUTPUT" | |
| npx -y vercel@latest inspect "$DEPLOY_URL" -t "$VERCEL_TOKEN" || true | |
| echo "preview-name=$DEPLOY_URL" >> "$GITHUB_OUTPUT" | |
| - name: Trigger cron maintenance job (IP sync + ISR warm; force on deploy) | |
| if: ${{ success() }} | |
| env: | |
| CRON_URL: https://carolinevreeland.com/api/cron | |
| CRON_SECRET: ${{ secrets.CRON_SECRET }} | |
| run: | | |
| set -euo pipefail | |
| if [ -z "${CRON_SECRET:-}" ]; then | |
| echo "Cron maintenance step skipped: CRON_SECRET not set." | |
| exit 0 | |
| fi | |
| payload='{"force": true}' | |
| status="$(curl -s -o /dev/null -w "%{http_code}" -X POST "${CRON_URL}" \ | |
| -H "Content-Type: application/json" \ | |
| -H "X-Cron-Secret: ${CRON_SECRET}" \ | |
| --data "${payload}" || true)" | |
| case "$status" in | |
| 2*) echo "Cron maintenance OK ($status)";; | |
| *) echo "Cron maintenance returned HTTP $status. Continuing.";; | |
| esac |