1+ name : Build and deploy Docusaurus site to Azure Blob Storage
2+
3+ on :
4+ push :
5+ branches :
6+ - main
7+ - dev
8+ workflow_dispatch :
9+ inputs :
10+ environment :
11+ description : ' Environment to deploy to'
12+ required : true
13+ default : ' development'
14+ type : choice
15+ options :
16+ - development
17+ - production
18+
19+ jobs :
20+ determine-environment :
21+ runs-on : ubuntu-latest
22+ outputs :
23+ environment : ${{ steps.set-env.outputs.environment }}
24+ steps :
25+ - name : Determine environment
26+ id : set-env
27+ run : |
28+ if [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then
29+ echo "environment=${{ github.event.inputs.environment }}" >> $GITHUB_OUTPUT
30+ elif [[ "${{ github.ref }}" == "refs/heads/main" ]]; then
31+ echo "environment=production" >> $GITHUB_OUTPUT
32+ else
33+ echo "environment=development" >> $GITHUB_OUTPUT
34+ fi
35+
36+ build :
37+ runs-on : self-hosted
38+ needs : determine-environment
39+ environment : ${{ needs.determine-environment.outputs.environment }}
40+ permissions :
41+ contents : read
42+
43+ steps :
44+ - name : Check out source code
45+ uses : actions/checkout@v4
46+
47+ - name : Set up Node.js
48+ uses : actions/setup-node@v3
49+ with :
50+ node-version : ' 22.x'
51+
52+ - name : Cache Node.js dependencies
53+ uses : actions/cache@v3
54+ with :
55+ path : ~/.npm
56+ key : ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
57+ restore-keys : |
58+ ${{ runner.os }}-node-
59+
60+ - name : Cache Docusaurus build
61+ uses : actions/cache@v3
62+ id : cache-build
63+ with :
64+ path : |
65+ .docusaurus
66+ key : ${{ runner.os }}-docusaurus-${{ hashFiles('src/**', 'docs/**', 'blog/**', 'docusaurus.config.js', 'sidebars.js') }}
67+ restore-keys : |
68+ ${{ runner.os }}-docusaurus-
69+
70+ - name : Cache webpack
71+ uses : actions/cache@v3
72+ with :
73+ path : node_modules/.cache
74+ key : ${{ runner.os }}-webpack-${{ hashFiles('**/package-lock.json') }}
75+ restore-keys : |
76+ ${{ runner.os }}-webpack-
77+
78+ - name : Install dependencies and build site
79+ run : |
80+ npm ci
81+
82+ # Check if we have a valid cached build
83+ if [[ "${{ steps.cache-build.outputs.cache-hit }}" == "true" ]]; then
84+ echo "Build cache found, checking if rebuild needed..."
85+ # Docusaurus will intelligently rebuild only what's changed
86+ else
87+ echo "No build cache found, performing full build..."
88+ fi
89+
90+ # Run build - Docusaurus will use its internal caching
91+ npm run build
92+ env :
93+ NODE_OPTIONS : " --max-old-space-size=16384"
94+ DOCUSAURUS_URL : " https://${{ secrets.STORAGE_ACCOUNT_NAME }}.z13.web.core.windows.net"
95+ # Add any other environment-specific build variables here
96+ NODE_ENV : ${{ needs.determine-environment.outputs.environment }}
97+
98+ - name : Upload artifact for deployment
99+ uses : actions/upload-artifact@v4
100+ with :
101+ name : build-output
102+ path : build/
103+
104+ deploy :
105+ runs-on : ubuntu-latest
106+ needs : [build, determine-environment]
107+ environment : ${{ needs.determine-environment.outputs.environment }}
108+
109+ steps :
110+ - name : Download build artifact
111+ uses : actions/download-artifact@v4
112+ with :
113+ name : build-output
114+ path : build/
115+
116+ - name : Install azcopy
117+ run : |
118+ # Download and install azcopy for faster uploads
119+ wget -O azcopy.tar.gz https://aka.ms/downloadazcopy-v10-linux
120+ tar -xf azcopy.tar.gz --strip-components=1
121+ sudo mv azcopy /usr/local/bin/
122+ azcopy --version
123+
124+ - name : Upload to Azure Blob Storage with AzCopy and comprehensive MIME types
125+ run : |
126+ echo "Deploying to ${{ needs.determine-environment.outputs.environment }} environment"
127+ echo "Starting high-performance sync of changed files with proper MIME types..."
128+
129+ # Create SAS token for azcopy (more secure than using key directly)
130+ end_date=$(date -u -d "30 minutes" '+%Y-%m-%dT%H:%MZ')
131+ sas_token=$(az storage container generate-sas \
132+ --account-name ${{ secrets.STORAGE_ACCOUNT_NAME }} \
133+ --account-key ${{ secrets.STORAGE_ACCOUNT_KEY }} \
134+ --name '$web' \
135+ --permissions dlrw \
136+ --expiry $end_date \
137+ --output tsv)
138+
139+ # Use azcopy sync without content type mapping (will be set in fallback step)
140+ azcopy sync "./build/" \
141+ "https://${{ secrets.STORAGE_ACCOUNT_NAME }}.blob.core.windows.net/\$web?$sas_token" \
142+ --delete-destination=true \
143+ --compare-hash=MD5 \
144+ --log-level=INFO \
145+ --cap-mbps=0 \
146+ --block-size-mb=4
147+
148+ echo "Sync completed with comprehensive MIME types!"
149+
150+ - name : Set MIME types for all file types
151+ run : |
152+ echo "Setting MIME types for all file types..."
153+
154+ # Install Azure CLI if not available
155+ if ! command -v az &> /dev/null; then
156+ curl -sL https://aka.ms/InstallAzureCLIDeb | sudo bash
157+ fi
158+
159+ # Web files
160+ echo "Setting MIME types for web files..."
161+ az storage blob update-batch --account-name ${{ secrets.STORAGE_ACCOUNT_NAME }} --account-key ${{ secrets.STORAGE_ACCOUNT_KEY }} --source '$web' --pattern "*.css" --content-type "text/css" --if-unmodified-since "1970-01-01T00:00:00Z" --no-progress || true
162+ az storage blob update-batch --account-name ${{ secrets.STORAGE_ACCOUNT_NAME }} --account-key ${{ secrets.STORAGE_ACCOUNT_KEY }} --source '$web' --pattern "*.js" --content-type "application/javascript" --if-unmodified-since "1970-01-01T00:00:00Z" --no-progress || true
163+ az storage blob update-batch --account-name ${{ secrets.STORAGE_ACCOUNT_NAME }} --account-key ${{ secrets.STORAGE_ACCOUNT_KEY }} --source '$web' --pattern "*.mjs" --content-type "application/javascript" --if-unmodified-since "1970-01-01T00:00:00Z" --no-progress || true
164+ az storage blob update-batch --account-name ${{ secrets.STORAGE_ACCOUNT_NAME }} --account-key ${{ secrets.STORAGE_ACCOUNT_KEY }} --source '$web' --pattern "*.json" --content-type "application/json" --if-unmodified-since "1970-01-01T00:00:00Z" --no-progress || true
165+ az storage blob update-batch --account-name ${{ secrets.STORAGE_ACCOUNT_NAME }} --account-key ${{ secrets.STORAGE_ACCOUNT_KEY }} --source '$web' --pattern "*.html" --content-type "text/html" --if-unmodified-since "1970-01-01T00:00:00Z" --no-progress || true
166+ az storage blob update-batch --account-name ${{ secrets.STORAGE_ACCOUNT_NAME }} --account-key ${{ secrets.STORAGE_ACCOUNT_KEY }} --source '$web' --pattern "*.htm" --content-type "text/html" --if-unmodified-since "1970-01-01T00:00:00Z" --no-progress || true
167+ az storage blob update-batch --account-name ${{ secrets.STORAGE_ACCOUNT_NAME }} --account-key ${{ secrets.STORAGE_ACCOUNT_KEY }} --source '$web' --pattern "*.xml" --content-type "application/xml" --if-unmodified-since "1970-01-01T00:00:00Z" --no-progress || true
168+ az storage blob update-batch --account-name ${{ secrets.STORAGE_ACCOUNT_NAME }} --account-key ${{ secrets.STORAGE_ACCOUNT_KEY }} --source '$web' --pattern "*.txt" --content-type "text/plain" --if-unmodified-since "1970-01-01T00:00:00Z" --no-progress || true
169+
170+ # Images
171+ echo "Setting MIME types for images..."
172+ az storage blob update-batch --account-name ${{ secrets.STORAGE_ACCOUNT_NAME }} --account-key ${{ secrets.STORAGE_ACCOUNT_KEY }} --source '$web' --pattern "*.png" --content-type "image/png" --if-unmodified-since "1970-01-01T00:00:00Z" --no-progress || true
173+ az storage blob update-batch --account-name ${{ secrets.STORAGE_ACCOUNT_NAME }} --account-key ${{ secrets.STORAGE_ACCOUNT_KEY }} --source '$web' --pattern "*.jpg" --content-type "image/jpeg" --if-unmodified-since "1970-01-01T00:00:00Z" --no-progress || true
174+ az storage blob update-batch --account-name ${{ secrets.STORAGE_ACCOUNT_NAME }} --account-key ${{ secrets.STORAGE_ACCOUNT_KEY }} --source '$web' --pattern "*.jpeg" --content-type "image/jpeg" --if-unmodified-since "1970-01-01T00:00:00Z" --no-progress || true
175+ az storage blob update-batch --account-name ${{ secrets.STORAGE_ACCOUNT_NAME }} --account-key ${{ secrets.STORAGE_ACCOUNT_KEY }} --source '$web' --pattern "*.gif" --content-type "image/gif" --if-unmodified-since "1970-01-01T00:00:00Z" --no-progress || true
176+ az storage blob update-batch --account-name ${{ secrets.STORAGE_ACCOUNT_NAME }} --account-key ${{ secrets.STORAGE_ACCOUNT_KEY }} --source '$web' --pattern "*.webp" --content-type "image/webp" --if-unmodified-since "1970-01-01T00:00:00Z" --no-progress || true
177+ az storage blob update-batch --account-name ${{ secrets.STORAGE_ACCOUNT_NAME }} --account-key ${{ secrets.STORAGE_ACCOUNT_KEY }} --source '$web' --pattern "*.svg" --content-type "image/svg+xml" --if-unmodified-since "1970-01-01T00:00:00Z" --no-progress || true
178+ az storage blob update-batch --account-name ${{ secrets.STORAGE_ACCOUNT_NAME }} --account-key ${{ secrets.STORAGE_ACCOUNT_KEY }} --source '$web' --pattern "*.ico" --content-type "image/x-icon" --if-unmodified-since "1970-01-01T00:00:00Z" --no-progress || true
179+
180+ # Fonts
181+ echo "Setting MIME types for fonts..."
182+ az storage blob update-batch --account-name ${{ secrets.STORAGE_ACCOUNT_NAME }} --account-key ${{ secrets.STORAGE_ACCOUNT_KEY }} --source '$web' --pattern "*.woff" --content-type "font/woff" --if-unmodified-since "1970-01-01T00:00:00Z" --no-progress || true
183+ az storage blob update-batch --account-name ${{ secrets.STORAGE_ACCOUNT_NAME }} --account-key ${{ secrets.STORAGE_ACCOUNT_KEY }} --source '$web' --pattern "*.woff2" --content-type "font/woff2" --if-unmodified-since "1970-01-01T00:00:00Z" --no-progress || true
184+ az storage blob update-batch --account-name ${{ secrets.STORAGE_ACCOUNT_NAME }} --account-key ${{ secrets.STORAGE_ACCOUNT_KEY }} --source '$web' --pattern "*.ttf" --content-type "font/ttf" --if-unmodified-since "1970-01-01T00:00:00Z" --no-progress || true
185+ az storage blob update-batch --account-name ${{ secrets.STORAGE_ACCOUNT_NAME }} --account-key ${{ secrets.STORAGE_ACCOUNT_KEY }} --source '$web' --pattern "*.otf" --content-type "font/otf" --if-unmodified-since "1970-01-01T00:00:00Z" --no-progress || true
186+
187+ echo "All MIME types set successfully!"
188+
189+ - name : Purge CDN endpoint (if configured)
190+ run : |
191+ if [[ -n "${{ secrets.CDN_ENDPOINT_NAME }}" ]] && [[ -n "${{ secrets.CDN_PROFILE_NAME }}" ]] && [[ -n "${{ secrets.CDN_RESOURCE_GROUP }}" ]]; then
192+ echo "Note: CDN purge requires Azure login. Skipping CDN purge when using storage key authentication."
193+ echo "To use CDN purge, you'll need to use Azure AD authentication or purge CDN manually."
194+ else
195+ echo "CDN configuration not found, skipping CDN purge."
196+ fi
197+
198+ - name : Display deployment URL
199+ run : |
200+ echo "🚀 Deployment complete!"
201+ echo "Environment: ${{ needs.determine-environment.outputs.environment }}"
202+ echo "URL: https://${{ secrets.STORAGE_ACCOUNT_NAME }}.z13.web.core.windows.net"
203+ if [[ -n "${{ secrets.CUSTOM_DOMAIN }}" ]]; then
204+ echo "Custom Domain: ${{ secrets.CUSTOM_DOMAIN }}"
205+ fi
206+ echo "All files deployed with proper MIME types for optimal browser compatibility!"
0 commit comments