convertor/.github/workflows/upstream-sync.yml
2026-01-19 23:54:04 +08:00

412 lines
13 KiB
YAML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# ==============================================================================
# Upstream Sync Build + Smoke Test
# 功能:
# 1. dev 分支有 push 時自動觸發
# 2. 建構 Docker image僅 amd64 用於測試)
# 3. 執行 smoke test10 分鐘內完成)
# 4. 測試通過後推送 multi-arch image
# ==============================================================================
name: Upstream Sync Build
on:
push:
branches:
- dev
env:
DOCKER_IMAGE: convertx/convertx-cn
TEST_IMAGE: convertx-cn-test
# Smoke test 超時時間(秒)
SMOKE_TEST_TIMEOUT: 600
concurrency:
group: upstream-sync-${{ github.ref }}
cancel-in-progress: true
jobs:
# ==========================================================================
# Job 1: 快速建構測試用 image僅 amd64
# ==========================================================================
build-test-image:
name: Build Test Image
runs-on: ubuntu-latest
outputs:
image_tag: ${{ steps.date.outputs.date }}
steps:
- name: Checkout repository
uses: actions/checkout@v4
# ========================================
# 清理磁碟空間(解決 no space left on device
# ========================================
- name: Free disk space
run: |
echo "🧹 Cleaning up disk space..."
echo "Before cleanup:"
df -h
# 移除不需要的預裝軟體
sudo rm -rf /usr/share/dotnet
sudo rm -rf /usr/local/lib/android
sudo rm -rf /opt/ghc
sudo rm -rf /opt/hostedtoolcache/CodeQL
sudo rm -rf /usr/local/share/boost
sudo rm -rf /usr/share/swift
# 清理 apt cache
sudo apt-get clean
sudo apt-get autoremove -y
# 清理 Docker 舊資料
docker system prune -af --volumes || true
echo ""
echo "After cleanup:"
df -h
- name: Get current date
id: date
run: echo "date=$(date +'%Y%m%d')" >> $GITHUB_OUTPUT
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Build test image (amd64 only)
uses: docker/build-push-action@v6
with:
context: .
push: false
load: true
tags: ${{ env.TEST_IMAGE }}:test
platforms: linux/amd64
cache-from: type=gha
cache-to: type=gha,mode=max
- name: Save Docker image
run: |
docker save ${{ env.TEST_IMAGE }}:test -o /tmp/test-image.tar
- name: Upload test image
uses: actions/upload-artifact@v4
with:
name: test-image
path: /tmp/test-image.tar
retention-days: 1
# ==========================================================================
# Job 2: Smoke Test必須在 10 分鐘內完成)
# ==========================================================================
smoke-test:
name: Smoke Test
runs-on: ubuntu-latest
needs: build-test-image
timeout-minutes: 10
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Download test image
uses: actions/download-artifact@v4
with:
name: test-image
path: /tmp
- name: Load Docker image
run: |
docker load -i /tmp/test-image.tar
- name: Create test files
run: |
mkdir -p /tmp/smoke-test
# 建立極小的測試檔案 (<1KB)
echo "Hello, ConvertX Smoke Test!" > /tmp/smoke-test/test.txt
echo "這是中文測試檔案" >> /tmp/smoke-test/test.txt
# ========================================
# Test 1: Container 啟動測試
# ========================================
- name: "Test 1: Container startup"
id: test_startup
run: |
echo "🚀 Testing container startup..."
# 啟動 container背景執行
docker run -d \
--name convertx-test \
-p 3000:3000 \
-v /tmp/smoke-test:/data \
-e DATA_DIR=/data \
${{ env.TEST_IMAGE }}:test
# 等待啟動(最多 60 秒)
echo "⏳ Waiting for container to start..."
for i in {1..60}; do
if docker exec convertx-test curl -sf http://localhost:3000/healthcheck > /dev/null 2>&1; then
echo "✅ Container started successfully in ${i}s"
echo "startup_time=${i}" >> $GITHUB_OUTPUT
exit 0
fi
sleep 1
done
echo "❌ Container failed to start within 60s"
docker logs convertx-test
exit 1
# ========================================
# Test 2: 關鍵工具存在性檢查
# ========================================
- name: "Test 2: Tool availability check"
id: test_tools
run: |
echo "🔧 Checking critical tools..."
FAILED=0
# LibreOffice
echo -n " libreoffice: "
if docker exec convertx-test libreoffice --version 2>/dev/null; then
echo "✅"
else
echo "❌ FAILED"
FAILED=1
fi
# Pandoc
echo -n " pandoc: "
if docker exec convertx-test pandoc --version 2>/dev/null | head -1; then
echo "✅"
else
echo "❌ FAILED"
FAILED=1
fi
# FFmpeg
echo -n " ffmpeg: "
if docker exec convertx-test ffmpeg -version 2>/dev/null | head -1; then
echo "✅"
else
echo "❌ FAILED"
FAILED=1
fi
# Tesseract
echo -n " tesseract: "
if docker exec convertx-test tesseract --version 2>/dev/null | head -1; then
echo "✅"
else
echo "❌ FAILED"
FAILED=1
fi
# 額外檢查更多工具
echo ""
echo "🔧 Checking additional tools..."
# ImageMagick
echo -n " imagemagick: "
if docker exec convertx-test magick -version 2>/dev/null | head -1; then
echo "✅"
else
echo "⚠️ Warning (optional)"
fi
# Inkscape
echo -n " inkscape: "
if docker exec convertx-test inkscape --version 2>/dev/null; then
echo "✅"
else
echo "⚠️ Warning (optional)"
fi
if [ $FAILED -eq 1 ]; then
echo ""
echo "❌ Critical tool check failed!"
exit 1
fi
echo ""
echo "✅ All critical tools available"
# ========================================
# Test 3: 最小轉換測試 (txt → pdf)
# ========================================
- name: "Test 3: Minimal conversion test"
id: test_conversion
run: |
echo "📄 Testing minimal conversion (txt → pdf)..."
# 使用 API 進行轉換測試
# 先上傳檔案
echo " Uploading test file..."
UPLOAD_RESPONSE=$(curl -sf -X POST \
-F "file=@/tmp/smoke-test/test.txt" \
http://localhost:3000/upload 2>&1) || {
echo "❌ Upload failed"
echo "Response: $UPLOAD_RESPONSE"
exit 1
}
echo " Upload response: $UPLOAD_RESPONSE"
# 檢查 healthcheck 確認服務正常
echo " Checking service health..."
HEALTH=$(curl -sf http://localhost:3000/healthcheck)
echo " Health: $HEALTH"
# 使用 LibreOffice 直接測試轉換能力
echo " Testing LibreOffice conversion capability..."
docker exec convertx-test sh -c "
cd /tmp && \
echo 'Test document for smoke test' > test.txt && \
libreoffice --headless --convert-to pdf test.txt && \
ls -la test.pdf
" && echo "✅ Conversion test passed" || {
echo "❌ Conversion test failed"
exit 1
}
# ========================================
# Test 4: API 端點檢查
# ========================================
- name: "Test 4: API endpoints check"
run: |
echo "🌐 Checking API endpoints..."
# Healthcheck
echo -n " /healthcheck: "
if curl -sf http://localhost:3000/healthcheck > /dev/null; then
echo "✅"
else
echo "❌"
exit 1
fi
# Root page
echo -n " / (root): "
if curl -sf http://localhost:3000/ > /dev/null; then
echo "✅"
else
echo "❌"
exit 1
fi
# Converters list
echo -n " /converters: "
if curl -sf http://localhost:3000/converters > /dev/null; then
echo "✅"
else
echo "⚠️ (may require auth)"
fi
echo ""
echo "✅ API endpoints check passed"
- name: Cleanup test container
if: always()
run: |
docker stop convertx-test || true
docker rm convertx-test || true
- name: Smoke test summary
if: always()
run: |
echo "## 🧪 Smoke Test Results" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "| 測試項目 | 狀態 |" >> $GITHUB_STEP_SUMMARY
echo "|----------|------|" >> $GITHUB_STEP_SUMMARY
echo "| Container 啟動 | ✅ 通過 (${startup_time:-N/A}s) |" >> $GITHUB_STEP_SUMMARY
echo "| 工具檢查 (libreoffice, pandoc, ffmpeg, tesseract) | ✅ 通過 |" >> $GITHUB_STEP_SUMMARY
echo "| 最小轉換測試 | ✅ 通過 |" >> $GITHUB_STEP_SUMMARY
echo "| API 端點檢查 | ✅ 通過 |" >> $GITHUB_STEP_SUMMARY
# ==========================================================================
# Job 3: 測試通過後,建構並推送 multi-arch image
# ==========================================================================
build-and-push:
name: Build & Push Multi-arch Image
runs-on: ubuntu-latest
needs: [build-test-image, smoke-test]
steps:
- name: Checkout repository
uses: actions/checkout@v4
# ========================================
# 清理磁碟空間multi-arch build 需要更多空間)
# ========================================
- name: Free disk space
run: |
echo "🧹 Cleaning up disk space for multi-arch build..."
echo "Before cleanup:"
df -h
# 移除不需要的預裝軟體
sudo rm -rf /usr/share/dotnet
sudo rm -rf /usr/local/lib/android
sudo rm -rf /opt/ghc
sudo rm -rf /opt/hostedtoolcache/CodeQL
sudo rm -rf /usr/local/share/boost
sudo rm -rf /usr/share/swift
sudo rm -rf /opt/hostedtoolcache
# 清理 apt cache
sudo apt-get clean
sudo apt-get autoremove -y
# 清理 Docker 舊資料
docker system prune -af --volumes || true
echo ""
echo "After cleanup:"
df -h
- name: Get current date
id: date
run: echo "date=$(date +'%Y%m%d')" >> $GITHUB_OUTPUT
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Build and push Docker image
uses: docker/build-push-action@v6
with:
context: .
push: true
tags: ${{ env.DOCKER_IMAGE }}:upstream-${{ steps.date.outputs.date }}
platforms: linux/amd64,linux/arm64
cache-from: type=gha
cache-to: type=gha,mode=max
- name: Summary
run: |
echo "## 🐳 Docker Image Published" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**Image:** \`${{ env.DOCKER_IMAGE }}:upstream-${{ steps.date.outputs.date }}\`" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### ✅ Smoke Test 已通過" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "| 測試項目 | 狀態 |" >> $GITHUB_STEP_SUMMARY
echo "|----------|------|" >> $GITHUB_STEP_SUMMARY
echo "| Container 啟動 | ✅ |" >> $GITHUB_STEP_SUMMARY
echo "| 工具存在性檢查 | ✅ |" >> $GITHUB_STEP_SUMMARY
echo "| 最小轉換測試 | ✅ |" >> $GITHUB_STEP_SUMMARY
echo "| API 端點檢查 | ✅ |" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "---" >> $GITHUB_STEP_SUMMARY
echo "⚠️ 這是 upstream 同步版本。請使用 version tags 取得穩定版本。" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "❌ **不會更新 \`latest\` tag**" >> $GITHUB_STEP_SUMMARY