CI: make builds work on China-based self-hosted Gitea runner
The self-hosted Windows runner can't reach github.com (GFW), so the previous workflow failed cloning actions/checkout and would also fail downloading the Flutter SDK and the sqlite3 native binary. - Vendor the official, SHA-256-verified sqlite3 binaries under vendor/sqlite3/ and select them via pubspec hooks.user_defines (source: test-sqlite3). Builds and tests now run fully offline — no GitHub download, no proxy, no LD_LIBRARY_PATH hack (removed .local-sqlite/). - Consolidate CI into one Windows workflow: fetch actions from the gitea.com mirror, use the runner's pre-installed Flutter (no SDK download), and use the flutter-io.cn pub/Flutter mirrors. Server tests use the Tsinghua PyPI mirror. - Document the offline build + China mirrors in README. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -3,28 +3,35 @@ name: CI
|
|||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches: [main]
|
branches: [main]
|
||||||
|
tags: ["v*"]
|
||||||
pull_request:
|
pull_request:
|
||||||
branches: [main]
|
branches: [main]
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
# Allow builds to find SQLite / Flutter artifacts behind a corporate proxy.
|
# This pipeline targets a self-hosted Windows runner inside mainland China.
|
||||||
# Configure repo/org secrets HTTP_PROXY / HTTPS_PROXY in Gitea if needed.
|
# Notes on the design (so it works behind the GFW):
|
||||||
|
# * Actions are fetched from the gitea.com mirror, NOT github.com, which is
|
||||||
|
# unreachable here. (Alternatively set DEFAULT_ACTIONS_URL=https://gitea.com
|
||||||
|
# in the runner's config and drop the full URL prefix.)
|
||||||
|
# * Flutter is expected to be pre-installed on the runner (the same machine
|
||||||
|
# used for local development) — we do NOT download the SDK from Google.
|
||||||
|
# * pub / Flutter artifacts use the flutter-io.cn mirrors.
|
||||||
|
# * The sqlite3 native binary is vendored in the repo (vendor/sqlite3/), so no
|
||||||
|
# GitHub-releases download happens during the build.
|
||||||
env:
|
env:
|
||||||
FLUTTER_VERSION: "3.41.4"
|
PUB_HOSTED_URL: https://pub.flutter-io.cn
|
||||||
|
FLUTTER_STORAGE_BASE_URL: https://storage.flutter-io.cn
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
analyze:
|
flutter:
|
||||||
name: Analyze (Flutter)
|
name: Flutter (analyze, test, Windows build)
|
||||||
runs-on: ubuntu-latest
|
runs-on: windows-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: https://gitea.com/actions/checkout@v4
|
||||||
|
|
||||||
- name: Set up Flutter
|
- name: Flutter version (must be pre-installed on the runner)
|
||||||
uses: subosito/flutter-action@v2
|
run: flutter --version
|
||||||
with:
|
|
||||||
flutter-version: ${{ env.FLUTTER_VERSION }}
|
|
||||||
channel: stable
|
|
||||||
cache: true
|
|
||||||
|
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: flutter pub get
|
run: flutter pub get
|
||||||
@@ -35,67 +42,42 @@ jobs:
|
|||||||
- name: Static analysis
|
- name: Static analysis
|
||||||
run: flutter analyze
|
run: flutter analyze
|
||||||
|
|
||||||
test:
|
|
||||||
name: Test (Flutter, Linux)
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
needs: analyze
|
|
||||||
steps:
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
|
|
||||||
- name: Set up Flutter
|
|
||||||
uses: subosito/flutter-action@v2
|
|
||||||
with:
|
|
||||||
flutter-version: ${{ env.FLUTTER_VERSION }}
|
|
||||||
channel: stable
|
|
||||||
cache: true
|
|
||||||
|
|
||||||
# The sqlite3 Dart package downloads a precompiled binary from GitHub
|
|
||||||
# releases when building native assets. On Linux CI we instead link the
|
|
||||||
# system libsqlite3 to avoid the download (faster + works offline).
|
|
||||||
# This override is applied only in CI; the committed pubspec.yaml stays
|
|
||||||
# clean so the Windows build downloads the bundled sqlite3.dll normally.
|
|
||||||
- name: Install system SQLite
|
|
||||||
run: sudo apt-get update && sudo apt-get install -y libsqlite3-dev
|
|
||||||
|
|
||||||
- name: Use system SQLite for native assets (CI only)
|
|
||||||
run: |
|
|
||||||
cat >> pubspec.yaml <<'EOF'
|
|
||||||
|
|
||||||
hooks:
|
|
||||||
user_defines:
|
|
||||||
sqlite3:
|
|
||||||
source: system
|
|
||||||
EOF
|
|
||||||
|
|
||||||
- name: Install dependencies
|
|
||||||
run: flutter pub get
|
|
||||||
|
|
||||||
- name: Run tests
|
- name: Run tests
|
||||||
run: flutter test --reporter expanded
|
run: flutter test --reporter expanded
|
||||||
|
|
||||||
|
- name: Enable Windows desktop
|
||||||
|
run: flutter config --enable-windows-desktop
|
||||||
|
|
||||||
|
- name: Build Windows release
|
||||||
|
run: flutter build windows --release
|
||||||
|
|
||||||
|
- name: Package artifact
|
||||||
|
run: Compress-Archive -Path "build/windows/x64/runner/Release/*" -DestinationPath "badnote-windows-x64.zip" -Force
|
||||||
|
|
||||||
|
- name: Upload artifact
|
||||||
|
uses: https://gitea.com/actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: badnote-windows-x64
|
||||||
|
path: badnote-windows-x64.zip
|
||||||
|
if-no-files-found: error
|
||||||
|
|
||||||
server:
|
server:
|
||||||
name: Test (Server, optional)
|
name: Server tests (optional)
|
||||||
runs-on: ubuntu-latest
|
runs-on: windows-latest
|
||||||
# The server is an optional/experimental backend. Keep it from blocking
|
# The Python backend is optional/experimental; never block the pipeline.
|
||||||
# the pipeline, but still surface failures.
|
|
||||||
continue-on-error: true
|
continue-on-error: true
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: https://gitea.com/actions/checkout@v4
|
||||||
|
|
||||||
- name: Set up Python
|
- name: Install dependencies (Tsinghua PyPI mirror)
|
||||||
uses: actions/setup-python@v5
|
|
||||||
with:
|
|
||||||
python-version: "3.12"
|
|
||||||
cache: pip
|
|
||||||
|
|
||||||
- name: Install dependencies
|
|
||||||
working-directory: server
|
working-directory: server
|
||||||
run: |
|
run: |
|
||||||
python -m pip install --upgrade pip
|
python -m pip install --upgrade pip -i https://pypi.tuna.tsinghua.edu.cn/simple
|
||||||
pip install -r requirements.txt
|
pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple
|
||||||
|
|
||||||
- name: Run tests
|
- name: Run tests
|
||||||
working-directory: server
|
working-directory: server
|
||||||
|
env:
|
||||||
|
BADNOTE_JWT_SECRET: ci-test-secret
|
||||||
run: pytest -q
|
run: pytest -q
|
||||||
|
|||||||
@@ -1,57 +0,0 @@
|
|||||||
name: Windows Build
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches: [main]
|
|
||||||
tags: ["v*"]
|
|
||||||
pull_request:
|
|
||||||
branches: [main]
|
|
||||||
workflow_dispatch:
|
|
||||||
|
|
||||||
env:
|
|
||||||
FLUTTER_VERSION: "3.41.4"
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build-windows:
|
|
||||||
name: Build Windows (x64)
|
|
||||||
runs-on: windows-latest
|
|
||||||
steps:
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
|
|
||||||
- name: Set up Flutter
|
|
||||||
uses: subosito/flutter-action@v2
|
|
||||||
with:
|
|
||||||
flutter-version: ${{ env.FLUTTER_VERSION }}
|
|
||||||
channel: stable
|
|
||||||
cache: true
|
|
||||||
|
|
||||||
- name: Enable Windows desktop
|
|
||||||
run: flutter config --enable-windows-desktop
|
|
||||||
|
|
||||||
- name: Install dependencies
|
|
||||||
run: flutter pub get
|
|
||||||
|
|
||||||
- name: Analyze
|
|
||||||
run: flutter analyze
|
|
||||||
|
|
||||||
# The sqlite3 native asset downloads a precompiled DLL from GitHub
|
|
||||||
# releases. If the runner is behind a firewall, set HTTP_PROXY /
|
|
||||||
# HTTPS_PROXY as repository secrets and they will be honoured here.
|
|
||||||
- name: Build Windows release
|
|
||||||
env:
|
|
||||||
HTTP_PROXY: ${{ secrets.HTTP_PROXY }}
|
|
||||||
HTTPS_PROXY: ${{ secrets.HTTPS_PROXY }}
|
|
||||||
run: flutter build windows --release
|
|
||||||
|
|
||||||
- name: Package artifact
|
|
||||||
run: |
|
|
||||||
$dir = "build\windows\x64\runner\Release"
|
|
||||||
Compress-Archive -Path "$dir\*" -DestinationPath "badnote-windows-x64.zip" -Force
|
|
||||||
|
|
||||||
- name: Upload artifact
|
|
||||||
uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: badnote-windows-x64
|
|
||||||
path: badnote-windows-x64.zip
|
|
||||||
if-no-files-found: error
|
|
||||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -47,9 +47,6 @@ app.*.map.json
|
|||||||
# OMC orchestration state
|
# OMC orchestration state
|
||||||
.omc/
|
.omc/
|
||||||
|
|
||||||
# Local-only sqlite3 override for offline/firewalled test runs
|
|
||||||
.local-sqlite/
|
|
||||||
|
|
||||||
# Python server artifacts
|
# Python server artifacts
|
||||||
server/.venv/
|
server/.venv/
|
||||||
server/.omc/
|
server/.omc/
|
||||||
|
|||||||
23
README.md
23
README.md
@@ -26,14 +26,31 @@ flutter build windows --release
|
|||||||
|
|
||||||
Output: `build\windows\x64\runner\Release\badnote.exe`
|
Output: `build\windows\x64\runner\Release\badnote.exe`
|
||||||
|
|
||||||
If native asset downloads fail (e.g. sqlite3), set a proxy before building:
|
The `sqlite3` native binary is **vendored** under `vendor/sqlite3/` (configured via
|
||||||
|
`hooks.user_defines` in `pubspec.yaml`), so the build does not download anything
|
||||||
|
from GitHub — it works fully offline / behind a firewall. To add another
|
||||||
|
platform or architecture, drop its official release binary from
|
||||||
|
[sqlite3.dart releases](https://github.com/simolus3/sqlite3.dart/releases) into
|
||||||
|
`vendor/sqlite3/` (the build validates each file's SHA-256).
|
||||||
|
|
||||||
|
In mainland China, point pub/Flutter at the local mirrors:
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
$env:HTTP_PROXY="http://127.0.0.1:7890"
|
$env:PUB_HOSTED_URL="https://pub.flutter-io.cn"
|
||||||
$env:HTTPS_PROXY="http://127.0.0.1:7890"
|
$env:FLUTTER_STORAGE_BASE_URL="https://storage.flutter-io.cn"
|
||||||
|
flutter pub get
|
||||||
flutter build windows --release
|
flutter build windows --release
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Continuous integration
|
||||||
|
|
||||||
|
`.gitea/workflows/ci.yml` runs format + analyze + test + Windows release build on
|
||||||
|
a self-hosted **Windows** runner. It is written for runners behind the GFW:
|
||||||
|
actions come from the `gitea.com` mirror, Flutter is expected to be
|
||||||
|
pre-installed on the runner, and pub uses the `flutter-io.cn` mirror. If
|
||||||
|
`gitea.com` is unreachable too, set `DEFAULT_ACTIONS_URL=https://gitea.com` (or
|
||||||
|
your own mirror) in the runner config and use bare `actions/checkout@v4`.
|
||||||
|
|
||||||
## Architecture
|
## Architecture
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|||||||
12
pubspec.yaml
12
pubspec.yaml
@@ -61,3 +61,15 @@ dev_dependencies:
|
|||||||
|
|
||||||
flutter:
|
flutter:
|
||||||
uses-material-design: true
|
uses-material-design: true
|
||||||
|
|
||||||
|
# Use vendored, hash-verified sqlite3 native binaries (committed under
|
||||||
|
# vendor/sqlite3/) instead of downloading them from GitHub releases at build
|
||||||
|
# time. This keeps builds fully local/offline — important behind the GFW where
|
||||||
|
# the GitHub download times out — and deterministic. To support another
|
||||||
|
# platform/arch, drop its official release binary into vendor/sqlite3/ (the
|
||||||
|
# build validates each file's SHA-256 against the sqlite3 package).
|
||||||
|
hooks:
|
||||||
|
user_defines:
|
||||||
|
sqlite3:
|
||||||
|
source: test-sqlite3
|
||||||
|
directory: vendor/sqlite3/
|
||||||
|
|||||||
BIN
vendor/sqlite3/libsqlite3.x64.linux.so
vendored
Normal file
BIN
vendor/sqlite3/libsqlite3.x64.linux.so
vendored
Normal file
Binary file not shown.
BIN
vendor/sqlite3/sqlite3.x64.windows.dll
vendored
Normal file
BIN
vendor/sqlite3/sqlite3.x64.windows.dll
vendored
Normal file
Binary file not shown.
Reference in New Issue
Block a user