Files
ASLant 721cdb25d5 ci: 重构 CI 工作流并统一构建发布流程
- 删除 build.yml 和 release.yml,合并为单一 ci.yml
- 新增版本一致性校验及 tag 匹配检查
- 使用 npm ci 与 Cargo --locked 锁定依赖
- 缓存 Tauri CLI 2.12.1 并按 tag 触发发布
- 提交 package-lock.json 并忽略生成的 tailwind.css
2026-10-07 12:00:09 +08:00

150 lines
5.0 KiB
YAML

name: CI
on:
push:
branches: [main, master]
tags: ['v*']
pull_request:
branches: [main, master]
permissions:
contents: read
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: ${{ !startsWith(github.ref, 'refs/tags/') }}
env:
CARGO_TERM_COLOR: always
npm_config_loglevel: warn
TAURI_CLI_VERSION: '2.12.1'
jobs:
build:
name: Check and build Windows x64
runs-on: windows-latest
timeout-minutes: 45
outputs:
version: ${{ steps.version.outputs.version }}
steps:
- uses: actions/checkout@v4
with:
persist-credentials: false
- uses: actions/setup-node@v4
with:
node-version: '22'
cache: npm
- uses: dtolnay/rust-toolchain@stable
with:
components: rustfmt, clippy
- uses: Swatinem/rust-cache@v2
with:
workspaces: './src-tauri -> target'
- name: Validate versions
id: version
shell: pwsh
run: |
$version = (Get-Content package.json -Raw -Encoding utf8 | ConvertFrom-Json).version
$tauriVersion = (Get-Content src-tauri/tauri.conf.json -Raw -Encoding utf8 | ConvertFrom-Json).version
[Console]::OutputEncoding = [System.Text.UTF8Encoding]::new()
$metadata = cargo metadata --manifest-path src-tauri/Cargo.toml --locked --no-deps --format-version 1
if ($LASTEXITCODE -ne 0) { throw 'Cannot read Cargo package version' }
$cargoVersion = ($metadata | ConvertFrom-Json).packages[0].version
if ($version -cne $tauriVersion -or $version -cne $cargoVersion) {
throw "Version mismatch: npm=$version, Tauri=$tauriVersion, Cargo=$cargoVersion"
}
if ($env:GITHUB_REF -like 'refs/tags/*' -and $env:GITHUB_REF -cne "refs/tags/v$version") {
throw "Tag $env:GITHUB_REF does not match v$version"
}
Add-Content -Path $env:GITHUB_OUTPUT -Value "version=$version" -Encoding utf8
- name: Install frontend dependencies
run: npm ci
- name: Check frontend
run: npm run check
- name: Check Rust
run: |
cargo fmt --manifest-path src-tauri/Cargo.toml --all -- --check
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
cargo clippy --manifest-path src-tauri/Cargo.toml --locked --all-targets --all-features -- -D warnings
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
cargo test --manifest-path src-tauri/Cargo.toml --locked
- name: Cache Tauri CLI
id: tauri-cli
uses: actions/cache@v4
with:
path: ~/.cargo/bin/cargo-tauri.exe
key: tauri-cli-${{ env.TAURI_CLI_VERSION }}-windows-x64
- name: Install Tauri CLI
if: steps.tauri-cli.outputs.cache-hit != 'true'
run: cargo install tauri-cli --version "=$env:TAURI_CLI_VERSION" --locked
- name: Build CSS
run: npm run build:css
- name: Build application and installers
run: npm run build
- name: Prepare artifacts
shell: pwsh
env:
APP_VERSION: ${{ steps.version.outputs.version }}
run: |
$version = $env:APP_VERSION
$files = @{
'src-tauri/target/release/bundle/Portable/UPX-Tools.exe' = "UPX-Tools-$version-x64-portable.exe"
"src-tauri/target/release/bundle/msi/UPX-Tools_${version}_x64_zh-CN.msi" = "UPX-Tools-$version-x64.msi"
"src-tauri/target/release/bundle/nsis/UPX-Tools_${version}_x64-setup.exe" = "UPX-Tools-$version-x64-setup.exe"
}
foreach ($source in $files.Keys) {
if (!(Test-Path -LiteralPath $source -PathType Leaf) -or (Get-Item -LiteralPath $source).Length -eq 0) {
throw "Missing or empty build artifact: $source"
}
}
New-Item release -ItemType Directory -Force | Out-Null
foreach ($source in $files.Keys) {
Copy-Item -LiteralPath $source -Destination (Join-Path release $files[$source])
}
- name: Upload Windows packages
uses: actions/upload-artifact@v4
with:
name: UPX-Tools-Windows-x64
path: release/*
if-no-files-found: error
compression-level: 0
release:
name: Publish release
needs: build
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v')
runs-on: ubuntu-latest
timeout-minutes: 10
permissions:
contents: write
steps:
- uses: actions/download-artifact@v4
with:
name: UPX-Tools-Windows-x64
path: release
- uses: softprops/action-gh-release@v2
with:
files: |
release/UPX-Tools-${{ needs.build.outputs.version }}-x64-portable.exe
release/UPX-Tools-${{ needs.build.outputs.version }}-x64.msi
release/UPX-Tools-${{ needs.build.outputs.version }}-x64-setup.exe
fail_on_unmatched_files: true
prerelease: ${{ contains(needs.build.outputs.version, '-') }}
generate_release_notes: true