Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
160 changes: 140 additions & 20 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,20 @@ on:
branches:
- main
pull_request:
types:
- opened
- synchronize
- reopened
- closed

jobs:
deploy:
runs-on: ubuntu-latest
permissions:
contents: read
deployments: write
issues: write
pull-requests: write

steps:
- uses: actions/checkout@v4
Expand All @@ -25,35 +32,148 @@ jobs:
- name: Install dependencies
run: npm ci

- name: Build
- name: Build Next.js
run: npm run build
env:
NODE_ENV: production

- name: Deploy to Cloudflare (Preview for PR / Production for main)
uses: cloudflare/wrangler-action@v3
with:
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
command: |
if [ "${{ github.event_name }}" = "pull_request" ]; then
# Deploy to preview with unique name based on PR number
opennextjs-cloudflare build
wrangler deploy --env preview --name sparkmemos-pr-${{ github.event.pull_request.number }}
else
# Deploy to production
opennextjs-cloudflare deploy
fi
- name: Build OpenNext
run: npx opennextjs-cloudflare build

- name: Install Wrangler
run: npm install -g wrangler

# Deploy to main domain (main branch only)
- name: Deploy to Cloudflare (Main)
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
run: wrangler deploy
env:
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}

# Deploy to preview environment (PR only)
- name: Deploy to Cloudflare (Preview)
if: github.event_name == 'pull_request'
run: |
wrangler deploy --env pr-${{ github.event.pull_request.number }} --legacy-env
env:
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}

# Get actual domain from Cloudflare API
- name: Get deployment URL
if: github.event_name == 'pull_request'
id: get-url
run: |
PR_NUM=${{ github.event.pull_request.number }}
ACCOUNT_ID=${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
WORKER_NAME="sparkmemos"

SUBDOMAIN_RESPONSE=$(curl -s -X GET \
"https://api.cloudflare.com/client/v4/accounts/${ACCOUNT_ID}/workers/subdomain" \
-H "Authorization: Bearer ${{ secrets.CLOUDFLARE_API_TOKEN }}" \
-H "Content-Type: application/json")

ACCOUNT_SUBDOMAIN=$(echo $SUBDOMAIN_RESPONSE | jq -r '.result.subdomain // empty')

if [ -z "$ACCOUNT_SUBDOMAIN" ]; then
ACCOUNT_SUBDOMAIN=$ACCOUNT_ID
fi

PREVIEW_URL="https://${WORKER_NAME}-pr-${PR_NUM}.${ACCOUNT_SUBDOMAIN}.workers.dev"

echo "Preview URL: $PREVIEW_URL"
echo "preview_url=${PREVIEW_URL}" >> $GITHUB_OUTPUT
env:
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}

# Comment preview link on PR
- name: Deploy status comment
if: github.event_name == 'pull_request'
uses: actions/github-script@v7
with:
script: |
const previewUrl = `https://sparkmemos-pr-${{ github.event.pull_request.number }}.workers.dev`;
const previewUrl = process.env.PREVIEW_URL;
const prNumber = context.payload.pull_request.number;
const owner = context.repo.owner;
const repo = context.repo.repo;

const { data: comments } = await github.rest.issues.listComments({
owner,
repo,
issue_number: prNumber
});

const existingComment = comments.find(comment =>
comment.body.includes('🚀 Preview deployed:')
);

const commentBody = `🚀 Preview deployed: ${previewUrl}`;

if (existingComment) {
await github.rest.issues.updateComment({
owner,
repo,
comment_id: existingComment.id,
body: commentBody
});
} else {
await github.rest.issues.createComment({
owner,
repo,
issue_number: prNumber,
body: commentBody
});
}
env:
PREVIEW_URL: ${{ steps.get-url.outputs.preview_url }}

cleanup:
runs-on: ubuntu-latest
permissions:
contents: read
deployments: write
issues: write
pull-requests: write

if: github.event_name == 'pull_request' && github.event.action == 'closed'

steps:
- name: Install Wrangler
run: npm install -g wrangler

- name: Cleanup preview environment
run: |
PR_NUM=${{ github.event.pull_request.number }}
ACCOUNT_ID=${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
WORKER_NAME="sparkmemos"

echo "Cleaning up preview environment for PR #${PR_NUM}"

RESPONSE=$(curl -s -X DELETE \
"https://api.cloudflare.com/client/v4/accounts/${ACCOUNT_ID}/workers/scripts/${WORKER_NAME}/environments/pr-${PR_NUM}" \
-H "Authorization: Bearer ${{ secrets.CLOUDFLARE_API_TOKEN }}" \
-H "Content-Type: application/json")

echo "API Cleanup response: $RESPONSE"

echo "Cleanup completed for PR #${PR_NUM}"
env:
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}

- name: Add cleanup comment
uses: actions/github-script@v7
with:
script: |
const prNumber = context.payload.pull_request.number;
const owner = context.repo.owner;
const repo = context.repo.repo;

await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.payload.pull_request.number,
body: `🚀 Preview deployed: ${previewUrl}`
owner,
repo,
issue_number: prNumber,
body: `🧹 Preview environment cleaned up (PR #${prNumber} closed/merged)`
});
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,4 @@ You can check out [the Next.js GitHub repository](https://github.com/vercel/next
The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.

Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details.
# Test
Copy link

Copilot AI Mar 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This appends a top-level heading # Test with no meaningful content to the project README. Even for testing PR preview deployments, this change should not be merged into the main branch as it degrades the quality of the project documentation. If this is purely for deployment testing, it should be reverted or the PR should be closed after verification.

Copilot uses AI. Check for mistakes.