Add Velopack lifecycle hook (required for Windows installer packaging) #17
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: Release Build | |
| on: | |
| push: | |
| tags: | |
| - 'v*' | |
| workflow_dispatch: | |
| permissions: | |
| contents: write | |
| jobs: | |
| # ============================================================ | |
| # macOS: .app bundle + .dmg (arm64 + x64) | |
| # ============================================================ | |
| build-macos: | |
| name: macOS ${{ matrix.arch }} | |
| runs-on: ${{ matrix.runner }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - arch: arm64 | |
| runner: macos-14 | |
| rid: osx-arm64 | |
| - arch: x64 | |
| runner: macos-15 | |
| rid: osx-x64 | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-dotnet@v4 | |
| with: | |
| dotnet-version: '10.0.x' | |
| - name: Get version | |
| shell: bash | |
| run: | | |
| VERSION=${GITHUB_REF#refs/tags/v} | |
| [[ "$VERSION" == refs/* ]] && VERSION=0.0.0-dev | |
| echo "VERSION=$VERSION" >> $GITHUB_ENV | |
| - name: Publish (self-contained) | |
| run: dotnet publish src/Taskly/Taskly.csproj -c Release -r ${{ matrix.rid }} --self-contained true -p:PublishSingleFile=true -p:Version=${{ env.VERSION }} -o publish | |
| - name: Assemble .app bundle | |
| shell: bash | |
| run: | | |
| mkdir -p "Taskly.app/Contents/MacOS" | |
| mkdir -p "Taskly.app/Contents/Resources" | |
| cp -R publish/* "Taskly.app/Contents/MacOS/" | |
| # 写 Info.plist(用实际版本号替换占位) | |
| sed 's/0\.3\.0/${{ env.VERSION }}/' packaging/macos/Info.plist > "Taskly.app/Contents/Info.plist" | |
| chmod +x "Taskly.app/Contents/MacOS/Taskly" | |
| - name: Create .dmg (with retry) | |
| shell: bash | |
| run: | | |
| chmod +x packaging/macos/create-dmg.sh | |
| packaging/macos/create-dmg.sh "Taskly.app" "taskly-${{ env.VERSION }}-macos-${{ matrix.arch }}.dmg" "Taskly" | |
| - uses: actions/upload-artifact@v4 | |
| with: | |
| name: taskly-macos-${{ matrix.arch }} | |
| path: '*.dmg' | |
| # ============================================================ | |
| # Windows: Setup.exe (Velopack) | |
| # ============================================================ | |
| build-windows: | |
| name: Windows x64 | |
| runs-on: windows-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-dotnet@v4 | |
| with: | |
| dotnet-version: '10.0.x' | |
| - name: Get version | |
| shell: bash | |
| run: | | |
| VERSION=${GITHUB_REF#refs/tags/v} | |
| [[ "$VERSION" == refs/* ]] && VERSION=0.0.0-dev | |
| echo "VERSION=$VERSION" >> $GITHUB_ENV | |
| - name: Publish (self-contained) | |
| run: dotnet publish src/Taskly/Taskly.csproj -c Release -r win-x64 --self-contained true -p:PublishSingleFile=true -p:Version=${{ env.VERSION }} -o publish | |
| - name: Install Velopack | |
| run: dotnet tool install -g vpk | |
| - name: Create Setup.exe | |
| shell: pwsh | |
| run: | | |
| $env:PATH = "$env:USERPROFILE\.dotnet\tools;$env:PATH" | |
| # 诊断:确认 publish 目录内容 | |
| Write-Host "=== publish 目录 ===" | |
| Get-ChildItem publish/*.exe | Format-Table Name, Length | |
| # 运行 vpk(出错了能看到完整输出) | |
| vpk pack -u Taskly -v ${{ env.VERSION }} -p publish -e Taskly.exe -o build --verbose | |
| Write-Host "=== build 产物 ===" | |
| Get-ChildItem build/*.exe | Format-Table Name, Length | |
| - uses: actions/upload-artifact@v4 | |
| with: | |
| name: taskly-windows-x64 | |
| path: 'build/*.exe' | |
| # ============================================================ | |
| # Linux: .AppImage + .deb | |
| # ============================================================ | |
| build-linux: | |
| name: Linux x64 | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-dotnet@v4 | |
| with: | |
| dotnet-version: '10.0.x' | |
| - name: Get version | |
| shell: bash | |
| run: | | |
| VERSION=${GITHUB_REF#refs/tags/v} | |
| [[ "$VERSION" == refs/* ]] && VERSION=0.0.0-dev | |
| echo "VERSION=$VERSION" >> $GITHUB_ENV | |
| - name: Publish (self-contained) | |
| run: dotnet publish src/Taskly/Taskly.csproj -c Release -r linux-x64 --self-contained true -p:PublishSingleFile=true -p:Version=${{ env.VERSION }} -o publish | |
| # --- AppImage --- | |
| - name: Install FUSE for AppImage | |
| run: sudo apt-get update && sudo apt-get install -y libfuse2 | |
| - name: Build AppImage | |
| shell: bash | |
| run: | | |
| # 组装 AppDir(appimagetool 要求 .desktop 在根目录) | |
| mkdir -p AppDir/usr/bin | |
| cp -R publish/* AppDir/usr/bin/ | |
| chmod +x AppDir/usr/bin/Taskly | |
| # .desktop 必须在 AppDir 根目录 | |
| cp packaging/linux/taskly.desktop AppDir/taskly.desktop | |
| cp packaging/linux/AppRun AppDir/AppRun | |
| chmod +x AppDir/AppRun | |
| # 下载 appimagetool | |
| wget -q "https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-x86_64.AppImage" -O appimagetool | |
| chmod +x appimagetool | |
| # 生成 AppImage(CI 环境用 APPIMAGE_EXTRACT_AND_RUN 绕过 FUSE) | |
| ARCH=x86_64 APPIMAGE_EXTRACT_AND_RUN=1 ./appimagetool AppDir "taskly-${{ env.VERSION }}-linux-x64.AppImage" | |
| ls -la *.AppImage | |
| # --- .deb --- | |
| - name: Build .deb | |
| shell: bash | |
| run: | | |
| VERSION=${{ env.VERSION }} | |
| STAGING="deb-staging" | |
| mkdir -p "$STAGING/usr/bin" | |
| mkdir -p "$STAGING/usr/lib/taskly" | |
| mkdir -p "$STAGING/usr/share/applications" | |
| mkdir -p "$STAGING/DEBIAN" | |
| # 可执行文件 + 运行时(self-contained) | |
| cp -R publish/* "$STAGING/usr/lib/taskly/" | |
| chmod +x "$STAGING/usr/lib/taskly/Taskly" | |
| # 启动脚本(转发到 self-contained 可执行文件) | |
| cat > "$STAGING/usr/bin/taskly" << 'EOF' | |
| #!/bin/sh | |
| exec /usr/lib/taskly/Taskly "$@" | |
| EOF | |
| chmod +x "$STAGING/usr/bin/taskly" | |
| # .desktop 文件(Exec 指向启动脚本) | |
| sed 's|Exec=Taskly|Exec=/usr/bin/taskly|' packaging/linux/taskly.desktop > "$STAGING/usr/share/applications/taskly.desktop" | |
| # control 文件(用实际版本号) | |
| sed "s/Version: 0.3.0/Version: $VERSION/" packaging/linux/control > "$STAGING/DEBIAN/control" | |
| # 构建 .deb | |
| dpkg-deb --root-owner-group --build "$STAGING" "taskly-${{ env.VERSION }}-linux-x64.deb" | |
| ls -la *.deb | |
| - uses: actions/upload-artifact@v4 | |
| with: | |
| name: taskly-linux-x64 | |
| path: | | |
| *.AppImage | |
| *.deb | |
| # ============================================================ | |
| # Release: 收集所有产物,创建 GitHub Release | |
| # ============================================================ | |
| release: | |
| name: Create Release | |
| needs: [build-macos, build-windows, build-linux] | |
| runs-on: ubuntu-latest | |
| if: startsWith(github.ref, 'refs/tags/') | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Get version | |
| shell: bash | |
| run: | | |
| VERSION=${GITHUB_REF#refs/tags/v} | |
| echo "VERSION=$VERSION" >> $GITHUB_ENV | |
| - uses: actions/download-artifact@v4 | |
| with: | |
| path: artifacts | |
| merge-multiple: true | |
| - name: List artifacts | |
| shell: bash | |
| run: find artifacts -type f | |
| - name: Create Release | |
| uses: softprops/action-gh-release@v2 | |
| with: | |
| files: | | |
| artifacts/*.dmg | |
| artifacts/*.exe | |
| artifacts/*.AppImage | |
| artifacts/*.deb | |
| name: Release v${{ env.VERSION }} | |
| body: | | |
| ## Downloads | |
| ### macOS | |
| - `taskly-${{ env.VERSION }}-macos-arm64.dmg` (Apple Silicon) | |
| - `taskly-${{ env.VERSION }}-macos-x64.dmg` (Intel) | |
| ### Windows | |
| - `taskly-${{ env.VERSION }}-windows-x64.exe` (Setup installer) | |
| ### Linux | |
| - `taskly-${{ env.VERSION }}-linux-x64.AppImage` (zero-install) | |
| - `taskly-${{ env.VERSION }}-linux-x64.deb` (Debian/Ubuntu) | |
| --- | |
| *Release notes are automatically generated.* | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} |