name: Build & Release on: push: tags: - "v*" permissions: contents: write jobs: create-release: runs-on: ubuntu-latest outputs: release-id: ${{ steps.create.outputs.id }} steps: - name: Create draft release id: create env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | TAG="${{ github.ref_name }}" REPO="${{ github.repository }}" gh release view "$TAG" --repo "$REPO" >/dev/null 2>&1 && \ echo "id=$(gh release view "$TAG" --repo "$REPO" --json id --jq '.id')" >> "$GITHUB_OUTPUT" && \ echo "Release already exists." && exit 0 gh release create "$TAG" \ --repo "$REPO" \ --title "Clustri $TAG" \ --notes "See the assets below to download and install." \ --draft --verify-tag --target main echo "id=$(gh release view "$TAG" --repo "$REPO" --json id --jq '.id')" >> "$GITHUB_OUTPUT" build: needs: create-release strategy: fail-fast: false matrix: include: - platform: ubuntu-22.04 runner: ubuntu-22.04 target: "" - platform: windows runner: windows-latest target: "" - platform: macos runner: macos-latest target: "--target universal-apple-darwin" runs-on: ${{ matrix.runner }} 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' && '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 shell: bash env: TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }} run: npx tauri build ${{ matrix.target }} - name: Upload artifacts shell: bash env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | TAG="${{ github.ref_name }}" REPO="${{ github.repository }}" upload() { local file="$1" if [ -f "$file" ]; then echo "Uploading $(basename "$file")..." gh release upload "$TAG" "$file" --clobber --repo "$REPO" || true fi } find src-tauri/target -path "*/bundle/*" \( \ -name "*.deb" -o -name "*.rpm" -o -name "*.AppImage" -o \ -name "*.dmg" -o -name "*.app.tar.gz" -o -name "*.msi" -o \ -name "*.exe" -o -name "*.nsis.zip" -o -name "*.msi.zip" -o \ -name "*.sig" \ \) -type f | while read f; do upload "$f" done update-latest-json: needs: build runs-on: ubuntu-latest steps: - name: Generate and upload latest.json env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | python3 << 'PYEOF' import json, subprocess, os, tempfile tag = os.environ["GITHUB_REF_NAME"] repo = os.environ["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() data = json.loads(run(f'gh release view "{tag}" --repo "{repo}" --json assets')) assets = {a["name"]: a for a in data["assets"]} def find_asset(pattern): for name in assets: if pattern in name: return name return None def download_sig(name): if not name: return "" 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 app = find_asset(".AppImage") sig = find_asset(".AppImage.sig") if app and sig: s = download_sig(sig) if s: platforms["linux-x86_64"] = {"signature": s, "url": f"{base_url}/{app}"} # Windows NSIS exe = find_asset("-setup.exe") sig = find_asset("nsis.zip.sig") if exe and sig: s = download_sig(sig) if s: platforms["windows-x86_64"] = {"signature": s, "url": f"{base_url}/{exe}"} # macOS universal app = find_asset("app.tar.gz") sig = find_asset("app.tar.gz.sig") if app and sig: s = download_sig(sig) if s: platforms["darwin-x86_64"] = {"signature": s, "url": f"{base_url}/{app}"} platforms["darwin-aarch64"] = {"signature": s, "url": f"{base_url}/{app}"} 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("/tmp/latest.json", "w") as f: json.dump(latest, f, indent=2) print(json.dumps(latest, indent=2)) PYEOF gh release upload "${{ github.ref_name }}" /tmp/latest.json --clobber --repo "${{ github.repository }}" echo "latest.json uploaded."