name: Build Windows portable on: workflow_dispatch: {} push: branches: [main] paths: - "app/**" - "crates/**" - "Cargo.lock" - "scripts/fetch-pdfium.ps1" - "scripts/fetch-qpdf.ps1" - ".github/workflows/build-windows.yml" permissions: contents: write jobs: build: runs-on: windows-latest steps: - uses: actions/checkout@v4 - uses: dtolnay/rust-toolchain@stable - name: Cache cargo uses: actions/cache@v4 with: path: | ~/.cargo/registry ~/.cargo/git target app/src-tauri/target key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }} - name: Fetch PDFium (Windows x64) shell: pwsh run: powershell -ExecutionPolicy Bypass -File scripts/fetch-pdfium.ps1 - name: Fetch QPDF (Windows x64) shell: pwsh run: powershell -ExecutionPolicy Bypass -File scripts/fetch-qpdf.ps1 # Bộ font Noto đóng gói theo app (phủ tiếng Việt) — hiển thị/ghi file # giống nhau trên mọi máy khách, không phụ thuộc font hệ điều hành. - name: Cache bundled fonts uses: actions/cache@v4 with: path: fonts key: noto-fonts-${{ hashFiles('scripts/fetch-fonts.ps1') }} - name: Fetch bundled fonts (Noto) shell: pwsh run: powershell -ExecutionPolicy Bypass -File scripts/fetch-fonts.ps1 # Test OCR cần tesseract thật (eng + vie). Chocolatey có sẵn trên runner. - name: Install Tesseract OCR (eng + vie) shell: pwsh run: | choco install tesseract -y --no-progress $tessdata = "C:\Program Files\Tesseract-OCR\tessdata" Invoke-WebRequest "https://github.com/tesseract-ocr/tessdata_fast/raw/main/vie.traineddata" -OutFile "$tessdata\vie.traineddata" echo "FOFREEXIT_TESSERACT_PATH=C:\Program Files\Tesseract-OCR\tesseract.exe" >> $env:GITHUB_ENV # Máy dev không có Rust — CI là nơi duy nhất chạy test engine. # Fail test = fail build, không publish bản hỏng. # --test-threads=1: PDFium serialize qua 1 mutex toàn cục; 1 test panic # khi đang giữ lock sẽ poison mutex làm mọi test song song chết oan. # FOFREEXIT_QPDF_PATH: test chạy với cwd = thư mục crate nên không tự # thấy qpdf/ ở root repo (test form/qpdf cần). - name: Run engine tests run: cargo test -p ff-engine -- --test-threads=1 env: FOFREEXIT_QPDF_PATH: ${{ github.workspace }}\qpdf\bin\qpdf.exe - name: Build release working-directory: app/src-tauri run: cargo build --release - name: Assemble portable folder shell: pwsh run: | $dist = "dist/FoFreeXit" New-Item -ItemType Directory -Force -Path $dist | Out-Null Copy-Item "app/src-tauri/target/release/fofreexit-app.exe" "$dist/FoFreeXit.exe" Copy-Item "pdfium.dll" "$dist/pdfium.dll" Copy-Item "qpdf/bin/*.exe" "$dist/" Copy-Item "qpdf/bin/*.dll" "$dist/" Copy-Item "scripts/portable-readme.txt" "$dist/DOC-doc-truoc-khi-chay.txt" New-Item -ItemType Directory -Force -Path "$dist/fonts" | Out-Null Copy-Item "fonts/*" "$dist/fonts/" Compress-Archive -Path "$dist/*" -DestinationPath "FoFreeXit-portable-win64.zip" -Force - name: Upload artifact uses: actions/upload-artifact@v4 with: name: FoFreeXit-portable-win64 path: FoFreeXit-portable-win64.zip retention-days: 30 - name: Publish GitHub Release uses: softprops/action-gh-release@v2 with: tag_name: win-build-${{ github.run_number }} name: "FoFreeXit Windows portable (build ${{ github.run_number }})" body: | Ban build Windows portable tu dong (khong can cai Rust/Visual Studio). Giai nen `FoFreeXit-portable-win64.zip` roi chay `FoFreeXit.exe`. Commit: ${{ github.sha }} files: FoFreeXit-portable-win64.zip prerelease: true env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}