Files
BadNote/.gitea/workflows/ci.yml
Akiba So 9db688d948
All checks were successful
CI / Windows build (push) Successful in 10m10s
fix(windows): require Flutter 3.44 for pen input
Surface Pen reports as PointerDeviceKind.stylus and multitouch is
delivered only on Flutter 3.44+ (WM_POINTER migration, PR #165323).
3.41.4 dropped pen events, so our stylus-kind capture got nothing and
pinch-zoom did not work. Pin CI to Flutter 3.44.2 (shadowing any cached
older SDK on the runner) and require flutter >=3.44.0 in pubspec.
2026-06-21 21:35:24 +08:00

240 lines
12 KiB
YAML

name: CI
on:
push:
branches: [main]
tags: ["v*"]
pull_request:
branches: [main]
workflow_dispatch:
# Targets a self-hosted Windows runner inside mainland China. See README
# "Continuous integration" for runner prerequisites. Key points:
# * github.com is unreachable here, so the checkout action is pulled from the
# gitea.com mirror. If gitea.com is also unreachable, use the manual
# checkout fallback below (it clones from your own Gitea instance).
# * Flutter must be pre-installed on the runner (the dev machine). We do NOT
# download the SDK.
# * pub/Flutter use the flutter-io.cn mirrors; the sqlite3 native binary is
# vendored (vendor/sqlite3/), so neither is downloaded from GitHub.
# * The flutter_onnxruntime plugin downloads the ONNX Runtime native lib from
# GitHub during the Windows build; we route that through the local proxy.
env:
PUB_HOSTED_URL: https://pub.flutter-io.cn
FLUTTER_STORAGE_BASE_URL: https://storage.flutter-io.cn
jobs:
windows:
name: Windows build
runs-on: windows-latest
steps:
- name: Checkout
uses: https://gitea.com/actions/checkout@v4
# Ensure Flutter is available. The runner's Actions shell does not have
# Flutter on PATH, so: use it if present (PATH / FLUTTER_ROOT / common
# dirs), otherwise install the pinned SDK from the flutter-io.cn mirror
# into a persistent dir (C:\flutter-ci) that is reused across runs.
# Pin Flutter 3.44.2 DETERMINISTICALLY. pdfrx needs Windows stylus +
# multitouch, which only landed in Flutter 3.44.0 (WM_POINTER migration).
# We install into a version-pinned dir and PREPEND it to PATH so this
# version shadows any older Flutter already on the runner (a stale
# C:\flutter-ci from prior runs must NOT win, or pen input breaks again).
- name: Set up Flutter (pinned 3.44.2)
shell: powershell
run: |
$ErrorActionPreference = 'Stop'
$ProgressPreference = 'SilentlyContinue'
$ver = '3.44.2'
$root = "C:\flutter-$ver"
$bin = Join-Path $root 'flutter\bin'
if (-not (Test-Path (Join-Path $bin 'flutter.bat'))) {
$url = "https://storage.flutter-io.cn/flutter_infra_release/releases/stable/windows/flutter_windows_$ver-stable.zip"
$zip = Join-Path $env:TEMP "flutter_$ver.zip"
New-Item -ItemType Directory -Force -Path $root | Out-Null
Write-Host "Downloading Flutter $ver from $url"
$ok = $false
$curl = "$env:SystemRoot\System32\curl.exe"
if (Test-Path $curl) {
& $curl -L --fail --retry 3 --retry-delay 5 -o $zip $url
if ($LASTEXITCODE -eq 0 -and (Test-Path $zip)) { $ok = $true }
else { Write-Host "curl download failed (exit $LASTEXITCODE), falling back" }
}
if (-not $ok) {
for ($i = 1; $i -le 3 -and -not $ok; $i++) {
try { Invoke-WebRequest -Uri $url -OutFile $zip -UseBasicParsing; $ok = $true }
catch { Write-Host "IWR attempt $i failed: $_"; Start-Sleep 5 }
}
}
if (-not $ok) { Write-Error "Failed to download Flutter $ver"; exit 1 }
Write-Host "Extracting to $root (slow on first run)"
Expand-Archive -Path $zip -DestinationPath $root -Force
Remove-Item $zip -Force
}
if (-not (Test-Path (Join-Path $bin 'flutter.bat'))) {
Write-Error "Flutter $ver install failed"; exit 1
}
# Prepend (first line wins in GITHUB_PATH) so 3.44.2 shadows any
# system/cached Flutter on the runner.
Add-Content -Path $env:GITHUB_PATH -Value $bin
Write-Host "Flutter $ver pinned at $bin"
- name: Flutter version
run: flutter --version
# pdfrx REQUIRES Windows Developer Mode (its build creates symbolic links;
# without Dev Mode `flutter build windows` fails). Enable it on the runner
# by setting the AppModelUnlock registry key (idempotent — a no-op if it is
# already on). Requires the runner to be elevated; if it is not, this fails
# loudly here, which is correct since the build cannot proceed regardless.
- name: Enable Windows Developer Mode (pdfrx symlinks)
shell: powershell
run: |
$ErrorActionPreference = 'Stop'
$key = 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\AppModelUnlock'
if (-not (Test-Path $key)) { New-Item -Path $key -Force | Out-Null }
New-ItemProperty -Path $key -Name 'AllowDevelopmentWithoutDevLicense' `
-Value 1 -PropertyType DWORD -Force | Out-Null
$v = (Get-ItemProperty -Path $key -Name 'AllowDevelopmentWithoutDevLicense').AllowDevelopmentWithoutDevLicense
Write-Host "AllowDevelopmentWithoutDevLicense = $v (1 = Developer Mode on)"
- name: Install dependencies
run: flutter pub get
# Quality gates run but never block the build, so a usable .exe is always
# produced even if a different toolchain version reports new lints.
- name: Format check (non-blocking)
continue-on-error: true
run: dart format --output=none --set-exit-if-changed lib test
- name: Analyze (non-blocking)
continue-on-error: true
run: flutter analyze
- name: Test (non-blocking)
continue-on-error: true
run: flutter test --reporter expanded
- name: Enable Windows desktop
run: flutter config --enable-windows-desktop
# pdfrx -> pdfium_dart pulls pdfium.dll from github.com at build time via a
# native-assets build hook (hook/build.dart) that uses package:http, which
# IGNORES HTTP_PROXY. Behind the GFW that direct download fails. The hook
# skips downloading when its output file already exists, so we (1) pre-fetch
# pdfium.dll through a CN-accessible GitHub mirror and pre-place it at the
# hook's deterministic shared-output path, and (2) also rewrite the hook's
# hardcoded GitHub URL to the mirror as a fallback.
- name: Pre-fetch PDFium (pdfrx native asset)
shell: powershell
run: |
$ErrorActionPreference = 'Stop'
$ProgressPreference = 'SilentlyContinue'
$rel = 'chromium/7811'
# Deterministic native-assets shared output path (verified from a real
# build: .dart_tool/hooks_runner/shared/pdfium_dart/build/<rel>/<plat>).
$dst = '.dart_tool\hooks_runner\shared\pdfium_dart\build\chromium_7811\win-x64'
$dll = Join-Path $dst 'pdfium.dll'
if (-not (Test-Path $dll)) {
New-Item -ItemType Directory -Force -Path $dst | Out-Null
$tgz = Join-Path $env:TEMP 'pdfium-win-x64.tgz'
$gh = "github.com/bblanchon/pdfium-binaries/releases/download/$rel/pdfium-win-x64.tgz"
$urls = @("https://gh-proxy.com/https://$gh", "https://ghfast.top/https://$gh", "https://$gh")
$curl = "$env:SystemRoot\System32\curl.exe"
$ok = $false
foreach ($u in $urls) {
Write-Host "Fetching PDFium: $u"
& $curl -L --fail --retry 2 --retry-delay 5 -o $tgz $u
if ($LASTEXITCODE -eq 0 -and (Test-Path $tgz)) { $ok = $true; break }
Write-Host " failed (exit $LASTEXITCODE)"
}
if (-not $ok) { Write-Error "Failed to fetch PDFium from all mirrors"; exit 1 }
$ex = Join-Path $env:TEMP 'pdfium_extract'
if (Test-Path $ex) { Remove-Item -Recurse -Force $ex }
New-Item -ItemType Directory -Force -Path $ex | Out-Null
& tar -xzf $tgz -C $ex
if ($LASTEXITCODE -ne 0) { Write-Error "tar extract failed"; exit 1 }
Copy-Item (Join-Path $ex 'bin\pdfium.dll') $dll -Force
Remove-Item $tgz -Force
if (-not (Test-Path $dll)) { Write-Error "pdfium.dll not placed"; exit 1 }
Write-Host "PDFium pre-placed at $dll"
} else {
Write-Host "pdfium.dll already present at $dll"
}
# Fallback: rewrite the hook's hardcoded GitHub URL to the mirror, in
# case the pre-placed path is not consulted for some build config.
$roots = @($env:PUB_CACHE, "$env:LOCALAPPDATA\Pub\Cache", "$env:APPDATA\Pub\Cache") |
Where-Object { $_ -and (Test-Path $_) }
foreach ($r in $roots) {
$hook = Get-ChildItem -Path $r -Recurse -Filter build.dart -ErrorAction SilentlyContinue |
Where-Object { $_.FullName -match 'pdfium_dart-[\d.]+[\\/]hook[\\/]build\.dart' } |
Select-Object -First 1
if ($hook) {
$orig = 'https://github.com/bblanchon/pdfium-binaries/releases/download/'
$mirror = 'https://gh-proxy.com/https://github.com/bblanchon/pdfium-binaries/releases/download/'
$c = Get-Content -Raw -LiteralPath $hook.FullName
if ($c -notmatch [regex]::Escape($mirror)) {
Set-Content -LiteralPath $hook.FullName -Value ($c.Replace($orig, $mirror)) -NoNewline
Write-Host "Patched hook URL to mirror: $($hook.FullName)"
}
break
}
}
# The flutter_onnxruntime plugin downloads the ONNX Runtime native lib
# from github.com during the build, which is blocked here. Pre-place the
# extracted SDK where the plugin expects it (via a China-accessible GitHub
# proxy) so it skips the download and still bundles onnxruntime.dll.
- name: Pre-fetch ONNX Runtime
shell: powershell
run: |
$ErrorActionPreference = 'Stop'
$ProgressPreference = 'SilentlyContinue'
$ver = 'onnxruntime-win-x64-1.22.0'
$dst = 'build\windows\x64\plugins\flutter_onnxruntime\onnxruntime'
$marker = Join-Path $dst "$ver\include\onnxruntime_cxx_api.h"
if (Test-Path $marker) { Write-Host "ONNX Runtime already present"; exit 0 }
New-Item -ItemType Directory -Force -Path $dst | Out-Null
$zip = Join-Path $env:TEMP 'ort.zip'
$gh = "github.com/microsoft/onnxruntime/releases/download/v1.22.0/$ver.zip"
$urls = @("https://gh-proxy.com/https://$gh", "https://ghfast.top/https://$gh", "https://$gh")
$curl = "$env:SystemRoot\System32\curl.exe"
$ok = $false
foreach ($u in $urls) {
Write-Host "Fetching ONNX Runtime: $u"
& $curl -L --fail --retry 2 --retry-delay 5 -o $zip $u
if ($LASTEXITCODE -eq 0 -and (Test-Path $zip)) { $ok = $true; break }
Write-Host " failed (exit $LASTEXITCODE)"
}
if (-not $ok) { Write-Error "Failed to fetch ONNX Runtime from all mirrors"; exit 1 }
Expand-Archive -Path $zip -DestinationPath $dst -Force
Remove-Item $zip -Force
if (-not (Test-Path $marker)) { Write-Error "ONNX Runtime not in expected layout"; exit 1 }
Write-Host "ONNX Runtime ready at $dst\$ver"
# Proxy vars are kept as a fallback in case the pre-fetch above is bypassed
# (CMake's file(DOWNLOAD) honours them).
- name: Build Windows release
env:
HTTP_PROXY: http://192.168.31.189:7890
HTTPS_PROXY: http://192.168.31.189:7890
http_proxy: http://192.168.31.189:7890
https_proxy: http://192.168.31.189:7890
run: flutter build windows --release
- name: Show build output
shell: powershell
run: Get-ChildItem build\windows\x64\runner\Release
- name: Package artifact
shell: powershell
run: Compress-Archive -Path "build/windows/x64/runner/Release/*" -DestinationPath "badnote-windows-x64.zip" -Force
- name: Upload artifact (best-effort)
continue-on-error: true
uses: https://gitea.com/actions/upload-artifact@v3
with:
name: badnote-windows-x64
path: badnote-windows-x64.zip
if-no-files-found: warn