Skip to content

Commit 1bf5b85

Browse files
authored
Merge pull request #2 from luandro/claude/fix-mapbox-token-error-011CV42p49ctqUNxzCLjj7XL
Various fixes and improvements
2 parents c225619 + 1e0d417 commit 1bf5b85

32 files changed

+3582
-2081
lines changed

.env.example

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# Mapbox Configuration
2+
# Get your free Mapbox token at: https://account.mapbox.com/access-tokens/
3+
# Note: If no token is provided, the app will fall back to OpenStreetMap tiles
4+
VITE_MAPBOX_TOKEN=your_mapbox_token_here
Lines changed: 190 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,190 @@
1+
name: Deploy PR Preview
2+
3+
on:
4+
pull_request:
5+
types: [opened, synchronize, reopened]
6+
paths-ignore:
7+
- '**.md'
8+
- 'docs/**'
9+
10+
# Cancel in-progress runs for the same PR
11+
concurrency:
12+
group: pr-preview-${{ github.event.pull_request.number }}
13+
cancel-in-progress: true
14+
15+
jobs:
16+
# Security check - prevent forks from accessing secrets
17+
security-check:
18+
name: Security Check
19+
runs-on: ubuntu-latest
20+
outputs:
21+
is-fork: ${{ steps.fork-check.outputs.is-fork }}
22+
steps:
23+
- name: Check if PR is from fork
24+
id: fork-check
25+
run: |
26+
if [ "${{ github.event.pull_request.head.repo.full_name }}" != "${{ github.repository }}" ]; then
27+
echo "is-fork=true" >> $GITHUB_OUTPUT
28+
echo "⚠️ PR is from a fork - deployment will be skipped for security" >> $GITHUB_STEP_SUMMARY
29+
else
30+
echo "is-fork=false" >> $GITHUB_OUTPUT
31+
fi
32+
33+
deploy-preview:
34+
name: Deploy Preview to Cloudflare Pages
35+
runs-on: ubuntu-latest
36+
needs: security-check
37+
if: needs.security-check.outputs.is-fork == 'false'
38+
permissions:
39+
contents: read
40+
deployments: write
41+
pull-requests: write
42+
43+
steps:
44+
- name: Checkout PR code
45+
uses: actions/checkout@v4
46+
with:
47+
ref: ${{ github.event.pull_request.head.sha }}
48+
49+
- name: Setup Node.js
50+
uses: actions/setup-node@v4
51+
with:
52+
node-version: '18'
53+
cache: 'npm'
54+
55+
- name: Install dependencies
56+
run: npm ci
57+
58+
- name: Build application
59+
run: npm run build
60+
env:
61+
NODE_ENV: production
62+
63+
- name: Deploy to Cloudflare Pages
64+
id: deploy
65+
uses: cloudflare/wrangler-action@v3
66+
with:
67+
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
68+
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
69+
command: pages deploy dist --project-name=geo-alert-commander --branch=pr-${{ github.event.pull_request.number }}
70+
71+
- name: Generate deployment details
72+
id: deployment-info
73+
run: |
74+
PREVIEW_URL="https://pr-${{ github.event.pull_request.number }}.geo-alert-commander.pages.dev"
75+
echo "preview-url=$PREVIEW_URL" >> $GITHUB_OUTPUT
76+
77+
# Extract deployment URL from Cloudflare output if available
78+
CLOUDFLARE_URL="${{ steps.deploy.outputs.url }}"
79+
if [ -n "$CLOUDFLARE_URL" ]; then
80+
echo "cloudflare-url=$CLOUDFLARE_URL" >> $GITHUB_OUTPUT
81+
fi
82+
83+
- name: Post preview comment to PR
84+
uses: actions/github-script@v7
85+
with:
86+
script: |
87+
const prNumber = context.payload.pull_request.number;
88+
const previewUrl = '${{ steps.deployment-info.outputs.preview-url }}';
89+
const cloudflareUrl = '${{ steps.deployment-info.outputs.cloudflare-url }}' || previewUrl;
90+
const commitSha = '${{ github.event.pull_request.head.sha }}';
91+
const shortSha = commitSha.substring(0, 7);
92+
93+
const commentBody = `## 🚀 Preview Deployment Ready!
94+
95+
Your changes have been deployed to Cloudflare Pages.
96+
97+
**Preview URL:** ${cloudflareUrl}
98+
99+
**Deployment Details:**
100+
- Branch: \`${{ github.event.pull_request.head.ref }}\`
101+
- Commit: \`${shortSha}\`
102+
- Build: ✅ Successful
103+
104+
---
105+
106+
**Testing the PWA:**
107+
1. Visit the preview URL on your mobile device
108+
2. Install the app (Add to Home Screen)
109+
3. Test offline functionality
110+
111+
**Note:** The preview deployment uses the same service worker and manifest as production. Clear your browser cache if you've previously installed the app.
112+
113+
---
114+
115+
<sub>Deployed via [Cloudflare Pages](https://pages.cloudflare.com/)</sub>`;
116+
117+
// Find existing preview comment
118+
const { data: comments } = await github.rest.issues.listComments({
119+
owner: context.repo.owner,
120+
repo: context.repo.repo,
121+
issue_number: prNumber,
122+
});
123+
124+
const botComment = comments.find(comment =>
125+
comment.user.type === 'Bot' &&
126+
comment.body.includes('Preview Deployment Ready')
127+
);
128+
129+
if (botComment) {
130+
// Update existing comment
131+
await github.rest.issues.updateComment({
132+
owner: context.repo.owner,
133+
repo: context.repo.repo,
134+
comment_id: botComment.id,
135+
body: commentBody,
136+
});
137+
} else {
138+
// Create new comment
139+
await github.rest.issues.createComment({
140+
owner: context.repo.owner,
141+
repo: context.repo.repo,
142+
issue_number: prNumber,
143+
body: commentBody,
144+
});
145+
}
146+
147+
- name: Generate deployment summary
148+
run: |
149+
echo "## 🎉 PR Preview Deployed" >> $GITHUB_STEP_SUMMARY
150+
echo "" >> $GITHUB_STEP_SUMMARY
151+
echo "**Preview URL:** ${{ steps.deployment-info.outputs.preview-url }}" >> $GITHUB_STEP_SUMMARY
152+
echo "**PR Number:** #${{ github.event.pull_request.number }}" >> $GITHUB_STEP_SUMMARY
153+
echo "**Branch:** ${{ github.event.pull_request.head.ref }}" >> $GITHUB_STEP_SUMMARY
154+
echo "**Commit:** ${{ github.event.pull_request.head.sha }}" >> $GITHUB_STEP_SUMMARY
155+
echo "" >> $GITHUB_STEP_SUMMARY
156+
echo "**Build Stats:**" >> $GITHUB_STEP_SUMMARY
157+
echo "- Node version: $(node --version)" >> $GITHUB_STEP_SUMMARY
158+
echo "- NPM version: $(npm --version)" >> $GITHUB_STEP_SUMMARY
159+
160+
deployment-skipped:
161+
name: Deployment Skipped (Fork)
162+
runs-on: ubuntu-latest
163+
needs: security-check
164+
if: needs.security-check.outputs.is-fork == 'true'
165+
steps:
166+
- name: Comment on PR
167+
uses: actions/github-script@v7
168+
with:
169+
script: |
170+
const commentBody = `## ⚠️ Preview Deployment Skipped
171+
172+
Preview deployments are not available for pull requests from forked repositories due to security restrictions.
173+
174+
**Why?** Deploying from forks would expose sensitive secrets (Cloudflare API tokens) to external contributors.
175+
176+
**What you can do:**
177+
- Build and test locally using \`npm run build && npm run preview\`
178+
- Wait for a maintainer to review and potentially deploy a preview manually
179+
- If you're a maintainer, close and reopen this PR from a branch in the main repository
180+
181+
---
182+
183+
<sub>For more information, see [GitHub Actions security best practices](https://docs.github.com/en/actions/security-guides/security-hardening-for-github-actions)</sub>`;
184+
185+
await github.rest.issues.createComment({
186+
owner: context.repo.owner,
187+
repo: context.repo.repo,
188+
issue_number: context.payload.pull_request.number,
189+
body: commentBody,
190+
});
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
name: Deploy to Production
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
paths-ignore:
8+
- '**.md'
9+
- 'docs/**'
10+
workflow_dispatch:
11+
inputs:
12+
environment:
13+
description: 'Deployment environment'
14+
required: true
15+
default: 'production'
16+
type: choice
17+
options:
18+
- production
19+
- test
20+
21+
jobs:
22+
deploy:
23+
name: Deploy to Cloudflare Pages
24+
runs-on: ubuntu-latest
25+
permissions:
26+
contents: read
27+
deployments: write
28+
29+
steps:
30+
- name: Checkout repository
31+
uses: actions/checkout@v4
32+
33+
- name: Setup Node.js
34+
uses: actions/setup-node@v4
35+
with:
36+
node-version: '18'
37+
cache: 'npm'
38+
39+
- name: Install dependencies
40+
run: npm ci
41+
42+
- name: Build application
43+
run: npm run build
44+
env:
45+
# Add any build-time environment variables here
46+
# VITE_MAPBOX_TOKEN is intentionally NOT set - users configure in Cloudflare
47+
NODE_ENV: production
48+
49+
- name: Deploy to Cloudflare Pages
50+
id: deploy
51+
uses: cloudflare/wrangler-action@v3
52+
with:
53+
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
54+
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
55+
command: pages deploy dist --project-name=geo-alert-commander --branch=${{ github.ref_name }}
56+
57+
- name: Generate deployment summary
58+
run: |
59+
echo "## 🚀 Deployment Complete" >> $GITHUB_STEP_SUMMARY
60+
echo "" >> $GITHUB_STEP_SUMMARY
61+
echo "**Environment:** ${{ inputs.environment || 'production' }}" >> $GITHUB_STEP_SUMMARY
62+
echo "**Branch:** ${{ github.ref_name }}" >> $GITHUB_STEP_SUMMARY
63+
echo "**Commit:** ${{ github.sha }}" >> $GITHUB_STEP_SUMMARY
64+
echo "" >> $GITHUB_STEP_SUMMARY
65+
echo "**Deployment URL:** ${{ steps.deploy.outputs.url }}" >> $GITHUB_STEP_SUMMARY
66+
echo "" >> $GITHUB_STEP_SUMMARY
67+
echo "**Build Stats:**" >> $GITHUB_STEP_SUMMARY
68+
echo "- Node version: $(node --version)" >> $GITHUB_STEP_SUMMARY
69+
echo "- NPM version: $(npm --version)" >> $GITHUB_STEP_SUMMARY

.gitignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,11 @@ dist
1212
dist-ssr
1313
*.local
1414

15+
# Environment variables
16+
.env
17+
.env.local
18+
.env.production
19+
1520
# Editor directories and files
1621
.vscode/*
1722
!.vscode/extensions.json

0 commit comments

Comments
 (0)