From a3f735bb120eb52250dff4a597a82856ac0cfc83 Mon Sep 17 00:00:00 2001 From: Kayshen-X Date: Tue, 5 May 2026 22:15:00 +0800 Subject: [PATCH] ci: multi-platform Rust build matrix + release pipeline MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - rust-multiplatform.yml: PR/push 验证矩阵 - desktop (macOS aarch64+x86_64, Linux x86_64+aarch64, Windows x86_64): cargo build/test --release - linux-aarch64 通过 cross 交叉编译 - wasm-web (wasm32-unknown-unknown): openpencil-shell-web --release + 上传 .wasm - mobile-check (iOS aarch64+sim on macOS, Android aarch64+x86_64 on Linux): cargo check 仅 - 所有 desktop binary + wasm 上传 14 day artifact - rust-release.yml: tag push (v*) 触发 - desktop matrix build → tar.gz / zip 包 - wasm32 release bundle - softprops/action-gh-release@v2 创建 draft GitHub Release Linux job 设 STEP1A_REQUIRE_GPU=1 强制 GPU smoke 实测(per Phase A Gate Round 3 BLOCK 1 fix)。 Mobile target 仅 cargo check —— Step 1a kill-spike 不打 link 实物(spec §11 推 1f)。 --- .github/workflows/rust-multiplatform.yml | 164 +++++++++++++++++++++++ .github/workflows/rust-release.yml | 142 ++++++++++++++++++++ 2 files changed, 306 insertions(+) create mode 100644 .github/workflows/rust-multiplatform.yml create mode 100644 .github/workflows/rust-release.yml diff --git a/.github/workflows/rust-multiplatform.yml b/.github/workflows/rust-multiplatform.yml new file mode 100644 index 000000000..d586e8a94 --- /dev/null +++ b/.github/workflows/rust-multiplatform.yml @@ -0,0 +1,164 @@ +name: Rust multi-platform build + +# Builds the OpenPencil Rust workspace across all supported targets. +# Runs on every push/PR to verify the matrix stays green; release artifacts +# are produced by `rust-release.yml` on tag pushes. + +on: + push: + branches: [main, v0.8.0] + paths: + - 'Cargo.toml' + - 'Cargo.lock' + - 'crates/**' + - 'vendor/jian/**' + - 'rust-toolchain.toml' + - 'deny.toml' + - '.github/workflows/rust-multiplatform.yml' + pull_request: + paths: + - 'Cargo.toml' + - 'Cargo.lock' + - 'crates/**' + - 'vendor/jian/**' + - '.github/workflows/rust-multiplatform.yml' + workflow_dispatch: + +jobs: + desktop: + name: ${{ matrix.label }} + runs-on: ${{ matrix.runner }} + strategy: + fail-fast: false + matrix: + include: + - label: macos-aarch64 + runner: macos-latest + target: aarch64-apple-darwin + cross: false + - label: macos-x86_64 + runner: macos-13 + target: x86_64-apple-darwin + cross: false + - label: linux-x86_64 + runner: ubuntu-latest + target: x86_64-unknown-linux-gnu + cross: false + - label: linux-aarch64 + runner: ubuntu-latest + target: aarch64-unknown-linux-gnu + cross: true + - label: windows-x86_64 + runner: windows-latest + target: x86_64-pc-windows-msvc + cross: false + steps: + - uses: actions/checkout@v4 + with: + submodules: recursive + - uses: dtolnay/rust-toolchain@stable + with: + toolchain: '1.85' + targets: ${{ matrix.target }} + components: rustfmt, clippy + - uses: Swatinem/rust-cache@v2 + with: + key: ${{ matrix.target }} + - name: Install Linux GL/EGL prereqs + if: runner.os == 'Linux' && matrix.cross == false + run: | + sudo apt-get update + sudo apt-get install -y \ + libxkbcommon-dev libxkbcommon-x11-dev \ + libwayland-dev libxcb-render0-dev libxcb-shape0-dev libxcb-xfixes0-dev \ + libegl1-mesa-dev libgles2-mesa-dev libgbm-dev mesa-utils \ + libfreetype-dev libfontconfig1-dev + - name: Install cross + if: matrix.cross == true + run: cargo install cross --locked --version 0.2.5 + - name: Build (host) + if: matrix.cross == false + run: cargo build --workspace --target ${{ matrix.target }} --release + - name: Build (cross) + if: matrix.cross == true + run: cross build --workspace --target ${{ matrix.target }} --release + - name: Test (host, Linux strict-GPU) + if: matrix.cross == false && runner.os == 'Linux' + env: + STEP1A_REQUIRE_GPU: '1' + run: cargo test --workspace --target ${{ matrix.target }} + - name: Test (host, macOS / Windows) + if: matrix.cross == false && runner.os != 'Linux' + run: cargo test --workspace --target ${{ matrix.target }} + - name: Upload openpencil-app binary + if: matrix.cross == false + uses: actions/upload-artifact@v4 + with: + name: openpencil-app-${{ matrix.label }} + path: | + target/${{ matrix.target }}/release/openpencil-app + target/${{ matrix.target }}/release/openpencil-app.exe + if-no-files-found: ignore + retention-days: 14 + + wasm-web: + name: wasm32-unknown-unknown / openpencil-shell-web + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + submodules: recursive + - uses: dtolnay/rust-toolchain@stable + with: + toolchain: '1.85' + targets: wasm32-unknown-unknown + - uses: Swatinem/rust-cache@v2 + with: + key: wasm32 + - run: cargo build -p openpencil-shell-web --target wasm32-unknown-unknown --release + - name: Upload wasm bundle + uses: actions/upload-artifact@v4 + with: + name: openpencil-shell-web-wasm + path: target/wasm32-unknown-unknown/release/openpencil_shell_web.wasm + if-no-files-found: warn + retention-days: 14 + + mobile-check: + name: ${{ matrix.label }} (cargo check only) + runs-on: ${{ matrix.runner }} + strategy: + fail-fast: false + matrix: + include: + # iOS targets need Xcode SDK — macOS runner only. + - label: ios-aarch64 + runner: macos-latest + target: aarch64-apple-ios + - label: ios-aarch64-sim + runner: macos-latest + target: aarch64-apple-ios-sim + # Android targets via NDK — Linux runner. + - label: android-aarch64 + runner: ubuntu-latest + target: aarch64-linux-android + - label: android-x86_64 + runner: ubuntu-latest + target: x86_64-linux-android + steps: + - uses: actions/checkout@v4 + with: + submodules: recursive + - uses: dtolnay/rust-toolchain@stable + with: + toolchain: '1.85' + targets: ${{ matrix.target }} + - uses: Swatinem/rust-cache@v2 + with: + key: mobile-${{ matrix.target }} + # Real linking needs platform SDK / NDK; Step 1a only verifies the + # workspace type-checks against mobile targets (per spec §11 mobile + # readiness invariants). The shell-native `unimplemented!` stubs for + # iOS/Android providers are exercised by this check. + - run: cargo check -p openpencil-shell-core --target ${{ matrix.target }} + - run: cargo check -p openpencil-shell-native --target ${{ matrix.target }} diff --git a/.github/workflows/rust-release.yml b/.github/workflows/rust-release.yml new file mode 100644 index 000000000..d6214a74c --- /dev/null +++ b/.github/workflows/rust-release.yml @@ -0,0 +1,142 @@ +name: Rust release artifacts + +# Triggered on tag push (v*) — builds release binaries across desktop targets, +# the WASM bundle, and uploads them to a GitHub Release draft. Step 1a kill-spike +# only ships `openpencil-app` (a placeholder binary entry); real desktop apps +# (DMG / AppImage / EXE installer) come in Step 1f and replace this scaffolding. + +on: + push: + tags: ['v*'] + workflow_dispatch: + +jobs: + build: + name: ${{ matrix.label }} + runs-on: ${{ matrix.runner }} + strategy: + fail-fast: false + matrix: + include: + - label: macos-aarch64 + runner: macos-latest + target: aarch64-apple-darwin + archive: tar.gz + - label: macos-x86_64 + runner: macos-13 + target: x86_64-apple-darwin + archive: tar.gz + - label: linux-x86_64 + runner: ubuntu-latest + target: x86_64-unknown-linux-gnu + archive: tar.gz + - label: linux-aarch64 + runner: ubuntu-latest + target: aarch64-unknown-linux-gnu + archive: tar.gz + cross: true + - label: windows-x86_64 + runner: windows-latest + target: x86_64-pc-windows-msvc + archive: zip + steps: + - uses: actions/checkout@v4 + with: + submodules: recursive + - uses: dtolnay/rust-toolchain@stable + with: + toolchain: '1.85' + targets: ${{ matrix.target }} + - uses: Swatinem/rust-cache@v2 + with: + key: release-${{ matrix.target }} + - name: Install Linux GL/EGL prereqs + if: runner.os == 'Linux' && matrix.cross != true + run: | + sudo apt-get update + sudo apt-get install -y \ + libxkbcommon-dev libxkbcommon-x11-dev \ + libwayland-dev libxcb-render0-dev libxcb-shape0-dev libxcb-xfixes0-dev \ + libegl1-mesa-dev libgles2-mesa-dev libgbm-dev \ + libfreetype-dev libfontconfig1-dev + - name: Install cross + if: matrix.cross == true + run: cargo install cross --locked --version 0.2.5 + - name: Build (host) + if: matrix.cross != true + run: cargo build -p openpencil-app --target ${{ matrix.target }} --release + - name: Build (cross) + if: matrix.cross == true + run: cross build -p openpencil-app --target ${{ matrix.target }} --release + - name: Package archive (unix) + if: matrix.archive == 'tar.gz' + shell: bash + run: | + cd target/${{ matrix.target }}/release + tar czf ../../../openpencil-app-${{ matrix.label }}.tar.gz openpencil-app 2>/dev/null || \ + tar czf ../../../openpencil-app-${{ matrix.label }}.tar.gz openpencil-app.placeholder + - name: Package archive (windows) + if: matrix.archive == 'zip' + shell: pwsh + run: | + Compress-Archive ` + -Path target\${{ matrix.target }}\release\openpencil-app.exe ` + -DestinationPath openpencil-app-${{ matrix.label }}.zip ` + -ErrorAction SilentlyContinue + - name: Upload artifact + uses: actions/upload-artifact@v4 + with: + name: openpencil-app-${{ matrix.label }} + path: | + openpencil-app-${{ matrix.label }}.tar.gz + openpencil-app-${{ matrix.label }}.zip + if-no-files-found: ignore + + wasm: + name: wasm32 web bundle + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + submodules: recursive + - uses: dtolnay/rust-toolchain@stable + with: + toolchain: '1.85' + targets: wasm32-unknown-unknown + - uses: Swatinem/rust-cache@v2 + with: + key: release-wasm32 + - run: cargo build -p openpencil-shell-web --target wasm32-unknown-unknown --release + - name: Package wasm artifact + run: | + cd target/wasm32-unknown-unknown/release + tar czf ../../../openpencil-shell-web-wasm.tar.gz \ + openpencil_shell_web.wasm 2>/dev/null || true + - name: Upload artifact + uses: actions/upload-artifact@v4 + with: + name: openpencil-shell-web-wasm + path: openpencil-shell-web-wasm.tar.gz + if-no-files-found: warn + + release-draft: + name: Create / update GitHub Release draft + needs: [build, wasm] + runs-on: ubuntu-latest + if: startsWith(github.ref, 'refs/tags/v') + steps: + - uses: actions/checkout@v4 + - uses: actions/download-artifact@v4 + with: + path: dist + - name: Flatten artifacts + run: | + mkdir -p release-files + find dist -type f \( -name "*.tar.gz" -o -name "*.zip" \) -exec cp {} release-files/ \; + ls -la release-files + - name: Create / update GitHub Release + uses: softprops/action-gh-release@v2 + with: + draft: true + files: release-files/* + generate_release_notes: true