name: Build & Release on: push: tags: - "v*" permissions: contents: write jobs: release: strategy: fail-fast: false matrix: include: - platform: ubuntu-22.04 args: "" - platform: windows-latest args: "" - platform: macos-latest args: "--target universal-apple-darwin" runs-on: ${{ matrix.platform }} steps: - uses: actions/checkout@v4 - name: Setup Node.js uses: actions/setup-node@v4 with: node-version: 20 cache: npm - name: Install frontend dependencies run: npm ci - name: Setup Rust uses: dtolnay/rust-toolchain@stable with: targets: ${{ matrix.platform == 'macos-latest' && 'aarch64-apple-darwin,x86_64-apple-darwin' || '' }} - name: Rust cache uses: Swatinem/rust-cache@v2 with: workspaces: src-tauri - name: Install Linux dependencies if: matrix.platform == 'ubuntu-22.04' run: | sudo apt-get update sudo apt-get install -y libwebkit2gtk-4.1-dev libappindicator3-dev librsvg2-dev patchelf - name: Build and release uses: tauri-apps/tauri-action@v1 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }} with: tagName: ${{ github.ref_name }} releaseName: "Clustri ${{ github.ref_name }}" releaseBody: "See the assets below to download and install." releaseDraft: true prerelease: false updaterJsonPreferNsis: true args: ${{ matrix.args }} - name: Upload updater artifacts shell: bash env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | RELEASE_TAG="${{ github.ref_name }}" # Upload all .sig files from the entire target directory find src-tauri/target -name "*.sig" -type f | while read sig_file; do echo "Uploading $(basename "$sig_file")..." gh release upload "$RELEASE_TAG" "$sig_file" --clobber --repo ${{ github.repository }} 2>/dev/null || true done # Upload updater bundles (.app.tar.gz, .nsis.zip, .msi.zip) find src-tauri/target \( -name "*.app.tar.gz" -o -name "*.nsis.zip" -o -name "*.msi.zip" \) -type f | while read bundle_file; do echo "Uploading $(basename "$bundle_file")..." gh release upload "$RELEASE_TAG" "$bundle_file" --clobber --repo ${{ github.repository }} 2>/dev/null || true done update-latest-json: needs: release runs-on: ubuntu-latest steps: - name: Generate and upload latest.json env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | python3 << 'PYEOF' import json, subprocess, os, sys, tempfile TAG = os.environ.get("GITHUB_REF_NAME", "") REPO = os.environ.get("GITHUB_REPOSITORY", "") VERSION = TAG.lstrip("v") BASE_URL = f"https://github.com/{REPO}/releases/download/{TAG}" def run(cmd): return subprocess.check_output(cmd, shell=True, text=True).strip() def find_asset(pattern): data = json.loads(run(f'gh release view "{TAG}" --repo "{REPO}" --json assets')) for a in data["assets"]: if pattern in a["name"]: return a["name"] return None def download_asset(name): with tempfile.TemporaryDirectory() as d: subprocess.run( f'gh release download "{TAG}" --repo "{REPO}" -p "{name}" -D "{d}"', shell=True, capture_output=True ) path = os.path.join(d, name) if os.path.exists(path): with open(path) as f: return f.read().strip() return "" platforms = {} # Linux AppImage appimage = find_asset(".AppImage") appimage_sig = find_asset(".AppImage.sig") if appimage and appimage_sig: sig = download_asset(appimage_sig) if sig: platforms["linux-x86_64"] = {"signature": sig, "url": f"{BASE_URL}/{appimage}"} # Windows NSIS nsis = find_asset("-setup.exe") nsis_sig = find_asset("nsis.zip.sig") if nsis and nsis_sig: sig = download_asset(nsis_sig) if sig: platforms["windows-x86_64"] = {"signature": sig, "url": f"{BASE_URL}/{nsis}"} # macOS universal macos = find_asset("app.tar.gz") macos_sig = find_asset("app.tar.gz.sig") if macos and macos_sig: sig = download_asset(macos_sig) if sig: platforms["darwin-x86_64"] = {"signature": sig, "url": f"{BASE_URL}/{macos}"} platforms["darwin-aarch64"] = {"signature": sig, "url": f"{BASE_URL}/{macos}"} latest = { "version": VERSION, "notes": "See the assets below to download and install.", "pub_date": run("date -u +%Y-%m-%dT%H:%M:%SZ"), "platforms": platforms, } with open("latest.json", "w") as f: json.dump(latest, f, indent=2) print(json.dumps(latest, indent=2)) subprocess.run( f'gh release upload "{TAG}" latest.json --clobber --repo "{REPO}"', shell=True, check=True ) print("latest.json uploaded successfully.") PYEOF