Files
web2app/.github/workflows/build-app.yml
shumengya 255429d529 fix: pass app_version to CI and ship Windows NSIS installer only
Add app_version to workflow_dispatch inputs and worker dispatch payload. Collect only setup.exe from bundle/nsis, prefer installer URLs in release lookup, and use git-tag-safe job IDs.
2026-07-03 16:55:12 +08:00

242 lines
7.5 KiB
YAML

name: Build App
on:
workflow_dispatch:
inputs:
job_id:
description: Build job ID
required: true
type: string
app_name:
description: Application display name (Chinese)
required: true
type: string
app_name_en:
description: Application English name for packaging
required: true
type: string
app_identifier:
description: Application bundle identifier
required: true
type: string
app_version:
description: Application version string
required: true
type: string
permissions:
contents: write
env:
JOB_ID: ${{ inputs.job_id }}
APP_NAME: ${{ inputs.app_name }}
APP_NAME_EN: ${{ inputs.app_name_en }}
APP_IDENTIFIER: ${{ inputs.app_identifier }}
APP_VERSION: ${{ inputs.app_version }}
NDK_VERSION: "27.2.12479018"
# Faster release builds in CI; local release profile keeps full LTO.
CI: true
CARGO_PROFILE_RELEASE_LTO: false
CARGO_PROFILE_RELEASE_CODEGEN_UNITS: 16
jobs:
build-windows:
runs-on: windows-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: lts/*
cache: npm
- name: Install dependencies
run: npm ci --workspace=template --include-workspace-root
- name: Prepare template
run: node .github/scripts/prepare-template.mjs
- uses: dtolnay/rust-toolchain@stable
- uses: swatinem/rust-cache@v2
with:
workspaces: template/src-tauri -> target
shared-key: tauri-release
- name: Build Windows app
working-directory: template
run: npm run tauri build -- --bundles nsis
- name: Collect Windows artifacts
shell: pwsh
run: |
New-Item -ItemType Directory -Force -Path artifacts/windows | Out-Null
$nsisDir = "template/src-tauri/target/release/bundle/nsis"
if (-not (Test-Path $nsisDir)) {
Write-Error "NSIS bundle directory not found: $nsisDir"
exit 1
}
$installers = Get-ChildItem -Path $nsisDir -Filter "*-setup.exe"
if (-not $installers) {
Write-Error "No NSIS installer (*-setup.exe) found in $nsisDir"
exit 1
}
$installers | Copy-Item -Destination artifacts/windows -Force
Get-ChildItem artifacts/windows
- uses: actions/upload-artifact@v4
with:
name: windows-build
path: artifacts/windows/*
if-no-files-found: error
build-android:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: lts/*
cache: npm
- name: Install dependencies
run: npm ci --workspace=template --include-workspace-root
- name: Prepare template
run: node .github/scripts/prepare-template.mjs
- uses: actions/setup-java@v4
with:
distribution: temurin
java-version: 17
- uses: android-actions/setup-android@v3
- name: Cache Android NDK
uses: actions/cache@v4
id: android-ndk-cache
with:
path: ${{ env.ANDROID_HOME }}/ndk/${{ env.NDK_VERSION }}
key: android-ndk-${{ env.NDK_VERSION }}-${{ runner.os }}
- name: Cache Gradle
uses: actions/cache@v4
with:
path: |
~/.gradle/caches
~/.gradle/wrapper
key: gradle-${{ runner.os }}-${{ hashFiles('template/src-tauri/Cargo.lock', 'template/package.json') }}
restore-keys: |
gradle-${{ runner.os }}-
- name: Install Android SDK components
run: |
sdkmanager "platforms;android-34" "build-tools;34.0.0"
if [ "${{ steps.android-ndk-cache.outputs.cache-hit }}" != "true" ]; then
sdkmanager "ndk;${{ env.NDK_VERSION }}"
fi
- uses: dtolnay/rust-toolchain@stable
with:
targets: aarch64-linux-android
- uses: swatinem/rust-cache@v2
with:
workspaces: template/src-tauri -> target
shared-key: tauri-release
- name: Initialize Android project
working-directory: template
run: npm run tauri android init
env:
NDK_HOME: ${{ env.ANDROID_HOME }}/ndk/${{ env.NDK_VERSION }}
- name: Patch Android app (system bars + network)
run: node .github/scripts/patch-android-system-bars.mjs
- name: Regenerate app icons for Android
run: node .github/scripts/generate-app-icons.mjs
env:
JOB_ID: ${{ inputs.job_id }}
- name: Build Android APK
working-directory: template
run: npm run tauri android build -- --apk --target aarch64 --ci
env:
NDK_HOME: ${{ env.ANDROID_HOME }}/ndk/${{ env.NDK_VERSION }}
- name: Sign Android APK
run: bash .github/scripts/sign-android-apk.sh
env:
ANDROID_KEYSTORE_BASE64: ${{ secrets.ANDROID_KEYSTORE_BASE64 }}
ANDROID_KEYSTORE_PASSWORD: ${{ secrets.ANDROID_KEYSTORE_PASSWORD }}
ANDROID_KEY_PASSWORD: ${{ secrets.ANDROID_KEY_PASSWORD }}
ANDROID_KEY_ALIAS: ${{ secrets.ANDROID_KEY_ALIAS }}
- uses: actions/upload-artifact@v4
with:
name: android-build
path: artifacts/android/*
if-no-files-found: error
finalize:
needs: [build-windows, build-android]
runs-on: ubuntu-latest
if: always() && needs.build-windows.result == 'success' && needs.build-android.result == 'success'
steps:
- uses: actions/checkout@v4
- uses: actions/download-artifact@v4
with:
name: windows-build
path: release-assets/windows
- uses: actions/download-artifact@v4
with:
name: android-build
path: release-assets/android
- name: Rename release assets
run: |
mkdir -p release-assets/final
shopt -s nullglob
for file in release-assets/windows/*; do
base="$(basename "$file")"
cp "$file" "release-assets/final/web2app-${{ inputs.job_id }}-windows-${base}"
done
for file in release-assets/android/*; do
base="$(basename "$file")"
cp "$file" "release-assets/final/web2app-${{ inputs.job_id }}-android-${base}"
done
ls -la release-assets/final
- name: Create GitHub Release
uses: softprops/action-gh-release@v2
with:
tag_name: build-${{ inputs.job_id }}
name: Web2App ${{ inputs.app_name }} (${{ inputs.job_id }})
body: |
Automated build for **${{ inputs.app_name }}** (English: `${{ inputs.app_name_en }}`, version: `${{ inputs.app_version }}`, ID: `${{ inputs.app_identifier }}`).
- Windows NSIS installer (*-setup.exe)
- Android APK (arm64-v8a, signed for sideload install)
draft: false
prerelease: true
files: release-assets/final/*
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Remove uploaded site zip
run: |
path="builds/${{ inputs.job_id }}/site.zip"
sha=$(gh api repos/${{ github.repository }}/contents/$path --jq .sha 2>/dev/null || true)
if [ -n "$sha" ]; then
gh api repos/${{ github.repository }}/contents/$path \
-X DELETE \
-f message="chore: cleanup build ${{ inputs.job_id }}" \
-f sha="$sha"
fi
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}