tauri-build-windows-official #7
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: tauri-build-windows-official | |
| on: | |
| workflow_dispatch: | |
| inputs: | |
| env_name: | |
| description: "Frontend build mode (development/production/test)" | |
| required: false | |
| default: "production" | |
| jobs: | |
| build: | |
| # Windows 专用构建 Job: | |
| # - 固定运行在 GitHub-hosted Windows Server 2025 Runner 上 | |
| # - 不适用于 macOS / Linux 等其他平台 | |
| # 如需支持多平台,请为不同平台创建独立的 workflow 或 job | |
| runs-on: windows-2025 | |
| permissions: | |
| contents: write | |
| env: | |
| # 前端构建参数 | |
| # build.cjs reads ENV_NAME; default production | |
| ENV_NAME: ${{ inputs.env_name || 'production' }} | |
| # App config values | |
| APP_SERVER_BASE_URL: ${{ secrets.APP_SERVER_BASE_URL }} | |
| APP_SERVER_VERSION: ${{ secrets.APP_SERVER_VERSION }} | |
| APP_SERVER_SECRET_KEY: ${{ secrets.APP_SERVER_SECRET_KEY }} | |
| APP_UPDATER_CHECK_URL: ${{ secrets.APP_UPDATER_CHECK_URL }} | |
| APP_UPDATER_LATEST_JSON_URL: ${{ secrets.APP_UPDATER_LATEST_JSON_URL }} | |
| APP_RUNTIME_LATEST_JSON_URL: ${{ secrets.APP_RUNTIME_LATEST_JSON_URL }} | |
| APP_UPDATER_TEMP_DIR: ${{ secrets.APP_UPDATER_TEMP_DIR }} | |
| APP_WEBVIEW_DOWNLOAD_URL: ${{ secrets.APP_WEBVIEW_DOWNLOAD_URL }} | |
| # Release 相关上下文 | |
| # - tag push 时 github.ref_name 即为 vX.Y.Z | |
| # - workflow_dispatch 时不会创建 release,仅用于手动构建 | |
| RELEASE_TAG: ${{ github.ref_name }} | |
| # R2 相关配置(若未配置对应 Secret,则相关功能会被跳过或报错) | |
| R2_ACCOUNT_ID: ${{ secrets.R2_ACCOUNT_ID }} | |
| R2_ACCESS_KEY_ID: ${{ secrets.R2_ACCESS_KEY_ID }} | |
| R2_SECRET_ACCESS_KEY: ${{ secrets.R2_SECRET_ACCESS_KEY }} | |
| R2_BUCKET: ${{ secrets.R2_BUCKET }} | |
| R2_PUBLIC_BASE_URL: ${{ secrets.R2_PUBLIC_BASE_URL }} | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| fetch-tags: true | |
| - name: Setup pnpm | |
| uses: pnpm/action-setup@v4 | |
| with: | |
| version: 9 | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: 20 | |
| cache: pnpm | |
| - name: Setup Rust toolchain | |
| uses: dtolnay/rust-toolchain@stable | |
| - name: Ensure AWS CLI | |
| shell: powershell | |
| run: | | |
| $ErrorActionPreference = "Stop" | |
| if (Get-Command aws -ErrorAction SilentlyContinue) { | |
| aws --version | |
| exit 0 | |
| } | |
| $msiPath = Join-Path $env:RUNNER_TEMP "AWSCLIV2.msi" | |
| Invoke-WebRequest "https://awscli.amazonaws.com/AWSCLIV2.msi" -OutFile $msiPath | |
| Start-Process msiexec.exe -Wait -ArgumentList "/i `"$msiPath`" /qn" | |
| @( | |
| "C:\Program Files\Amazon\AWSCLIV2", | |
| "C:\Program Files\Amazon\AWSCLIV2\bin" | |
| ) | ForEach-Object { | |
| if (Test-Path $_) { | |
| Add-Content -Path $env:GITHUB_PATH -Value $_ | |
| } | |
| } | |
| $awsExe = Get-Command aws -ErrorAction SilentlyContinue | |
| if (-not $awsExe) { | |
| $awsInstalled = Get-ChildItem "C:\Program Files\Amazon" -Filter aws.exe -Recurse -ErrorAction SilentlyContinue | | |
| Select-Object -First 1 | |
| if (-not $awsInstalled) { | |
| Write-Error "AWS CLI installation completed, but aws.exe was not found." | |
| } | |
| & $awsInstalled.FullName --version | |
| exit 0 | |
| } | |
| aws --version | |
| - name: Install dependencies | |
| run: pnpm install --frozen-lockfile | |
| - name: Prepare app config | |
| shell: powershell | |
| run: | | |
| Copy-Item "src-tauri/config.example.toml" "src-tauri/config.production.toml" -Force | |
| $configPath = "src-tauri/config.production.toml" | |
| $content = Get-Content $configPath -Raw | |
| function Set-ConfigValue { | |
| param( | |
| [string]$Pattern, | |
| [string]$Value | |
| ) | |
| if ([string]::IsNullOrWhiteSpace($Value)) { | |
| return | |
| } | |
| $escapedValue = $Value.Replace('\', '\\').Replace('"', '\"') | |
| $script:content = [regex]::Replace( | |
| $script:content, | |
| $Pattern, | |
| ('$1"{0}"' -f $escapedValue), | |
| [System.Text.RegularExpressions.RegexOptions]::Multiline | |
| ) | |
| } | |
| Set-ConfigValue '^(base_url\s*=\s*)".*"$' "${{ env.APP_SERVER_BASE_URL }}" | |
| Set-ConfigValue '^(version\s*=\s*)".*"$' "${{ env.APP_SERVER_VERSION }}" | |
| Set-ConfigValue '^(secret_key\s*=\s*)".*"$' "${{ env.APP_SERVER_SECRET_KEY }}" | |
| Set-ConfigValue '^(check_url\s*=\s*)".*"$' "${{ env.APP_UPDATER_CHECK_URL }}" | |
| Set-ConfigValue '^(latest_json_url\s*=\s*)".*"$' "${{ env.APP_UPDATER_LATEST_JSON_URL }}" | |
| Set-ConfigValue '^(runtime_latest_json_url\s*=\s*)".*"$' "${{ env.APP_RUNTIME_LATEST_JSON_URL }}" | |
| Set-ConfigValue '^(updater_temp_dir\s*=\s*)".*"$' "${{ env.APP_UPDATER_TEMP_DIR }}" | |
| Set-ConfigValue '^(downlaod_url\s*=\s*)".*"$' "${{ env.APP_WEBVIEW_DOWNLOAD_URL }}" | |
| $utf8NoBom = New-Object System.Text.UTF8Encoding($false) | |
| $resolvedConfigPath = (Resolve-Path $configPath).Path | |
| [System.IO.File]::WriteAllText($resolvedConfigPath, $content, $utf8NoBom) | |
| # 在 CI 构建期间使用 fixed 版本的 Tauri 配置 | |
| # 先将 src-tauri/tauri.conf.fixed.json 覆盖为 src-tauri/tauri.conf.json, | |
| # 然后再由 prepare-version.mjs 统一写入最终版本号,确保参与打包的配置版本正确。 | |
| - name: Use fixed Tauri config | |
| shell: powershell | |
| run: | | |
| Copy-Item "src-tauri/tauri.conf.fixed.json" "src-tauri/tauri.conf.json" -Force | |
| - name: Prepare version from tag | |
| # For release events, GITHUB_REF_NAME is usually "vX.Y.Z" as well. | |
| run: node deploy/prepare-version.mjs | |
| # Build and bundle the Tauri app. | |
| # It will run `beforeBuildCommand` from `src-tauri/tauri.conf.json` (node build.cjs -> pnpm build:<env>) | |
| - name: Build Tauri app | |
| uses: tauri-apps/tauri-action@v0 | |
| env: | |
| # 优先使用 GT_TOKEN;未配置时回退到 GitHub 自动注入的 token | |
| GITHUB_TOKEN: ${{ secrets.GT_TOKEN || github.token }} | |
| # Optional: enable updater signing / release signing if you configure them later | |
| TAURI_PRIVATE_KEY: ${{ secrets.TAURI_PRIVATE_KEY }} | |
| TAURI_KEY_PASSWORD: ${{ secrets.TAURI_KEY_PASSWORD }} | |
| with: | |
| projectPath: . | |
| # 与本地一致,使用 production feature 进行构建 | |
| args: --features production | |
| - name: Generate latest.json | |
| run: node deploy/generate-latest-json.mjs | |
| - name: Publish GitHub release assets | |
| if: startsWith(github.ref, 'refs/tags/') | |
| env: | |
| GH_TOKEN: ${{ secrets.GT_TOKEN || github.token }} | |
| GH_REPO: ${{ github.repository }} | |
| run: node deploy/publish-github-release.mjs | |
| - name: Upload installer to R2 storage | |
| # tag push 时上传到 R2 | |
| if: startsWith(github.ref, 'refs/tags/') | |
| shell: powershell | |
| run: | | |
| $ErrorActionPreference = "Stop" | |
| $TAG = "${{ env.RELEASE_TAG }}" | |
| # 去掉前缀 v,得到纯版本号,如 0.1.0 | |
| $VERSION = $TAG.TrimStart('v') | |
| # 找到 NSIS 安装包 | |
| $installer = Get-ChildItem "src-tauri/target/release/bundle/nsis" -Filter *.exe | Select-Object -First 1 | |
| if (-not $installer) { | |
| Write-Error "NSIS installer not found under src-tauri/target/release/bundle/nsis" | |
| } | |
| # 使用 AWS CLI 上传到 R2(唯一方式) | |
| if (-not (Get-Command aws -ErrorAction SilentlyContinue)) { | |
| Write-Error "aws CLI not found. Please install AWS CLI v2 and ensure 'aws' is in PATH." | |
| } | |
| $accountId = "${{ env.R2_ACCOUNT_ID }}" | |
| $bucket = "${{ env.R2_BUCKET }}" | |
| $endpoint = "https://${accountId}.r2.cloudflarestorage.com" | |
| $dest = "s3://${bucket}/${VERSION}/simprint_setup.exe" | |
| $env:AWS_ACCESS_KEY_ID = "${{ env.R2_ACCESS_KEY_ID }}" | |
| $env:AWS_SECRET_ACCESS_KEY = "${{ env.R2_SECRET_ACCESS_KEY }}" | |
| $env:AWS_EC2_METADATA_DISABLED = "true" | |
| Write-Host "Uploading $($installer.FullName) to R2: $dest" | |
| aws s3 cp $installer.FullName $dest --endpoint-url $endpoint --region auto | |
| - name: Upload latest.json to R2 root | |
| # tag push 时上传到 R2 | |
| if: startsWith(github.ref, 'refs/tags/') | |
| shell: powershell | |
| run: | | |
| $ErrorActionPreference = "Stop" | |
| if (-not (Get-Command aws -ErrorAction SilentlyContinue)) { | |
| Write-Error "aws CLI not found. Please install AWS CLI v2 and ensure 'aws' is in PATH." | |
| } | |
| $accountId = "${{ env.R2_ACCOUNT_ID }}" | |
| $bucket = "${{ env.R2_BUCKET }}" | |
| $endpoint = "https://${accountId}.r2.cloudflarestorage.com" | |
| $dest = "s3://${bucket}/latest.json" | |
| $env:AWS_ACCESS_KEY_ID = "${{ env.R2_ACCESS_KEY_ID }}" | |
| $env:AWS_SECRET_ACCESS_KEY = "${{ env.R2_SECRET_ACCESS_KEY }}" | |
| $env:AWS_EC2_METADATA_DISABLED = "true" | |
| Write-Host "Uploading latest.json to R2 root: $dest" | |
| aws s3 cp "latest.json" $dest --endpoint-url $endpoint --region auto | |
| - name: Upload latest.json artifact (manual runs) | |
| if: github.event_name == 'workflow_dispatch' && hashFiles('latest.json') != '' | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: latest-json | |
| path: latest.json | |
| - name: Publish version metadata | |
| if: startsWith(github.ref, 'refs/tags/') | |
| env: | |
| VERSION_API_URL: ${{ secrets.VERSION_API_URL }} | |
| VERSION_API_KEY: ${{ secrets.VERSION_API_KEY }} | |
| RELEASE_TAG: ${{ env.RELEASE_TAG }} | |
| run: node deploy/publish-version.mjs |