1- name : Deploy to GitHub Pages
1+ name : Deploy Hexo to GitHub Pages (Safe Version)
22
33on :
44 push :
5- branches :
6- - main
7- pull_request :
8- branches :
9- - main
5+ branches : [main]
106 workflow_dispatch :
117
128jobs :
13- # 构建和测试作业
14- build-and-test :
9+ deploy :
1510 runs-on : ubuntu-latest
1611 permissions :
1712 contents : read
18- env :
19- NODE_VERSION : " 20"
13+ pages : write
14+ id-token : write
15+
16+ environment :
17+ name : github-pages
18+ url : ${{ steps.deployment.outputs.page_url }}
19+
2020 defaults :
2121 run :
22- shell : bash
2322 working-directory : ./src
2423
2524 steps :
26- - name : Checkout repository
25+ - name : Checkout
2726 uses : actions/checkout@v4
2827 with :
29- token : ${{ secrets.GITHUB_TOKEN }}
3028 submodules : recursive
31- fetch-depth : 0 # 获取完整历史用于缓存优化
29+ fetch-depth : 0
3230
3331 - name : Setup Node.js
3432 uses : actions/setup-node@v4
3533 with :
36- node-version : ${{ env.NODE_VERSION }}
34+ node-version : " 20 "
3735 cache : " npm"
3836 cache-dependency-path : " ./src/package-lock.json"
3937
40- - name : Cache node_modules
41- uses : actions/cache@v4
42- with :
43- path : |
44- ./src/node_modules
45- ~/.npm
46- key : ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
47- restore-keys : |
48- ${{ runner.os }}-node-
49- ${{ runner.os }}-
50-
5138 - name : Install dependencies
5239 run : npm ci --prefer-offline --no-audit
5340
54- - name : Check for security vulnerabilities
55- run : npm audit --audit-level=moderate || true
56-
5741 - name : Clean previous build
5842 run : |
5943 echo "🧹 Cleaning previous build..."
6044 npm run clean || echo "Clean command completed"
61- rm -rf public/ || echo "No previous public directory to remove"
6245
6346 - name : Build site
6447 run : npm run build
6548 env :
6649 NODE_ENV : production
6750
68- - name : Verify build success
51+ - name : Verify build output
6952 run : |
70- echo "🔍 Verifying build success ..."
53+ echo "🔍 Verifying build output ..."
7154 if [ ! -d "public" ]; then
7255 echo "❌ Build failed: public directory not found"
73- echo "🔍 Checking for build errors..."
74- echo "Current directory: $(pwd)"
75- ls -la
76- echo "🔍 Checking for any generated files..."
77- find . -type f -name "*.html" -o -name "*.css" -o -name "*.js" | head -10
7856 exit 1
7957 fi
80- echo "✅ Build successful: public directory found"
81-
82- - name : Debug build output
83- run : |
84- echo "🔍 Debugging build output..."
85- echo "Current directory: $(pwd)"
86- echo "Directory contents:"
87- ls -la
88- echo ""
89- echo "Checking for public directory:"
90- if [ -d "public" ]; then
91- echo "✅ Public directory exists"
92- echo "Public directory contents:"
93- ls -la public/ | head -10
94- echo "Total files in public: $(find public -type f | wc -l)"
95- else
96- echo "❌ Public directory not found"
97- echo "Looking for other possible output directories:"
98- find . -maxdepth 2 -type d -name "*public*" -o -name "*dist*" -o -name "*build*" 2>/dev/null || echo "No common output directories found"
99- fi
100-
101- - name : Clean problematic files
102- run : |
103- echo "🧹 Cleaning problematic files..."
104-
105- # 检查 public 目录是否存在
106- if [ ! -d "public" ]; then
107- echo "⚠️ Public directory not found, skipping cleanup"
108- exit 0
109- fi
110-
111- echo "📊 Checking artifact size and content..."
112-
113- # 删除 Zone.Identifier 文件
114- find ./public -name "*:Zone.Identifier" -type f -delete
115- find ./public -name "*.Zone.Identifier" -type f -delete
11658
117- # 删除其他可能包含冒号的文件
118- find ./public -name "*:*" -type f -delete
119-
120- # 删除隐藏文件
121- find ./public -name ".*" -type f -delete
122-
123- # 删除 macOS 系统文件
124- find ./public -name ".DS_Store" -type f -delete
125- find ./public -name "Thumbs.db" -type f -delete
126-
127- # 删除符号链接
128- find ./public -type l -delete
129-
130- # 处理硬链接(保留一个副本,删除重复的)
131- echo "🔍 Checking for hard links..."
132- find ./public -type f -exec ls -i {} \; | awk '{print $1}' | sort | uniq -d | while read inode; do
133- echo "⚠️ Found hard links with inode $inode"
134- # 找到所有具有相同 inode 的文件
135- files=$(find ./public -type f -inum "$inode")
136- # 保留第一个文件,删除其余的
137- first_file=$(echo "$files" | head -1)
138- echo " Keeping: $first_file"
139- echo "$files" | tail -n +2 | xargs rm -f
140- done
141-
142- # 检查总大小
143- TOTAL_SIZE_BYTES=$(du -sb ./public | cut -f1)
144- TOTAL_SIZE_GB=$(echo "scale=2; $TOTAL_SIZE_BYTES / 1024 / 1024 / 1024" | bc -l 2>/dev/null || echo "0")
145- echo "📊 Total artifact size: $(du -sh ./public | cut -f1) ($TOTAL_SIZE_GB GB)"
146-
147- # 检查是否超过 10GB 限制
148- if (( $(echo "$TOTAL_SIZE_GB > 10" | bc -l) )); then
149- echo "❌ Artifact size exceeds 10GB limit: $TOTAL_SIZE_GB GB"
150- echo "🔍 Largest files:"
151- find ./public -type f -exec ls -lh {} \; | sort -k5 -hr | head -10
59+ if [ ! -f "public/index.html" ]; then
60+ echo "❌ Build failed: index.html not found"
15261 exit 1
15362 fi
15463
155- # 检查文件数量
156- FILE_COUNT=$(find ./public -type f | wc -l)
157- echo "📊 Total files: $FILE_COUNT"
158-
159- # 列出最大的文件
160- echo "🔍 Largest files:"
161- find ./public -type f -exec ls -lh {} \; | sort -k5 -hr | head -5
162-
163- echo "✅ Problematic files cleaned"
164-
165- - name : Test build output
166- run : |
167- if [ ! -d "public" ]; then
168- echo "❌ Build failed: public directory not found"
64+ INDEX_SIZE=$(stat -c%s "public/index.html" 2>/dev/null || stat -f%z "public/index.html")
65+ if [ "$INDEX_SIZE" -eq 0 ]; then
66+ echo "❌ Build failed: index.html is empty (0 bytes)"
16967 exit 1
17068 fi
171- echo "✅ Build successful: $(find public -type f | wc -l) files generated"
17269
173- - name : Verify build output
174- run : |
175- echo "📦 Verifying build output..."
176- if [ -d "./public" ]; then
177- echo "✅ Public directory exists with $(find ./public -type f | wc -l) files"
178- ls -la ./public/ | head -5
179- else
180- echo "❌ Public directory not found"
181- exit 1
182- fi
183-
184- # 部署作业
185- deploy :
186- needs : build-and-test
187- runs-on : ubuntu-latest
188- if : github.ref == 'refs/heads/main' && github.event_name == 'push'
70+ echo "✅ Build successful:"
71+ echo " - Files generated: $(find public -type f | wc -l)"
72+ echo " - index.html size: $INDEX_SIZE bytes"
73+ echo " - .nojekyll exists: $([ -f 'public/.nojekyll' ] && echo 'Yes' || echo 'No')"
18974
190- permissions :
191- pages : write
192- id-token : write
193- contents : write
194-
195- environment :
196- name : github-pages
197- url : ${{ steps.deployment.outputs.page_url }}
198-
199- steps :
200- - name : Checkout repository
201- uses : actions/checkout@v4
202-
203- - name : Setup Node.js
204- uses : actions/setup-node@v4
205- with :
206- node-version : " 20"
207- cache : " npm"
208- cache-dependency-path : " ./src/package-lock.json"
209-
210- - name : Install dependencies
211- run : npm ci --prefer-offline --no-audit
212- working-directory : ./src
213-
214- - name : Build site
215- run : npm run build
216- env :
217- NODE_ENV : production
218- working-directory : ./src
219-
220- - name : Clean problematic files
75+ - name : Clean only problematic files (minimal)
22176 run : |
222- echo "🧹 Cleaning problematic files..."
223-
224- # 检查 public 目录是否存在
225- if [ ! -d "public" ]; then
226- echo "⚠️ Public directory not found, skipping cleanup"
227- exit 0
228- fi
229-
230- echo "📊 Checking artifact size and content..."
77+ echo "🧹 Cleaning only essential problematic files..."
23178
232- # 删除 Zone.Identifier 文件
233- find ./public -name "*:Zone.Identifier" -type f -delete
234- find ./public -name "*.Zone.Identifier" -type f -delete
79+ # 只删除明确的系统文件,不使用通配符
80+ find ./public -name ".DS_Store" -type f -delete 2>/dev/null || true
81+ find ./public -name "Thumbs.db" -type f -delete 2>/dev/null || true
82+ find ./public -name "*:Zone.Identifier" -type f -delete 2>/dev/null || true
83+ find ./public -name "*.Zone.Identifier" -type f -delete 2>/dev/null || true
23584
236- # 删除其他可能包含冒号的文件
237- find ./public -name "*:*" -type f -delete
85+ echo "✅ Minimal cleanup completed"
23886
239- # 删除隐藏文件
240- find ./public -name ".*" -type f -delete
241-
242- # 删除 macOS 系统文件
243- find ./public -name ".DS_Store" -type f -delete
244- find ./public -name "Thumbs.db" -type f -delete
245-
246- # 删除符号链接
247- find ./public -type l -delete
248-
249- # 处理硬链接(保留一个副本,删除重复的)
250- echo "🔍 Checking for hard links..."
251- find ./public -type f -exec ls -i {} \; | awk '{print $1}' | sort | uniq -d | while read inode; do
252- echo "⚠️ Found hard links with inode $inode"
253- # 找到所有具有相同 inode 的文件
254- files=$(find ./public -type f -inum "$inode")
255- # 保留第一个文件,删除其余的
256- first_file=$(echo "$files" | head -1)
257- echo " Keeping: $first_file"
258- echo "$files" | tail -n +2 | xargs rm -f
259- done
260-
261- # 检查总大小
262- TOTAL_SIZE_BYTES=$(du -sb ./public | cut -f1)
263- TOTAL_SIZE_GB=$(echo "scale=2; $TOTAL_SIZE_BYTES / 1024 / 1024 / 1024" | bc -l 2>/dev/null || echo "0")
264- echo "📊 Total artifact size: $(du -sh ./public | cut -f1) ($TOTAL_SIZE_GB GB)"
265-
266- # 检查是否超过 10GB 限制
267- if (( $(echo "$TOTAL_SIZE_GB > 10" | bc -l) )); then
268- echo "❌ Artifact size exceeds 10GB limit: $TOTAL_SIZE_GB GB"
269- echo "🔍 Largest files:"
270- find ./public -type f -exec ls -lh {} \; | sort -k5 -hr | head -10
87+ - name : Final verification
88+ run : |
89+ echo "🔍 Final verification..."
90+ INDEX_SIZE=$(stat -c%s "public/index.html" 2>/dev/null || stat -f%z "public/index.html")
91+ if [ "$INDEX_SIZE" -eq 0 ]; then
92+ echo "❌ index.html became empty after cleanup!"
27193 exit 1
27294 fi
273-
274- # 检查文件数量
275- FILE_COUNT=$(find ./public -type f | wc -l)
276- echo "📊 Total files: $FILE_COUNT"
277-
278- # 列出最大的文件
279- echo "🔍 Largest files:"
280- find ./public -type f -exec ls -lh {} \; | sort -k5 -hr | head -5
281-
282- echo "✅ Problematic files cleaned"
95+ echo "✅ index.html still valid: $INDEX_SIZE bytes"
28396
28497 - name : Upload Pages artifact
28598 uses : actions/upload-pages-artifact@v3
@@ -290,68 +103,7 @@ jobs:
290103 id : deployment
291104 uses : actions/deploy-pages@v4
292105
293- - name : Verify deployment
106+ - name : Deployment success
294107 run : |
295108 echo "🚀 Deployment completed successfully!"
296109 echo "🌐 Site URL: ${{ steps.deployment.outputs.page_url }}"
297-
298- - name : Notify deployment status
299- if : always()
300- run : |
301- if [ "${{ job.status }}" == "success" ]; then
302- echo "✅ Deployment successful to ${{ steps.deployment.outputs.page_url }}"
303- else
304- echo "❌ Deployment failed"
305- exit 1
306- fi
307-
308- # 性能检查作业
309- performance-check :
310- runs-on : ubuntu-latest
311- if : github.ref == 'refs/heads/main' && github.event_name == 'push'
312- permissions :
313- contents : read
314-
315- steps :
316- - name : Checkout repository
317- uses : actions/checkout@v4
318-
319- - name : Setup Node.js
320- uses : actions/setup-node@v4
321- with :
322- node-version : " 20"
323- cache : " npm"
324- cache-dependency-path : " ./src/package-lock.json"
325-
326- - name : Install dependencies
327- run : npm ci --prefer-offline --no-audit
328- working-directory : ./src
329-
330- - name : Build site
331- run : npm run build
332- env :
333- NODE_ENV : production
334- working-directory : ./src
335-
336- - name : Check build size
337- run : |
338- BUILD_SIZE=$(du -sh ./src/public | cut -f1)
339- echo "📊 Build size: $BUILD_SIZE"
340-
341- # 检查是否有过大的文件
342- LARGE_FILES=$(find ./src/public -type f -size +1M | wc -l)
343- if [ $LARGE_FILES -gt 0 ]; then
344- echo "⚠️ Found $LARGE_FILES files larger than 1MB"
345- find ./src/public -type f -size +1M -exec ls -lh {} \;
346- else
347- echo "✅ No large files detected"
348- fi
349-
350- - name : Check for broken links (basic)
351- run : |
352- # 简单的链接检查
353- HTML_FILES=$(find ./src/public -name "*.html" | head -5)
354- for file in $HTML_FILES; do
355- echo "Checking $file..."
356- grep -o 'href="[^"]*"' "$file" | head -3 || true
357- done
0 commit comments