-
-
Notifications
You must be signed in to change notification settings - Fork 10
243 lines (225 loc) · 9.98 KB
/
Copy pathdeploy-s3.yml
File metadata and controls
243 lines (225 loc) · 9.98 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
name: Deploy
on:
push:
branches:
- main
workflow_dispatch:
inputs:
force_metadata_update:
description: 'Force metadata update for all files (bypasses size-only check)'
required: false
default: false
type: boolean
permissions:
contents: read
id-token: write
env:
AWS_REGION : "us-east-1"
AWS_REGION_ZONE : "us-east-1"
S3_BUCKET_NAME: "ciacompliancemanager-frontend-us-east-1-172017021075"
CLOUDFRONT_STACK_NAME: "ciacompliancemanager-frontend"
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Harden Runner
uses: step-security/harden-runner@fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594 # v2.16.0
with:
egress-policy: block
allowed-endpoints: >
accounts.google.com:443
amazon-cloudfront-secure-static-site-s3bucketroot-14oliw5cmta06.s3.us-east-1.amazonaws.com:443
api.github.com:443
api.securityscorecards.dev:443
app.fossa.io:443
auth.docker.io:443
bestpractices.coreinfrastructure.org:443
cfu.zaproxy.org:443
cla-assistant.io:443
cla-assistant.io:80
clients2.google.com:80
cloudformation.us-east-1.amazonaws.com:443
cloudfront.amazonaws.com:443
content-signature-2.cdn.mozilla.net:443
deb.debian.org:80
firefox-settings-attachments.cdn.mozilla.net:443
firefox.settings.services.mozilla.com:443
fonts.googleapis.com:443
fonts.gstatic.com:443
ghcr.io:443
github.com:443
hack23.com:443
hack23.com:80
hack23.comnull:443
img.shields.io:443
isitmaintained.com:443
isitmaintained.com:80
location.services.mozilla.com:443
news.zaproxy.org:443
objects.githubusercontent.com:443
pkg-containers.githubusercontent.com:443
production.cloudflare.docker.com:443
r10.o.lencr.org:443
r11.o.lencr.org:80
raw.githubusercontent.com:443
registry-1.docker.io:443
registry.npmjs.org:443
safebrowsingohttpgateway.googleapis.com:443
shavar.services.mozilla.com:443
slsa.dev:443
sonarcloud.io:443
storage.googleapis.com:443
sts.us-east-1.amazonaws.com:443
tel.zaproxy.org:443
tracking-protection.cdn.mozilla.net:443
us-central1-lighthouse-infrastructure.cloudfunctions.net:443
www.google.com:443
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: configure aws credentials
uses: aws-actions/configure-aws-credentials@8df5847569e6427dd6c4fb1cf565c83acfa8afa7 # v6.0.0
with:
role-to-assume: arn:aws:iam::172017021075:role/GithubWorkFlowRole
role-session-name: githubworkflowrolesessiont2
aws-region: ${{ env.AWS_REGION }}
- name: Deploy to S3 with proper cache headers
run: |
# Determine sync mode for versioned/hashed assets (can use --size-only safely)
if [ "${{ github.event.inputs.force_metadata_update }}" = "true" ]; then
HASHED_SYNC_MODE="--metadata-directive REPLACE"
DOCUMENT_SYNC_MODE="--metadata-directive REPLACE"
echo "🚀 Starting deployment with forced metadata update mode"
else
HASHED_SYNC_MODE="--size-only"
DOCUMENT_SYNC_MODE="" # Use normal sync (size+mtime) for documents
echo "🚀 Starting deployment with efficient sync mode (size-only for hashed assets, size+mtime for documents)"
fi
# Deploy JS and CSS files with 1-year cache (versioned, immutable assets)
echo "⚡ Deploying JS and CSS files with immutable cache headers..."
aws s3 sync docs/. s3://${{ env.S3_BUCKET_NAME }}/ \
--exclude "*" \
--include "*.js" \
--include "*.css" \
--cache-control "public, max-age=31536000, immutable" \
$HASHED_SYNC_MODE \
--exclude ".git/*"
# Deploy source map files with 1-year cache (versioned, immutable assets)
echo "🗺️ Deploying source map files with immutable cache headers..."
aws s3 sync docs/. s3://${{ env.S3_BUCKET_NAME }}/ \
--exclude "*" \
--include "*.js.map" \
--include "*.css.map" \
--cache-control "public, max-age=31536000, immutable" \
--content-type "application/json" \
$HASHED_SYNC_MODE \
--exclude ".git/*"
# Deploy font files with 1-year cache (static, immutable assets)
echo "🔤 Deploying font files with immutable cache headers..."
aws s3 sync docs/. s3://${{ env.S3_BUCKET_NAME }}/ \
--exclude "*" \
--include "*.woff" \
--include "*.woff2" \
--include "*.ttf" \
--include "*.eot" \
--include "*.otf" \
--cache-control "public, max-age=31536000, immutable" \
$HASHED_SYNC_MODE \
--exclude ".git/*"
# Deploy image files with 1-year cache (static, immutable assets, excluding screenshots)
echo "🖼️ Deploying image files with immutable cache headers..."
aws s3 sync docs/. s3://${{ env.S3_BUCKET_NAME }}/ \
--exclude "*" \
--include "*.webp" \
--include "*.png" \
--include "*.jpg" \
--include "*.jpeg" \
--include "*.gif" \
--include "*.svg" \
--include "*.ico" \
--cache-control "public, max-age=31536000, immutable" \
$HASHED_SYNC_MODE \
--exclude ".git/*" \
--exclude "screenshots/*"
# Deploy HTML files with short cache (1 hour, must revalidate)
# Use normal sync (size+mtime) for correctness - HTML is not content-hashed
echo "📄 Deploying HTML files with revalidation cache headers..."
aws s3 sync docs/. s3://${{ env.S3_BUCKET_NAME }}/ \
--exclude "*" \
--include "*.html" \
--cache-control "public, max-age=3600, must-revalidate" \
--content-type "text/html; charset=utf-8" \
$DOCUMENT_SYNC_MODE \
--exclude ".git/*"
# Deploy metadata files with medium cache (1 day)
# Use normal sync (size+mtime) for correctness - metadata files are not content-hashed
echo "📋 Deploying metadata files with 1-day cache headers..."
aws s3 sync docs/. s3://${{ env.S3_BUCKET_NAME }}/ \
--exclude "*" \
--include "*.xml" \
--include "*.json" \
--include "*.txt" \
--cache-control "public, max-age=86400" \
$DOCUMENT_SYNC_MODE \
--exclude ".git/*"
# Deploy screenshots with default cache (if directory exists)
if [ -d "docs/screenshots" ]; then
echo "📸 Deploying screenshots with default cache headers..."
aws s3 sync docs/screenshots/. s3://${{ env.S3_BUCKET_NAME }}/screenshots/ \
$HASHED_SYNC_MODE
else
echo "ℹ️ No screenshots directory found, skipping..."
fi
# Deploy all remaining files not already handled (catch-all)
echo "📦 Deploying remaining files..."
aws s3 sync docs/. s3://${{ env.S3_BUCKET_NAME }}/ \
--exclude ".git/*" \
--exclude "screenshots/*" \
--exclude "*.js" \
--exclude "*.css" \
--exclude "*.js.map" \
--exclude "*.css.map" \
--exclude "*.woff" \
--exclude "*.woff2" \
--exclude "*.ttf" \
--exclude "*.eot" \
--exclude "*.otf" \
--exclude "*.webp" \
--exclude "*.png" \
--exclude "*.jpg" \
--exclude "*.jpeg" \
--exclude "*.gif" \
--exclude "*.svg" \
--exclude "*.ico" \
--exclude "*.html" \
--exclude "*.xml" \
--exclude "*.json" \
--exclude "*.txt" \
$HASHED_SYNC_MODE
echo "✅ Deployment completed with optimized cache headers"
# Invalidate CloudFront cache to ensure latest content is served
- name: Invalidate CloudFront
run: |
echo "🔍 Discovering CloudFront distribution ID from stack: ${{ env.CLOUDFRONT_STACK_NAME }}"
CloudFrontDistId=$(aws cloudformation describe-stacks \
--stack-name ${{ env.CLOUDFRONT_STACK_NAME }} \
--query "Stacks[0].Outputs[?OutputKey=='CloudFrontDistributionId'].OutputValue" \
--output text 2>/dev/null || echo "")
if [ -z "$CloudFrontDistId" ]; then
echo "⚠️ Warning: CloudFront distribution ID not found in stack outputs"
echo "Attempting to find distribution by S3 origin domain..."
# List all distributions and filter by S3 bucket origin
CloudFrontDistId=$(aws cloudfront list-distributions \
--output json 2>/dev/null | \
jq -r ".DistributionList.Items[] | select(.Origins.Items[].DomainName | contains(\"${{ env.S3_BUCKET_NAME }}\")) | .Id" | \
head -n 1 || echo "")
fi
if [ -z "$CloudFrontDistId" ] || [ "$CloudFrontDistId" = "None" ]; then
echo "❌ Error: Could not discover CloudFront distribution ID"
exit 1
fi
echo "✅ Found CloudFront distribution: $CloudFrontDistId"
echo "🔄 Creating cache invalidation for all paths..."
aws cloudfront create-invalidation \
--distribution-id $CloudFrontDistId \
--paths "/*"
echo "✅ CloudFront cache invalidation completed"