Publish #14
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: Publish | |
| permissions: | |
| contents: write | |
| id-token: write | |
| attestations: write | |
| on: | |
| workflow_dispatch: | |
| inputs: | |
| version: | |
| description: "Version number (e.g., 2.0.0)" | |
| required: true | |
| type: string | |
| build_windows: | |
| description: "Build Windows installer" | |
| required: true | |
| type: boolean | |
| default: true | |
| build_linux: | |
| description: "Build Linux installer" | |
| required: true | |
| type: boolean | |
| default: false | |
| build_macos: | |
| description: "Build macOS installer" | |
| required: true | |
| type: boolean | |
| default: false | |
| jobs: | |
| prepare-platforms: | |
| name: Resolve selected platforms | |
| runs-on: ubuntu-latest | |
| outputs: | |
| platforms_json: ${{ steps.set-platforms.outputs.platforms_json }} | |
| steps: | |
| - name: Build platform matrix | |
| id: set-platforms | |
| shell: bash | |
| run: | | |
| platforms=() | |
| if [[ "${{ inputs.build_windows }}" == "true" ]]; then | |
| platforms+=('"windows"') | |
| fi | |
| if [[ "${{ inputs.build_linux }}" == "true" ]]; then | |
| platforms+=('"linux"') | |
| fi | |
| if [[ "${{ inputs.build_macos }}" == "true" ]]; then | |
| platforms+=('"macos"') | |
| fi | |
| if [[ ${#platforms[@]} -eq 0 ]]; then | |
| echo "At least one platform must be selected." | |
| exit 1 | |
| fi | |
| platforms_json="[$(IFS=,; echo "${platforms[*]}")]" | |
| echo "platforms_json=$platforms_json" >> "$GITHUB_OUTPUT" | |
| build-installers: | |
| name: Build installer (${{ matrix.platform }}) | |
| needs: prepare-platforms | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| platform: ${{ fromJSON(needs.prepare-platforms.outputs.platforms_json) }} | |
| runs-on: ${{ matrix.platform == 'windows' && 'windows-latest' || matrix.platform == 'linux' && 'ubuntu-24.04' || 'macos-15' }} | |
| steps: | |
| - uses: actions/checkout@v6.0.2 | |
| - name: Install Linux dependencies | |
| if: matrix.platform == 'linux' | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y \ | |
| libwebkit2gtk-4.1-dev \ | |
| libappindicator3-dev \ | |
| librsvg2-dev \ | |
| patchelf | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v6.2.0 | |
| with: | |
| node-version: lts/* | |
| cache: npm | |
| - name: Install Rust stable | |
| if: matrix.platform != 'macos' | |
| uses: dtolnay/rust-toolchain@stable | |
| - name: Install Rust stable (macOS Apple Silicon target) | |
| if: matrix.platform == 'macos' | |
| uses: dtolnay/rust-toolchain@stable | |
| with: | |
| targets: aarch64-apple-darwin | |
| - name: Rust cache | |
| uses: swatinem/rust-cache@v2.8.2 | |
| with: | |
| workspaces: ./src-tauri -> target | |
| - name: Install frontend dependencies | |
| run: npm ci | |
| - name: Build Tauri installer (Windows NSIS only) | |
| if: matrix.platform == 'windows' | |
| uses: tauri-apps/tauri-action@v0.6.1 | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| with: | |
| args: --bundles nsis | |
| - name: Build Tauri installer | |
| if: matrix.platform != 'windows' | |
| uses: tauri-apps/tauri-action@v0.6.1 | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Stage installer artifacts | |
| id: stage-installers | |
| shell: pwsh | |
| run: | | |
| $bundleRoot = Join-Path $env:GITHUB_WORKSPACE "src-tauri/target/release/bundle" | |
| $stagingRoot = Join-Path $env:GITHUB_WORKSPACE "release-assets" | |
| $platform = "${{ matrix.platform }}" | |
| New-Item -ItemType Directory -Force -Path $stagingRoot | Out-Null | |
| $patterns = switch ($platform) { | |
| "windows" { @("*.exe") } | |
| "linux" { @("*.deb", "*.rpm", "*.AppImage") } | |
| "macos" { @("*.dmg", "*.pkg", "*.app.tar.gz") } | |
| default { @() } | |
| } | |
| if ($patterns.Count -eq 0) { | |
| throw "Unsupported platform selection: $platform" | |
| } | |
| $files = foreach ($pattern in $patterns) { | |
| Get-ChildItem -Path $bundleRoot -Recurse -File -Filter $pattern -ErrorAction SilentlyContinue | |
| } | |
| $files = $files | Sort-Object -Property FullName -Unique | |
| if (-not $files -or $files.Count -eq 0) { | |
| throw "No installer artifacts found under $bundleRoot for platform $platform." | |
| } | |
| foreach ($file in $files) { | |
| Copy-Item -Path $file.FullName -Destination $stagingRoot -Force | |
| } | |
| - name: Upload installer artifacts | |
| uses: actions/upload-artifact@v6.0.0 | |
| with: | |
| name: installer-${{ matrix.platform }} | |
| path: ${{ github.workspace }}/release-assets | |
| if-no-files-found: error | |
| create-release: | |
| runs-on: windows-latest | |
| needs: | |
| - prepare-platforms | |
| - build-installers | |
| steps: | |
| - name: Download build artifacts | |
| uses: actions/download-artifact@v7.0.0 | |
| with: | |
| path: ${{ github.workspace }}/release-assets | |
| - name: Collect installer artifacts | |
| id: collect-installers | |
| shell: pwsh | |
| run: | | |
| $root = Join-Path $env:GITHUB_WORKSPACE "release-assets" | |
| $platforms = '${{ needs.prepare-platforms.outputs.platforms_json }}' | ConvertFrom-Json | |
| $files = @() | |
| foreach ($platform in $platforms) { | |
| $patterns = switch ($platform) { | |
| "windows" { @("*.exe") } | |
| "linux" { @("*.deb", "*.rpm", "*.AppImage") } | |
| "macos" { @("*.dmg", "*.pkg", "*.app.tar.gz") } | |
| default { @() } | |
| } | |
| if ($patterns.Count -eq 0) { | |
| throw "Unsupported platform selection: $platform" | |
| } | |
| $platformFiles = foreach ($pattern in $patterns) { | |
| Get-ChildItem -Path $root -Recurse -File -Filter $pattern -ErrorAction SilentlyContinue | |
| } | |
| $platformFiles = $platformFiles | Sort-Object -Property FullName -Unique | |
| if (-not $platformFiles -or $platformFiles.Count -eq 0) { | |
| throw "No installer artifacts found under $root for platform $platform." | |
| } | |
| $files += $platformFiles | |
| } | |
| $files = $files | Sort-Object -Property FullName -Unique | |
| if (-not $files -or $files.Count -eq 0) { | |
| throw "No installer artifacts found under $root." | |
| } | |
| $artifactList = ($files | ForEach-Object { $_.FullName }) -join "," | |
| $attestationSubjects = ($files | ForEach-Object { $_.FullName }) -join "`n" | |
| "artifacts=$artifactList" >> $env:GITHUB_OUTPUT | |
| "subject_path<<EOF" >> $env:GITHUB_OUTPUT | |
| $attestationSubjects >> $env:GITHUB_OUTPUT | |
| "EOF" >> $env:GITHUB_OUTPUT | |
| - name: Attest release artifact | |
| uses: actions/attest-build-provenance@v3.2.0 | |
| with: | |
| subject-path: ${{ steps.collect-installers.outputs.subject_path }} | |
| - name: Create Draft Release | |
| uses: ncipollo/release-action@v1.20.0 | |
| with: | |
| commit: ${{ github.sha }} | |
| tag: v${{ inputs.version }} | |
| name: Release v${{ inputs.version }} | |
| allowUpdates: true | |
| updateOnlyUnreleased: true | |
| replacesArtifacts: true | |
| draft: true | |
| artifacts: ${{ steps.collect-installers.outputs.artifacts }} | |
| token: ${{ secrets.GITHUB_TOKEN }} |