Update dotnet-ci.yaml #80
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: .NET CI/CD - Multi-Platform Release | |
| on: | |
| push: | |
| branches: [ main, master ] | |
| paths-ignore: | |
| - '**.md' | |
| - '**.gitignore' | |
| - '.github/**/*.yml' | |
| pull_request: | |
| branches: [ main, master ] | |
| workflow_dispatch: | |
| inputs: | |
| tagSuffix: | |
| description: 'Tag后缀(可选,如 beta1、rc2)' | |
| required: false | |
| default: '' | |
| type: string | |
| preRelease: | |
| description: '是否标记为预发布版本' | |
| required: false | |
| default: 'false' | |
| type: boolean | |
| env: | |
| SOLUTION_PATH: ./src/GeneralUpdate.Tool.Avalonia.sln | |
| PUBLISH_DIR: ./publish | |
| PROJECT_NAME: GeneralUpdate.Tool.Avalonia | |
| DOTNET_SDK_VERSION: '8.0.x' # 显式指定SDK版本,避免自动升级到预览版 | |
| jobs: | |
| build: | |
| name: Build ${{ matrix.os }} - ${{ matrix.target-os }} | |
| runs-on: ${{ matrix.os }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| os: [windows-latest, ubuntu-latest] | |
| target-os: [win-x64, linux-x64] | |
| exclude: | |
| - os: windows-latest | |
| target-os: linux-x64 | |
| - os: ubuntu-latest | |
| target-os: win-x64 | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| lfs: false | |
| # 强制指定SDK版本,避免使用预览版(如10.0) | |
| - name: Setup .NET SDK ${{ env.DOTNET_SDK_VERSION }} | |
| uses: actions/setup-dotnet@v4 | |
| with: | |
| dotnet-version: ${{ env.DOTNET_SDK_VERSION }} | |
| cache: true | |
| cache-dependency-path: | | |
| ${{ env.SOLUTION_PATH }} | |
| **/packages.lock.json | |
| # 修复核心:拆分锁文件生成和依赖还原(避免参数冲突) | |
| - name: Generate packages.lock.json (if missing) | |
| run: | | |
| # 仅当锁文件不存在时生成(避免覆盖已有锁文件) | |
| if [ ! -f "./src/packages.lock.json" ]; then | |
| echo "🔍 未找到锁文件,开始生成..." | |
| dotnet restore ${{ env.SOLUTION_PATH }} --generate-lock-file | |
| if [ $? -ne 0 ]; then | |
| echo "❌ 锁文件生成失败" | |
| exit 1 | |
| fi | |
| echo "✅ 锁文件生成成功" | |
| else | |
| echo "ℹ️ 锁文件已存在,跳过生成" | |
| fi | |
| shell: bash | |
| - name: Restore dependencies (locked mode) | |
| run: | | |
| # 使用已存在的锁文件还原依赖(锁定模式) | |
| dotnet restore ${{ env.SOLUTION_PATH }} --locked-mode | |
| if [ $? -ne 0 ]; then | |
| echo "❌ 依赖还原失败,请检查锁文件或依赖配置" | |
| exit 1 | |
| fi | |
| echo "✅ 依赖还原成功" | |
| shell: bash | |
| - name: Build Release version | |
| run: | | |
| dotnet build ${{ env.SOLUTION_PATH }} \ | |
| -c Release \ | |
| -r ${{ matrix.target-os }} \ | |
| --no-restore \ | |
| /p:WarningLevel=1 | |
| shell: bash | |
| - name: Publish application | |
| run: | | |
| mkdir -p ${{ env.PUBLISH_DIR }}/${{ matrix.target-os }} | |
| dotnet publish ${{ env.SOLUTION_PATH }} \ | |
| -c Release \ | |
| -r ${{ matrix.target-os }} \ | |
| -o ${{ env.PUBLISH_DIR }}/${{ matrix.target-os }} \ | |
| --no-build \ | |
| --self-contained true \ | |
| /p:PublishSingleFile=true \ | |
| /p:PublishTrimmed=true \ | |
| /p:TrimUnusedDependencies=true \ | |
| /p:DebugType=None \ | |
| /p:DebugSymbols=false \ | |
| /p:AssemblyVersion=1.0.${{ github.run_number }} \ | |
| /p:FileVersion=1.0.${{ github.run_number }} \ | |
| /p:UseAppHost=true | |
| if [ $(ls -A ${{ env.PUBLISH_DIR }}/${{ matrix.target-os }} | wc -l) -eq 0 ]; then | |
| echo "❌ 发布目录为空,发布失败" | |
| exit 1 | |
| fi | |
| shell: bash | |
| - name: Set execute permission (Linux only) | |
| if: matrix.target-os == 'linux-x64' | |
| run: | | |
| chmod +x ${{ env.PUBLISH_DIR }}/${{ matrix.target-os }}/${{ env.PROJECT_NAME }} | |
| if [ ! -x ${{ env.PUBLISH_DIR }}/${{ matrix.target-os }}/${{ env.PROJECT_NAME }} ]; then | |
| echo "❌ Linux可执行文件权限设置失败" | |
| exit 1 | |
| fi | |
| shell: bash | |
| - name: Package release files | |
| id: package | |
| run: | | |
| DATE=$(date +%Y%m%d) | |
| ZIP_NAME="${{ env.PROJECT_NAME }}_${{ matrix.target-os }}_${DATE}.zip" | |
| ZIP_PATH="${{ env.PUBLISH_DIR }}/${ZIP_NAME}" | |
| if [[ "${{ matrix.os }}" == "windows-latest" ]]; then | |
| powershell Compress-Archive -Path "${{ env.PUBLISH_DIR }}/${{ matrix.target-os }}/*" -DestinationPath "$ZIP_PATH" -Force | |
| else | |
| zip -r "$ZIP_PATH" "${{ env.PUBLISH_DIR }}/${{ matrix.target-os }}/*" | |
| fi | |
| if [ ! -f "$ZIP_PATH" ]; then | |
| echo "❌ 压缩包生成失败" | |
| exit 1 | |
| fi | |
| echo "zip_name=$ZIP_NAME" >> $GITHUB_OUTPUT | |
| echo "zip_path=$ZIP_PATH" >> $GITHUB_OUTPUT | |
| echo "✅ 压缩包生成成功:$ZIP_NAME" | |
| shell: bash | |
| - name: Upload build artifact | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: ${{ matrix.target-os }}_artifact | |
| path: ${{ steps.package.outputs.zip_path }} | |
| retention-days: 7 | |
| if-no-files-found: error | |
| release: | |
| name: Create GitHub Release | |
| runs-on: ubuntu-latest | |
| needs: build | |
| if: github.event_name == 'push' || github.event_name == 'workflow_dispatch' | |
| permissions: | |
| contents: write | |
| steps: | |
| - name: Download all artifacts | |
| uses: actions/download-artifact@v4 | |
| with: | |
| path: ./artifacts | |
| merge-multiple: false | |
| - name: Configure Git user | |
| run: | | |
| git config --global user.name "GitHub Actions" | |
| git config --global user.email "actions@github.com" | |
| git fetch --tags | |
| shell: bash | |
| - name: Generate date-based Tag | |
| id: create_tag | |
| run: | | |
| BASE_TAG="v$(date +%Y%m%d)" | |
| TAG_SUFFIX="${{ github.event.inputs.tagSuffix }}" | |
| if [ -n "$TAG_SUFFIX" ]; then | |
| FINAL_TAG="${BASE_TAG}-${TAG_SUFFIX}" | |
| else | |
| FINAL_TAG="${BASE_TAG}" | |
| fi | |
| if git rev-parse "$FINAL_TAG" >/dev/null 2>&1; then | |
| echo "ℹ️ Tag $FINAL_TAG 已存在,跳过创建" | |
| else | |
| git tag "$FINAL_TAG" | |
| git push origin "$FINAL_TAG" | |
| echo "✅ 成功创建Tag:$FINAL_TAG" | |
| fi | |
| echo "tag_name=$FINAL_TAG" >> $GITHUB_OUTPUT | |
| shell: bash | |
| - name: Create Release | |
| uses: softprops/action-gh-release@v2 | |
| with: | |
| tag_name: ${{ steps.create_tag.outputs.tag_name }} | |
| name: Release ${{ steps.create_tag.outputs.tag_name }} | |
| body: | | |
| ## 🚀 自动构建发布 | |
| - 构建日期:${{ steps.create_tag.outputs.tag_name }} | |
| - 构建编号:${{ github.run_number }} | |
| - 包含平台:Windows x64 / Linux x64 | |
| - 构建模式:Release | 单文件 | 自包含 | 依赖裁剪 | |
| files: | | |
| ./artifacts/win-x64_artifact/*.zip | |
| ./artifacts/linux-x64_artifact/*.zip | |
| prerelease: ${{ github.event.inputs.preRelease == 'true' || github.event.inputs.tagSuffix != '' }} | |
| draft: false | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Cleanup artifacts | |
| if: always() | |
| run: | | |
| rm -rf ./artifacts | |
| echo "✅ 产物清理完成" | |
| shell: bash |