1+ name : waggle deployment (PR to deploy)
2+
3+ on :
4+ pull_request :
5+ branches : [ deploy ]
6+ types : [ opened, synchronize, reopened, ready_for_review ]
7+
8+ jobs :
9+ build :
10+ runs-on : ubuntu-latest
11+ permissions :
12+ contents : read
13+
14+ steps :
15+ - name : Checkout source
16+ uses : actions/checkout@v4
17+ with :
18+ fetch-depth : 0
19+
20+ - name : Node.js
21+ uses : actions/setup-node@v4
22+ with :
23+ node-version : 22
24+ cache : ' npm'
25+
26+ - name : Install dependencies
27+ run : npm ci
28+
29+ - name : Build React App
30+ run : npm run build
31+ env :
32+ VITE_BASE_URL : ${{ secrets.VITE_BASE_URL }}
33+
34+ - name : Configure AWS Credentials
35+ uses : aws-actions/configure-aws-credentials@v4
36+ with :
37+ aws-access-key-id : ${{ secrets.AWS_ACCESS_KEY_ID }}
38+ aws-secret-access-key : ${{ secrets.AWS_SECRET_ACCESS_KEY }}
39+ aws-region : ${{ secrets.AWS_REGION }}
40+
41+ - name : Deploy to S3 (validate & upload)
42+ shell : bash
43+ run : |
44+ set -euo pipefail
45+
46+ test -f dist/index.html
47+
48+ BUCKET="${{ secrets.AWS_BUCKET_NAME }}"
49+ [[ -n "$BUCKET" ]]
50+ [[ "$BUCKET" != s3://* ]]
51+
52+ aws s3 ls "s3://$BUCKET" >/dev/null
53+
54+ aws s3 sync "dist" "s3://$BUCKET" \
55+ --delete \
56+ --cache-control "public, max-age=31536000, immutable" \
57+ --exclude "index.html"
58+
59+ # HTML: no-cache
60+ aws s3 cp "dist/index.html" "s3://$BUCKET/index.html" \
61+ --cache-control "no-cache, no-store, must-revalidate" \
62+ --content-type "text/html"
63+
64+ - name : Invalidate CloudFront cache (HTML only)
65+ run : |
66+ aws cloudfront create-invalidation \
67+ --distribution-id ${{ secrets.AWS_DISTRIBUTION_ID }} \
68+ --paths "/index.html"
0 commit comments