diff --git a/.github/workflows/pre-release.yml b/.github/workflows/pre-release.yml deleted file mode 100644 index b8399c57..00000000 --- a/.github/workflows/pre-release.yml +++ /dev/null @@ -1,1166 +0,0 @@ -name: Create GitHub Pre-Release - -on: - workflow_dispatch: - inputs: - version_type: - description: "Version bump type" - required: true - default: "patch" - type: choice - options: - - patch - - minor - - major - - prerelease - -concurrency: - group: release-${{ github.ref_name }} # allow concurrent prerelease from different branches - cancel-in-progress: true - -permissions: - contents: write - packages: write - pull-requests: write - -env: - NODE_VERSION: 22 - PNPM_VERSION: 10.13.1 - RUST_TOOLCHAIN: nightly-2025-12-04 - CARGO_XWIN_VERSION: 0.20.2 - -jobs: - bump-version: - runs-on: ubuntu-24.04 - outputs: - new_tag: ${{ steps.version.outputs.new_tag }} - new_version: ${{ steps.version.outputs.new_version }} - branch_suffix: ${{ steps.branch.outputs.suffix }} - steps: - - name: Install cargo-edit - uses: taiki-e/cache-cargo-install-action@34ce5120836e5f9f1508d8713d7fdea0e8facd6f # v3.0.1 - with: - tool: cargo-edit - git: https://github.com/killercup/cargo-edit - rev: 96a3879fe3bafda6d0f943b642997fbf03e235cd # v0.13.9 - - - uses: actions/checkout@v6 - with: - token: ${{ secrets.GITHUB_TOKEN }} - ssh-key: ${{ secrets.DEPLOY_KEY }} - - - name: setup node - uses: ./.github/actions/setup-node - - - name: Setup SSH Agent for private dependencies - id: ssh-setup - if: ${{ github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository }} - uses: webfactory/ssh-agent@dc588b651fe13675774614f8e6a936a468676387 # v0.9.0 - with: - ssh-private-key: ${{ secrets.VK_PRIVATE_DEPLOY_KEY }} - - - name: Generate branch suffix - id: branch - run: | - branch_name="${{ github.ref_name }}" - # Get last 6 characters of branch name, remove all special chars (including dashes) - suffix=$(echo "$branch_name" | tail -c 7 | sed 's/[^a-zA-Z0-9]//g' | tr '[:upper:]' '[:lower:]') - echo "Branch: $branch_name" - echo "Suffix: $suffix" - echo "suffix=$suffix" >> $GITHUB_OUTPUT - - - name: Determine and update versions - id: version - run: | - # Get the latest version from npm registry - latest_npm_version=$(npm view vibe-kanban version 2>/dev/null || echo "0.0.0") - echo "Latest npm version: $latest_npm_version" - - # Get current repo version - current_repo_version=$(node -p "require('./package.json').version") - echo "Current repo version: $current_repo_version" - - # Use the higher of the two versions as the base (prevents downgrade errors with cargo set-version) - base_version=$(node -e " - const npm = '$latest_npm_version'.split('.').map(Number); - const repo = '$current_repo_version'.split('.').map(Number); - for (let i = 0; i < 3; i++) { - if ((npm[i] || 0) > (repo[i] || 0)) { console.log('$latest_npm_version'); process.exit(); } - if ((npm[i] || 0) < (repo[i] || 0)) { console.log('$current_repo_version'); process.exit(); } - } - console.log('$current_repo_version'); - ") - echo "Base version for bump: $base_version" - - timestamp=$(date +%Y%m%d%H%M%S) - - # Update root package.json based on base version - if [[ "${{ github.event.inputs.version_type }}" == "prerelease" ]]; then - # For prerelease, use current package.json version and add branch suffix - npm version prerelease --preid="${{ steps.branch.outputs.suffix }}" --no-git-tag-version - - new_version=$(node -p "require('./package.json').version") - new_tag="v${new_version}.${timestamp}" - else - # For regular releases, use base version and bump it - npm version $base_version --no-git-tag-version --allow-same-version - npm version ${{ github.event.inputs.version_type }} --no-git-tag-version - - new_version=$(node -p "require('./package.json').version") - new_tag="v${new_version}-${timestamp}" - fi - - # Update npx-cli package.json to match - ( - cd npx-cli - npm version $new_version --no-git-tag-version --allow-same-version - ) - - # Update web app package.json to match - ( - cd packages/local-web - npm version $new_version --no-git-tag-version --allow-same-version - ) - - cargo set-version --workspace "$new_version" - - node -e " - const fs = require('fs'); - const path = 'crates/tauri-app/tauri.conf.json'; - const conf = JSON.parse(fs.readFileSync(path, 'utf8')); - conf.version = '$new_version'; - fs.writeFileSync(path, JSON.stringify(conf, null, 2) + '\n'); - " - - echo "New version: $new_version" - echo "new_version=$new_version" >> $GITHUB_OUTPUT - echo "new_tag=$new_tag" >> $GITHUB_OUTPUT - - - name: Update remote crate lockfile - if: ${{ steps.ssh-setup.outcome == 'success' }} - run: cargo metadata --format-version 1 --manifest-path crates/remote/Cargo.toml > /dev/null - - - name: Update relay-tunnel crate lockfile - run: cargo metadata --format-version 1 --manifest-path crates/relay-tunnel/Cargo.toml > /dev/null - - - name: Stop SSH agent - if: ${{ steps.ssh-setup.outcome == 'success' }} - run: ssh-agent -k - - - name: Commit changes and create tag - run: | - git config --local user.email "action@github.com" - git config --local user.name "GitHub Action" - git add package.json pnpm-lock.yaml npx-cli/package.json npx-cli/package-lock.json packages/local-web/package.json crates/tauri-app/tauri.conf.json Cargo.lock - git add $(find . -name Cargo.toml) - [ -f crates/remote/Cargo.lock ] && git add crates/remote/Cargo.lock || true - [ -f crates/relay-tunnel/Cargo.lock ] && git add crates/relay-tunnel/Cargo.lock || true - git commit -m "chore: bump version to ${{ steps.version.outputs.new_version }}" - git tag -a ${{ steps.version.outputs.new_tag }} -m "Release ${{ steps.version.outputs.new_tag }}" - git push - git push --tags - - build-frontend: - needs: bump-version - runs-on: ubuntu-24.04 - env: - VITE_PUBLIC_REACT_VIRTUOSO_LICENSE_KEY: ${{ secrets.PUBLIC_REACT_VIRTUOSO_LICENSE_KEY }} - VITE_VK_SHARED_API_BASE: ${{ secrets.VK_SHARED_API_BASE }} - steps: - - uses: actions/checkout@v6 - with: - ref: ${{ needs.bump-version.outputs.new_tag }} - - - name: Setup Node - uses: ./.github/actions/setup-node - - - name: Install dependencies - run: pnpm install - - - name: Lint frontend - run: cd packages/local-web && npm run lint - - - name: Type check frontend - run: cd packages/local-web && npx tsc --noEmit - - - name: Build frontend - run: cd packages/local-web && npm run build - env: - SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }} - VITE_POSTHOG_API_KEY: ${{ secrets.POSTHOG_API_KEY }} - VITE_POSTHOG_API_ENDPOINT: ${{ secrets.POSTHOG_API_ENDPOINT }} - VITE_SENTRY_DSN: ${{ secrets.SENTRY_DSN }} - - - name: Create Sentry release - uses: getsentry/action-release@dab6548b3c03c4717878099e43782cf5be654289 # v3 - env: - SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }} - SENTRY_ORG: ${{ secrets.SENTRY_ORG }} - SENTRY_PROJECT: ${{ secrets.SENTRY_PROJECT }} - with: - release: ${{ needs.bump-version.outputs.new_version }} - environment: production - sourcemaps: "./packages/local-web/dist" - ignore_missing: true - - - name: Upload frontend artifact - uses: actions/upload-artifact@v6 - with: - name: frontend-dist - path: packages/local-web/dist/ - retention-days: 1 - - build-backend: - needs: [bump-version, build-frontend] - runs-on: ${{ matrix.os }} - strategy: - # Platform matrix - keep target/name in sync with package-npx-cli job - matrix: - include: - - target: x86_64-unknown-linux-musl - os: ubuntu-24.04 - name: linux-x64 - - target: aarch64-unknown-linux-musl - os: ubuntu-24.04-arm - name: linux-arm64 - - target: x86_64-pc-windows-msvc - os: ubuntu-24.04 - name: windows-x64 - - target: x86_64-apple-darwin - os: macos-15-xlarge - name: macos-x64 - - target: aarch64-apple-darwin - os: macos-15-xlarge - name: macos-arm64 - - target: aarch64-pc-windows-msvc - os: ubuntu-24.04 - name: windows-arm64 - env: - CARGO_INCREMENTAL: "0" - SCCACHE_GHA_ENABLED: "true" - RUSTC_WRAPPER: "sccache" - SCCACHE_CACHE_SIZE: "10G" - CARGO_HOME: ${{ github.workspace }}/.cargo - RUSTUP_HOME: ${{ github.workspace }}/.rustup - XWIN_CACHE_DIR: ${{ github.workspace }}/.xwin-cache - steps: - - uses: actions/checkout@v6 - with: - ref: ${{ needs.bump-version.outputs.new_tag }} - - - name: Setup sccache - uses: BloopAI/sccache-action@main - - - name: Cache Rust toolchain - uses: actions/cache@v5 - with: - path: .rustup/toolchains - key: rust-toolchain-${{ runner.os }}-${{ matrix.target }}-${{ env.RUST_TOOLCHAIN }} - - - name: Install Rust toolchain - uses: dtolnay/rust-toolchain@631a55b12751854ce901bb631d5902ceb48146f7 # stable - with: - toolchain: ${{ env.RUST_TOOLCHAIN }} - targets: ${{ matrix.target }} - components: rustfmt, clippy - - - name: Install dependencies (Linux) - if: runner.os == 'Linux' - run: | - sudo apt-get update - DEBIAN_FRONTEND=noninteractive sudo apt-get install -y clang libclang-dev lld llvm nasm cmake ninja-build - - if [[ "${{ matrix.target }}" == *"windows"* ]]; then - DEBIAN_FRONTEND=noninteractive sudo apt-get install -y clang-19 clang-tools-19 llvm-19 lld-19 - echo "/usr/lib/llvm-19/bin" >> $GITHUB_PATH - fi - - - name: Cache Cargo registry - uses: actions/cache@v5 - with: - path: | - .cargo/registry/cache - .cargo/registry/index - .cargo/git/db - .cargo/bin - .cargo/.crates.toml - .cargo/.crates2.json - key: cargo-${{ runner.os }}-${{ env.RUST_TOOLCHAIN }}-${{ matrix.target }}-${{ hashFiles('**/Cargo.lock') }} - restore-keys: | - cargo-${{ runner.os }}-${{ env.RUST_TOOLCHAIN }}-${{ matrix.target }}- - - - name: Install Zig - if: runner.os == 'Linux' && !contains(matrix.target, 'windows') - uses: BloopAI/setup-zig@main - with: - version: 0.15.2 - - - name: Install cargo zigbuild - if: runner.os == 'Linux' && !contains(matrix.target, 'windows') - uses: taiki-e/cache-cargo-install-action@34ce5120836e5f9f1508d8713d7fdea0e8facd6f # v3.0.1 - with: - tool: cargo-zigbuild - git: https://github.com/rust-cross/cargo-zigbuild - rev: bbb57ac6a5eb90f53617a5c218fda03080599e4a # v0.20.1 - - - name: Install cargo xwin - if: runner.os == 'Linux' && contains(matrix.target, 'windows') - uses: taiki-e/cache-cargo-install-action@34ce5120836e5f9f1508d8713d7fdea0e8facd6f # v3.0.1 - with: - tool: cargo-xwin - git: https://github.com/rust-cross/cargo-xwin - rev: 635a9559d49d719e79e0f60d92eb44447faf3212 # v0.20.2 - - - name: Cache xwin downloads - if: runner.os == 'Linux' && contains(matrix.target, 'windows') - uses: actions/cache@v5 - with: - path: ${{ github.workspace }}/.xwin-cache - key: xwin-${{ runner.os }}-${{ matrix.target }}-cargo-xwin-${{ env.CARGO_XWIN_VERSION }} - - - name: Cache target - uses: actions/cache@v5 - with: - path: target - key: target-${{ runner.os }}-${{ env.RUST_TOOLCHAIN }}-${{ matrix.target }}-${{ github.ref_name }}-${{ github.sha }} - restore-keys: | - target-${{ runner.os }}-${{ env.RUST_TOOLCHAIN }}-${{ matrix.target }}-${{ github.ref_name }}- - target-${{ runner.os }}-${{ env.RUST_TOOLCHAIN }}-${{ matrix.target }}- - - - name: Setup cargo-sweep - uses: taiki-e/cache-cargo-install-action@34ce5120836e5f9f1508d8713d7fdea0e8facd6f # v3.0.1 - with: - tool: cargo-sweep - git: https://github.com/holmgr/cargo-sweep - rev: 82f42d3593923db6fe715b299036512d91ddb35e # v0.8.0 - - - name: Download frontend artifact - uses: actions/download-artifact@v7 - with: - name: frontend-dist - path: packages/local-web/dist/ - - - name: Build backend (Linux) - if: runner.os == 'Linux' && !contains(matrix.target, 'windows') - run: | - cargo zigbuild --release --target ${{ matrix.target }} -p server -p mcp -p review --bin server --bin vibe-kanban-mcp --bin review - env: - POSTHOG_API_KEY: ${{ secrets.POSTHOG_API_KEY }} - POSTHOG_API_ENDPOINT: ${{ secrets.POSTHOG_API_ENDPOINT }} - VK_SHARED_API_BASE: ${{ secrets.VK_SHARED_API_BASE }} - VK_SHARED_RELAY_API_BASE: ${{ secrets.VK_SHARED_RELAY_API_BASE }} - SENTRY_DSN: ${{ secrets.SENTRY_DSN }} - - - name: Build backend (macOS) - if: runner.os == 'macOS' - run: | - if [[ "${{ matrix.target }}" == "x86_64-apple-darwin" ]]; then - export MACOSX_DEPLOYMENT_TARGET=10.12 - elif [[ "${{ matrix.target }}" == "aarch64-apple-darwin" ]]; then - export MACOSX_DEPLOYMENT_TARGET=11.0 - fi - cargo build --release --target ${{ matrix.target }} -p server -p mcp -p review --bin server --bin vibe-kanban-mcp --bin review - env: - POSTHOG_API_KEY: ${{ secrets.POSTHOG_API_KEY }} - POSTHOG_API_ENDPOINT: ${{ secrets.POSTHOG_API_ENDPOINT }} - VK_SHARED_API_BASE: ${{ secrets.VK_SHARED_API_BASE }} - VK_SHARED_RELAY_API_BASE: ${{ secrets.VK_SHARED_RELAY_API_BASE }} - SENTRY_DSN: ${{ secrets.SENTRY_DSN }} - - - name: Build backend (Windows) - if: runner.os == 'Linux' && contains(matrix.target, 'windows') - run: | - if [[ "${{ matrix.target }}" == "aarch64-pc-windows-msvc" ]]; then - # ring requires clang on arm64 windows. See https://github.com/briansmith/ring/issues/2117 - chmod +x scripts/ring-cc-wrapper.sh scripts/clang - export PATH="${{ github.workspace }}/scripts:$PATH" - export RING_CC=/usr/lib/llvm-19/bin/clang - export DEFAULT_CC=clang-cl - export CC_aarch64_pc_windows_msvc="${{ github.workspace }}/scripts/ring-cc-wrapper.sh" - fi - cargo xwin build --cross-compiler clang-cl --release --target ${{ matrix.target }} -p server -p mcp -p review --bin server --bin vibe-kanban-mcp --bin review - env: - POSTHOG_API_KEY: ${{ secrets.POSTHOG_API_KEY }} - POSTHOG_API_ENDPOINT: ${{ secrets.POSTHOG_API_ENDPOINT }} - VK_SHARED_API_BASE: ${{ secrets.VK_SHARED_API_BASE }} - VK_SHARED_RELAY_API_BASE: ${{ secrets.VK_SHARED_RELAY_API_BASE }} - SENTRY_DSN: ${{ secrets.SENTRY_DSN }} - # Avoid aws-lc-sys CMake failures when Rust's `release` profile includes debug info. - # Without this, cmake-rs selects RelWithDebInfo and CMake fails when ASM is enabled. - CARGO_PROFILE_RELEASE_DEBUG: 0 - - - name: Setup Sentry CLI - uses: matbour/setup-sentry-cli@3e938c54b3018bdd019973689ef984e033b0454b # v2 - with: - token: ${{ secrets.SENTRY_AUTH_TOKEN }} - organization: ${{ secrets.SENTRY_ORG }} - project: ${{ secrets.SENTRY_PROJECT }} - version: 2.21.2 - - - name: Upload source maps to Sentry - run: sentry-cli debug-files upload --include-sources target/${{ matrix.target }}/release - - - name: Prepare binaries (non-macOS) - if: runner.os != 'macOS' - shell: bash - run: | - mkdir -p dist - if [[ "${{ matrix.name }}" == *"windows"* ]]; then - cp target/${{ matrix.target }}/release/server.exe dist/vibe-kanban-${{ matrix.name }}.exe - cp target/${{ matrix.target }}/release/vibe-kanban-mcp.exe dist/vibe-kanban-mcp-${{ matrix.name }}.exe - cp target/${{ matrix.target }}/release/review.exe dist/vibe-kanban-review-${{ matrix.name }}.exe - else - cp target/${{ matrix.target }}/release/server dist/vibe-kanban-${{ matrix.name }} - cp target/${{ matrix.target }}/release/vibe-kanban-mcp dist/vibe-kanban-mcp-${{ matrix.name }} - cp target/${{ matrix.target }}/release/review dist/vibe-kanban-review-${{ matrix.name }} - fi - - # Code signing for macOS only - - name: Prepare Apple certificate (macOS) - if: runner.os == 'macOS' - run: | - echo "${{ secrets.APPLE_CERTIFICATE_P12_BASE64 }}" | base64 --decode > certificate.p12 - - - name: Write API Key to file - if: runner.os == 'macOS' - env: - API_KEY: ${{ secrets.APP_STORE_API_KEY }} - run: echo $API_KEY > app_store_key.json - - - name: Sign main binary (macOS) - if: runner.os == 'macOS' - uses: BloopAI/apple-code-sign-action@v1 - with: - input_path: target/${{ matrix.target }}/release/server - output_path: vibe-kanban - p12_file: certificate.p12 - p12_password: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }} - sign: true - sign_args: "--code-signature-flags=runtime" - - - name: Package main binary (macOS) - if: runner.os == 'macOS' - run: zip vibe-kanban.zip vibe-kanban - - - name: Sign MCP binary (macOS) - if: runner.os == 'macOS' - uses: BloopAI/apple-code-sign-action@v1 - with: - input_path: target/${{ matrix.target }}/release/vibe-kanban-mcp - output_path: vibe-kanban-mcp - p12_file: certificate.p12 - p12_password: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }} - sign: true - sign_args: "--code-signature-flags=runtime" - - - name: Package MCP binary (macOS) - if: runner.os == 'macOS' - run: zip vibe-kanban-mcp.zip vibe-kanban-mcp - - - name: Sign Review binary (macOS) - if: runner.os == 'macOS' - uses: BloopAI/apple-code-sign-action@v1 - with: - input_path: target/${{ matrix.target }}/release/review - output_path: vibe-kanban-review - p12_file: certificate.p12 - p12_password: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }} - sign: true - sign_args: "--code-signature-flags=runtime" - - - name: Package Review binary (macOS) - if: runner.os == 'macOS' - run: zip vibe-kanban-review.zip vibe-kanban-review - - - name: Notarize signed binaries (macOS) - if: runner.os == 'macOS' - uses: BloopAI/apple-code-sign-action@main - continue-on-error: true - with: - input_path: | - vibe-kanban.zip - vibe-kanban-mcp.zip - vibe-kanban-review.zip - sign: false - notarize: true - app_store_connect_api_key_json_file: app_store_key.json - - - name: Prepare signed binaries (macOS) - if: runner.os == 'macOS' - run: | - mkdir -p dist - cp vibe-kanban.zip dist/vibe-kanban-${{ matrix.name }}.zip - cp vibe-kanban-mcp.zip dist/vibe-kanban-mcp-${{ matrix.name }}.zip - cp vibe-kanban-review.zip dist/vibe-kanban-review-${{ matrix.name }}.zip - - - name: Clean up certificates (macOS) - if: runner.os == 'macOS' - run: | - rm -f certificate.p12 - rm -rf private_keys/ - - - name: Upload binary artifact - uses: actions/upload-artifact@v6 - with: - name: backend-binary-${{ matrix.name }} - path: dist/ - retention-days: 1 - - - name: Sweep Cargo target cache - shell: bash - run: | - cargo sweep --maxsize 10GB - cargo sweep --time 30 - - - package-npx-cli: - needs: [bump-version, build-frontend, build-backend] - runs-on: ubuntu-24.04 - strategy: - # NOTE: This matrix must be kept in sync with build-backend job above - # GitHub Actions doesn't support YAML anchors, so duplication is unavoidable - matrix: - include: - - target: x86_64-unknown-linux-musl - name: linux-x64 - binary: vibe-kanban - mcp_binary: vibe-kanban-mcp - review_binary: vibe-kanban-review - - target: x86_64-pc-windows-msvc - name: windows-x64 - binary: vibe-kanban.exe - mcp_binary: vibe-kanban-mcp.exe - review_binary: vibe-kanban-review.exe - - target: x86_64-apple-darwin - name: macos-x64 - binary: vibe-kanban - mcp_binary: vibe-kanban-mcp - review_binary: vibe-kanban-review - - target: aarch64-apple-darwin - name: macos-arm64 - binary: vibe-kanban - mcp_binary: vibe-kanban-mcp - review_binary: vibe-kanban-review - - target: aarch64-pc-windows-msvc - name: windows-arm64 - binary: vibe-kanban.exe - mcp_binary: vibe-kanban-mcp.exe - review_binary: vibe-kanban-review.exe - - target: aarch64-unknown-linux-musl - name: linux-arm64 - binary: vibe-kanban - mcp_binary: vibe-kanban-mcp - review_binary: vibe-kanban-review - steps: - - uses: actions/checkout@v6 - with: - ref: ${{ needs.bump-version.outputs.new_tag }} - - - name: Download frontend artifact - uses: actions/download-artifact@v7 - with: - name: frontend-dist - path: packages/local-web/dist/ - - - name: Download backend binary artifact - uses: actions/download-artifact@v7 - with: - name: backend-binary-${{ matrix.name }} - path: dist/ - - - name: List downloaded artifacts - run: | - echo "Downloaded backend binaries:" - find dist/ - - - name: Create platform package - if: matrix.name != 'macos-arm64' && matrix.name != 'macos-x64' - run: | - mkdir -p npx-cli/dist/${{ matrix.name }} - mkdir vibe-kanban-${{ matrix.name }} - mkdir vibe-kanban-mcp-${{ matrix.name }} - mkdir vibe-kanban-review-${{ matrix.name }} - - cp dist/vibe-kanban-${{ matrix.name }}* vibe-kanban-${{ matrix.name }}/${{ matrix.binary }} - cp dist/vibe-kanban-mcp-${{ matrix.name }}* vibe-kanban-mcp-${{ matrix.name }}/${{ matrix.mcp_binary }} - cp dist/vibe-kanban-review-${{ matrix.name }}* vibe-kanban-review-${{ matrix.name }}/${{ matrix.review_binary }} - - zip -j npx-cli/dist/${{ matrix.name }}/vibe-kanban.zip vibe-kanban-${{ matrix.name }}/${{ matrix.binary }} - zip -j npx-cli/dist/${{ matrix.name }}/vibe-kanban-mcp.zip vibe-kanban-mcp-${{ matrix.name }}/${{ matrix.mcp_binary }} - zip -j npx-cli/dist/${{ matrix.name }}/vibe-kanban-review.zip vibe-kanban-review-${{ matrix.name }}/${{ matrix.review_binary }} - - - name: Create platform package (macOS) - if: matrix.name == 'macos-arm64' || matrix.name == 'macos-x64' - run: | - mkdir -p npx-cli/dist/${{ matrix.name }} - mkdir vibe-kanban-${{ matrix.name }} - cp dist/vibe-kanban-${{ matrix.name }}* npx-cli/dist/${{ matrix.name }}/vibe-kanban.zip - cp dist/vibe-kanban-mcp-${{ matrix.name }}* npx-cli/dist/${{ matrix.name }}/vibe-kanban-mcp.zip - cp dist/vibe-kanban-review-${{ matrix.name }}* npx-cli/dist/${{ matrix.name }}/vibe-kanban-review.zip - - - name: Upload platform package artifact - uses: actions/upload-artifact@v6 - with: - name: npx-platform-${{ matrix.name }} - path: npx-cli/dist/ - retention-days: 1 - - upload-to-r2: - needs: [bump-version, package-npx-cli] - runs-on: ubuntu-24.04 - steps: - - uses: actions/checkout@v6 - with: - ref: ${{ needs.bump-version.outputs.new_tag }} - - - name: Download all platform packages - uses: actions/download-artifact@v7 - with: - pattern: npx-platform-* - path: binaries/ - merge-multiple: true - - - name: List downloaded binaries - run: | - echo "Downloaded binaries:" - find binaries/ - - - name: Configure AWS CLI for R2 - run: | - aws configure set aws_access_key_id ${{ secrets.R2_BINARIES_ACCESS_KEY_ID }} - aws configure set aws_secret_access_key ${{ secrets.R2_BINARIES_SECRET_ACCESS_KEY }} - aws configure set default.region auto - - - name: Generate manifest and upload to R2 - run: | - TAG="${{ needs.bump-version.outputs.new_tag }}" - ENDPOINT="${{ secrets.R2_BINARIES_ENDPOINT }}" - BUCKET="${{ secrets.R2_BINARIES_BUCKET }}" - - # Generate version manifest with checksums - node -e " - const fs = require('fs'); - const crypto = require('crypto'); - const manifest = { version: '$TAG', platforms: {} }; - const platforms = ['linux-x64', 'linux-arm64', 'windows-x64', 'windows-arm64', 'macos-x64', 'macos-arm64']; - const binaries = ['vibe-kanban', 'vibe-kanban-mcp', 'vibe-kanban-review']; - - for (const platform of platforms) { - manifest.platforms[platform] = {}; - for (const binary of binaries) { - const zipPath = \`binaries/\${platform}/\${binary}.zip\`; - if (fs.existsSync(zipPath)) { - const data = fs.readFileSync(zipPath); - manifest.platforms[platform][binary] = { - sha256: crypto.createHash('sha256').update(data).digest('hex'), - size: data.length - }; - } - } - } - fs.writeFileSync('version-manifest.json', JSON.stringify(manifest, null, 2)); - console.log('Generated manifest:'); - console.log(JSON.stringify(manifest, null, 2)); - " - - # Upload binaries (use full tag for path, allows multiple pre-releases to coexist) - for platform in linux-x64 linux-arm64 windows-x64 windows-arm64 macos-x64 macos-arm64; do - for binary in vibe-kanban vibe-kanban-mcp vibe-kanban-review; do - if [ -f "binaries/$platform/$binary.zip" ]; then - echo "Uploading binaries/$platform/$binary.zip..." - aws s3 cp "binaries/$platform/$binary.zip" \ - "s3://$BUCKET/binaries/$TAG/$platform/$binary.zip" \ - --endpoint-url "$ENDPOINT" - fi - done - done - - # Upload version manifest - echo "Uploading version manifest..." - aws s3 cp version-manifest.json \ - "s3://$BUCKET/binaries/$TAG/manifest.json" \ - --endpoint-url "$ENDPOINT" --content-type "application/json" - - # Update global manifest - VERSION="${{ needs.bump-version.outputs.new_version }}" - echo "Updating global manifest..." - echo "{\"latest\": \"$VERSION\"}" | aws s3 cp - \ - "s3://$BUCKET/binaries/manifest.json" \ - --endpoint-url "$ENDPOINT" --content-type "application/json" - - - name: Verify upload - run: | - TAG="${{ needs.bump-version.outputs.new_tag }}" - ENDPOINT="${{ secrets.R2_BINARIES_ENDPOINT }}" - BUCKET="${{ secrets.R2_BINARIES_BUCKET }}" - - echo "Listing uploaded files..." - aws s3 ls "s3://$BUCKET/binaries/$TAG/" \ - --endpoint-url "$ENDPOINT" \ - --recursive - - build-tauri: - needs: [bump-version, build-frontend] - runs-on: ${{ matrix.os }} - defaults: - run: - shell: bash - strategy: - matrix: - include: - - target: aarch64-apple-darwin - os: macos-15-xlarge - platform: darwin-aarch64 - - target: x86_64-apple-darwin - os: macos-15-xlarge - platform: darwin-x86_64 - - target: x86_64-unknown-linux-gnu - os: ubuntu-24.04 - platform: linux-x86_64 - - target: aarch64-unknown-linux-gnu - os: ubuntu-24.04-arm - platform: linux-aarch64 - - target: x86_64-pc-windows-msvc - os: ubuntu-24.04 - platform: windows-x86_64 - - target: aarch64-pc-windows-msvc - os: ubuntu-24.04 - platform: windows-aarch64 - env: - CARGO_INCREMENTAL: "0" - SCCACHE_GHA_ENABLED: "true" - RUSTC_WRAPPER: "sccache" - SCCACHE_CACHE_SIZE: "10G" - CARGO_HOME: ${{ github.workspace }}/.cargo - RUSTUP_HOME: ${{ github.workspace }}/.rustup - XWIN_CACHE_DIR: ${{ github.workspace }}/.xwin-cache - steps: - - uses: actions/checkout@v6 - with: - ref: ${{ needs.bump-version.outputs.new_tag }} - - - name: Setup sccache - uses: BloopAI/sccache-action@main - - - name: Cache Rust toolchain - uses: actions/cache@v5 - with: - path: .rustup/toolchains - key: rust-toolchain-${{ runner.os }}-${{ matrix.target }}-${{ env.RUST_TOOLCHAIN }} - - - name: Install Rust toolchain - uses: dtolnay/rust-toolchain@631a55b12751854ce901bb631d5902ceb48146f7 # stable - with: - toolchain: ${{ env.RUST_TOOLCHAIN }} - targets: ${{ matrix.target }} - - - name: Cache Cargo registry - uses: actions/cache@v5 - with: - path: | - .cargo/registry/cache - .cargo/registry/index - .cargo/git/db - .cargo/bin - .cargo/.crates.toml - .cargo/.crates2.json - key: cargo-tauri-${{ runner.os }}-${{ env.RUST_TOOLCHAIN }}-${{ matrix.target }}-${{ hashFiles('**/Cargo.lock') }} - restore-keys: | - cargo-tauri-${{ runner.os }}-${{ env.RUST_TOOLCHAIN }}-${{ matrix.target }}- - - - name: Cache target - uses: actions/cache@v5 - with: - path: target - key: tauri-target-${{ runner.os }}-${{ env.RUST_TOOLCHAIN }}-${{ matrix.target }}-${{ github.ref_name }}-${{ github.sha }} - restore-keys: | - tauri-target-${{ runner.os }}-${{ env.RUST_TOOLCHAIN }}-${{ matrix.target }}-${{ github.ref_name }}- - tauri-target-${{ runner.os }}-${{ env.RUST_TOOLCHAIN }}-${{ matrix.target }}- - - - name: Setup cargo-sweep - uses: taiki-e/cache-cargo-install-action@34ce5120836e5f9f1508d8713d7fdea0e8facd6f # v3.0.1 - with: - tool: cargo-sweep - git: https://github.com/holmgr/cargo-sweep - rev: 82f42d3593923db6fe715b299036512d91ddb35e # v0.8.0 - - - name: Setup Node - uses: ./.github/actions/setup-node - - - name: Install Linux dependencies - if: runner.os == 'Linux' && contains(matrix.target, 'linux') - run: | - sudo apt-get update - sudo apt-get install -y libwebkit2gtk-4.1-dev build-essential \ - libssl-dev libayatana-appindicator3-dev librsvg2-dev \ - libxdo-dev file pkg-config xdg-utils - - - name: Install Windows cross-compilation dependencies - if: runner.os == 'Linux' && contains(matrix.target, 'windows') - run: | - sudo apt-get update - DEBIAN_FRONTEND=noninteractive sudo apt-get install -y \ - clang libclang-dev lld llvm nasm cmake ninja-build nsis \ - clang-19 clang-tools-19 llvm-19 lld-19 \ - meson valac bison gobject-introspection libgirepository1.0-dev \ - libglib2.0-dev libgsf-1-dev libgcab-dev libmsi-dev - echo "/usr/lib/llvm-19/bin" >> $GITHUB_PATH - - - name: Build and install wixl - if: runner.os == 'Linux' && contains(matrix.target, 'windows') - env: - RUSTC_WRAPPER: "" - run: | - cd /tmp - curl -sL https://download.gnome.org/sources/msitools/0.103/msitools-0.103.tar.xz -o msitools-0.103.tar.xz - echo "d17622eebbf37fa4c09b59be0bc8db08b26be300a6731c74da1ebce262bce839 msitools-0.103.tar.xz" | sha256sum -c - - tar xJf msitools-0.103.tar.xz - cd msitools-0.103 - meson setup builddir --prefix=/usr - meson compile -C builddir wixl - sudo install -m755 builddir/tools/wixl/wixl /usr/local/bin/wixl - sudo install -m644 builddir/libmsi/libmsi-1.0.so.0.0.0 /usr/local/lib/ - sudo ln -sf libmsi-1.0.so.0.0.0 /usr/local/lib/libmsi-1.0.so.0 - sudo ln -sf libmsi-1.0.so.0 /usr/local/lib/libmsi-1.0.so - sudo ldconfig - sudo mkdir -p /usr/share/wixl-0.103/ext - sudo cp -r data/ext/ui /usr/share/wixl-0.103/ext/ - cd / && rm -rf /tmp/msitools-0.103 - wixl --version - - - name: Install cargo-xwin - if: runner.os == 'Linux' && contains(matrix.target, 'windows') - uses: taiki-e/cache-cargo-install-action@34ce5120836e5f9f1508d8713d7fdea0e8facd6f # v3.0.1 - with: - tool: cargo-xwin - git: https://github.com/rust-cross/cargo-xwin - rev: 635a9559d49d719e79e0f60d92eb44447faf3212 # v0.20.2 - - - name: Cache xwin downloads - if: runner.os == 'Linux' && contains(matrix.target, 'windows') - uses: actions/cache@v5 - with: - path: ${{ github.workspace }}/.xwin-cache - key: xwin-${{ runner.os }}-${{ matrix.target }}-cargo-xwin-${{ env.CARGO_XWIN_VERSION }} - - - name: Install dependencies - run: pnpm install - - - name: Install Tauri CLI - uses: taiki-e/cache-cargo-install-action@34ce5120836e5f9f1508d8713d7fdea0e8facd6f # v3.0.1 - with: - tool: tauri-cli@2 - - - name: Download frontend artifact - uses: actions/download-artifact@v7 - with: - name: frontend-dist - path: packages/local-web/dist/ - - - name: Patch tauri.conf.json for CI - run: | - node -e " - const fs = require('fs'); - const conf = JSON.parse(fs.readFileSync('crates/tauri-app/tauri.conf.json', 'utf8')); - // Inject the real updater endpoint (replaces __TAURI_UPDATE_ENDPOINT__ placeholder) - const endpoint = '${{ secrets.R2_BINARIES_PUBLIC_URL }}/binaries/tauri-update/latest.json'; - conf.plugins.updater.endpoints = conf.plugins.updater.endpoints.map(e => - e === '__TAURI_UPDATE_ENDPOINT__' ? endpoint : e - ); - fs.writeFileSync('crates/tauri-app/tauri.conf.json', JSON.stringify(conf, null, 2) + '\n'); - " - - - name: Set up Apple notarization key - if: runner.os == 'macOS' - env: - API_KEY_ID: ${{ secrets.APPLE_API_KEY_ID }} - API_ISSUER: ${{ secrets.APPLE_API_ISSUER }} - API_PRIVATE_KEY: ${{ secrets.APPLE_API_PRIVATE_KEY }} - run: | - # Write the .p8 key file where Tauri/notarytool can find it - mkdir -p ~/.private_keys - KEY_PATH="$HOME/.private_keys/AuthKey_${API_KEY_ID}.p8" - printf '%s' "$API_PRIVATE_KEY" > "$KEY_PATH" - - echo "APPLE_API_KEY=$API_KEY_ID" >> $GITHUB_ENV - echo "APPLE_API_ISSUER=$API_ISSUER" >> $GITHUB_ENV - echo "APPLE_API_KEY_PATH=$KEY_PATH" >> $GITHUB_ENV - - - name: Build Tauri app - run: | - if [[ "${{ matrix.target }}" == "aarch64-pc-windows-msvc" ]]; then - # ring requires clang on arm64 windows cross-compile - chmod +x scripts/ring-cc-wrapper.sh scripts/clang - export PATH="${{ github.workspace }}/scripts:$PATH" - export RING_CC=/usr/lib/llvm-19/bin/clang - export DEFAULT_CC=clang-cl - export CC_aarch64_pc_windows_msvc="${{ github.workspace }}/scripts/ring-cc-wrapper.sh" - export CARGO_PROFILE_RELEASE_DEBUG=0 - fi - - if [[ "${{ matrix.target }}" == *"windows"* ]]; then - cargo tauri build --runner cargo-xwin --target ${{ matrix.target }} --ci - else - cargo tauri build --target ${{ matrix.target }} --ci - fi - env: - TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }} - TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }} - APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE_P12_BASE64 }} - APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }} - APPLE_SIGNING_IDENTITY: ${{ secrets.APPLE_SIGNING_IDENTITY }} - APPLE_API_KEY: ${{ env.APPLE_API_KEY }} - APPLE_API_ISSUER: ${{ env.APPLE_API_ISSUER }} - APPLE_API_KEY_PATH: ${{ env.APPLE_API_KEY_PATH }} - POSTHOG_API_KEY: ${{ secrets.POSTHOG_API_KEY }} - POSTHOG_API_ENDPOINT: ${{ secrets.POSTHOG_API_ENDPOINT }} - VK_SHARED_API_BASE: ${{ secrets.VK_SHARED_API_BASE }} - VK_SHARED_RELAY_API_BASE: ${{ secrets.VK_SHARED_RELAY_API_BASE }} - SENTRY_DSN: ${{ secrets.SENTRY_DSN }} - - - name: Build MSI with wixl - if: contains(matrix.target, 'windows') - run: | - node scripts/build-tauri-msi.js \ - --target ${{ matrix.target }} \ - --version ${{ needs.bump-version.outputs.new_version }} - - # TODO: Re-enable Windows code signing once Azure Trusted Signing 403 is resolved - # - name: Setup Jsign - # if: contains(matrix.target, 'windows') - # id: jsign - # uses: ./.github/actions/setup-jsign - # - # - name: Install JRE for Jsign - # if: contains(matrix.target, 'windows') - # run: | - # sudo apt-get update - # sudo apt-get install -y default-jre-headless - # - # - name: Azure CLI login - # if: contains(matrix.target, 'windows') && env.AZURE_ENDPOINT != '' - # uses: azure/login@a457da9ea143d694b1b9c7c869ebb04ebe844ef5 # v2 - # with: - # creds: '{"clientId":"${{ secrets.AZURE_CLIENT_ID }}","clientSecret":"${{ secrets.AZURE_CLIENT_SECRET }}","tenantId":"${{ secrets.AZURE_TENANT_ID }}"}' - # allow-no-subscriptions: true - # env: - # AZURE_ENDPOINT: ${{ secrets.AZURE_ENDPOINT }} - # - # - name: Sign Windows artifacts with Azure Trusted Signing - # if: contains(matrix.target, 'windows') && env.AZURE_ENDPOINT != '' - # env: - # AZURE_ENDPOINT: ${{ secrets.AZURE_ENDPOINT }} - # AZURE_CODE_SIGNING_NAME: ${{ secrets.AZURE_CODE_SIGNING_NAME }} - # AZURE_CERT_PROFILE_NAME: ${{ secrets.AZURE_CERT_PROFILE_NAME }} - # run: | - # TOKEN=$(az account get-access-token --resource https://codesigning.azure.net --query accessToken -o tsv) - # - # # Extract hostname from endpoint URL - # KEYSTORE=$(echo "$AZURE_ENDPOINT" | sed 's|https\?://||;s|/.*||') - # - # # Sign all exe and msi files in the bundle directory - # find target/${{ matrix.target }}/release/bundle -type f \( -name "*.exe" -o -name "*.msi" \) | while read file; do - # echo "Signing: $file" - # java -jar "${{ steps.jsign.outputs.jar-path }}" \ - # --storetype TRUSTEDSIGNING \ - # --keystore "$KEYSTORE" \ - # --storepass "$TOKEN" \ - # --alias "${AZURE_CODE_SIGNING_NAME}/${AZURE_CERT_PROFILE_NAME}" \ - # --tsaurl http://timestamp.acs.microsoft.com \ - # --tsmode RFC3161 \ - # "$file" - # done - - - name: Collect updater artifacts and installers - run: | - mkdir -p tauri-artifacts/${{ matrix.platform }} - # Collect updater artifacts (.sig files and their corresponding bundles) - find target/${{ matrix.target }}/release/bundle -name "*.sig" | while read sig; do - artifact="${sig%.sig}" - if [ -f "$artifact" ]; then - cp "$artifact" "tauri-artifacts/${{ matrix.platform }}/" - cp "$sig" "tauri-artifacts/${{ matrix.platform }}/" - echo "Collected updater artifact: $(basename $artifact)" - fi - done - # Collect installer files for GitHub Release (DMG, AppImage, deb, msi, NSIS exe) - find target/${{ matrix.target }}/release/bundle \ - \( -name "*.dmg" -o -name "*.AppImage" -o -name "*.deb" -o -name "*.msi" -o -name "*-setup.exe" \) | while read f; do - cp "$f" "tauri-artifacts/${{ matrix.platform }}/" - echo "Collected installer: $(basename $f)" - done - echo "All artifacts for ${{ matrix.platform }}:" - ls -la tauri-artifacts/${{ matrix.platform }}/ - - - name: Clean up signing keys - if: always() && runner.os == 'macOS' - run: rm -rf ~/.private_keys - - - name: Upload Tauri artifacts - uses: actions/upload-artifact@v6 - with: - name: tauri-artifacts-${{ matrix.platform }} - path: tauri-artifacts/ - retention-days: 1 - - - name: Sweep Cargo target cache - if: always() - run: | - cargo sweep --maxsize 10GB - cargo sweep --time 30 - - upload-tauri-update: - needs: [bump-version, build-tauri] - runs-on: ubuntu-24.04 - steps: - - uses: actions/checkout@v6 - with: - ref: ${{ needs.bump-version.outputs.new_tag }} - - - name: Setup Node - uses: ./.github/actions/setup-node - - - name: Download all Tauri artifacts - uses: actions/download-artifact@v7 - with: - pattern: tauri-artifacts-* - path: tauri-artifacts/ - merge-multiple: true - - - name: List Tauri artifacts - run: find tauri-artifacts/ - - - name: Generate updater manifest - run: | - node scripts/generate-tauri-update-json.js \ - --version "${{ needs.bump-version.outputs.new_version }}" \ - --notes "Release ${{ needs.bump-version.outputs.new_tag }}" \ - --artifacts-dir ./tauri-artifacts \ - --download-base "${{ secrets.R2_BINARIES_PUBLIC_URL }}/binaries/${{ needs.bump-version.outputs.new_tag }}/tauri" \ - --output latest.json - echo "Generated latest.json:" - cat latest.json - - - name: Generate desktop manifest for NPX CLI - run: | - node scripts/generate-desktop-manifest.js \ - --version "${{ needs.bump-version.outputs.new_version }}" \ - --artifacts-dir ./tauri-artifacts \ - --output desktop-manifest.json - echo "Generated desktop-manifest.json:" - cat desktop-manifest.json - - - name: Configure AWS CLI for R2 - run: | - aws configure set aws_access_key_id ${{ secrets.R2_BINARIES_ACCESS_KEY_ID }} - aws configure set aws_secret_access_key ${{ secrets.R2_BINARIES_SECRET_ACCESS_KEY }} - aws configure set default.region auto - - - name: Upload Tauri artifacts and update manifest to R2 - run: | - TAG="${{ needs.bump-version.outputs.new_tag }}" - ENDPOINT="${{ secrets.R2_BINARIES_ENDPOINT }}" - BUCKET="${{ secrets.R2_BINARIES_BUCKET }}" - - # Upload individual platform artifacts - for platform in darwin-aarch64 darwin-x86_64 linux-x86_64 linux-aarch64 windows-x86_64 windows-aarch64; do - if [ -d "tauri-artifacts/$platform" ]; then - for file in tauri-artifacts/$platform/*; do - [ -f "$file" ] || continue - # Skip .sig files from artifact upload (signatures are in latest.json) - [[ "$file" == *.sig ]] && continue - filename=$(basename "$file") - echo "Uploading $filename for $platform..." - aws s3 cp "$file" \ - "s3://$BUCKET/binaries/$TAG/tauri/$platform/$filename" \ - --endpoint-url "$ENDPOINT" - done - fi - done - - # Upload latest.json alongside the tag artifacts (NOT to the fixed - # update endpoint). The fixed endpoint is only updated when a - # pre-release is promoted to a full release (see publish.yml). - echo "Uploading updater manifest for tag..." - aws s3 cp latest.json \ - "s3://$BUCKET/binaries/$TAG/tauri/latest.json" \ - --endpoint-url "$ENDPOINT" --content-type "application/json" - - echo "Update manifest uploaded to: binaries/$TAG/tauri/latest.json" - - # Upload desktop manifest for NPX CLI auto-install - echo "Uploading desktop manifest..." - aws s3 cp desktop-manifest.json \ - "s3://$BUCKET/binaries/$TAG/tauri/desktop-manifest.json" \ - --endpoint-url "$ENDPOINT" --content-type "application/json" - - echo "Desktop manifest uploaded to: binaries/$TAG/tauri/desktop-manifest.json" - - create-prerelease: - needs: [bump-version, build-frontend, upload-to-r2, upload-tauri-update] - runs-on: ubuntu-24.04 - steps: - - uses: actions/checkout@v6 - with: - ref: ${{ needs.bump-version.outputs.new_tag }} - - - name: Download frontend artifact - uses: actions/download-artifact@v7 - with: - name: frontend-dist - path: packages/local-web/dist/ - - - name: Download Tauri artifacts for release - uses: actions/download-artifact@v7 - with: - pattern: tauri-artifacts-* - path: tauri-release/ - merge-multiple: true - - - name: Collect Tauri installers for release - run: | - mkdir -p tauri-installers - find tauri-release \( -name "*.dmg" -o -name "*.AppImage" -o -name "*.deb" -o -name "*.msi" -o -name "*-setup.exe" \) \ - -exec cp {} tauri-installers/ \; - echo "Tauri installers for release:" - ls -la tauri-installers/ 2>/dev/null || echo "No installers found" - - - name: List downloaded artifacts - run: | - echo "Web dist:" - find packages/local-web/dist - - - name: Zip frontend - run: | - mkdir vibe-kanban-${{ needs.bump-version.outputs.new_tag }} - mv packages/local-web/dist vibe-kanban-${{ needs.bump-version.outputs.new_tag }} - zip -r vibe-kanban-${{ needs.bump-version.outputs.new_tag }}.zip vibe-kanban-${{ needs.bump-version.outputs.new_tag }} - - - name: Setup Node for npm pack - uses: ./.github/actions/setup-node - - - name: Install npx-cli dependencies - run: | - cd npx-cli - npm ci - - - name: Build npx-cli TypeScript, inject secrets, and Pack - run: | - cd npx-cli - npm run build - # Replace placeholders in the bundled output - sed -i "s|__R2_PUBLIC_URL__|${{ secrets.R2_BINARIES_PUBLIC_URL }}|g" bin/cli.js - sed -i "s|__BINARY_TAG__|${{ needs.bump-version.outputs.new_tag }}|g" bin/cli.js - npm pack - - - name: Create GitHub Pre-Release - uses: softprops/action-gh-release@153bb8e04406b158c6c84fc1615b65b24149a1fe # v2 - with: - tag_name: ${{ needs.bump-version.outputs.new_tag }} - name: Pre-release ${{ needs.bump-version.outputs.new_tag }} - prerelease: true - generate_release_notes: true - files: | - vibe-kanban-${{ needs.bump-version.outputs.new_tag }}.zip - npx-cli/vibe-kanban-*.tgz - tauri-installers/* diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml deleted file mode 100644 index 9df1f303..00000000 --- a/.github/workflows/publish.yml +++ /dev/null @@ -1,172 +0,0 @@ -name: Publish to npm - -on: - release: - types: [released] - workflow_dispatch: - inputs: - tag_name: - description: "Release tag (e.g., v1.2.3)" - required: true - release_id: - description: "GitHub release ID" - required: true - -concurrency: - group: publish - cancel-in-progress: true - -permissions: - contents: write - packages: write - id-token: write # Required for OIDC trusted publishing - -env: - # Node 22.22.2 regresses `npm install -g npm@...` with - # `Cannot find module 'promise-retry'`. Pin a known-good patch until the - # upstream Node/npm regression is resolved. - NODE_VERSION: 22.22.1 - PNPM_VERSION: 10.13.1 - -jobs: - publish: - runs-on: ubuntu-latest - # Only run for main app releases (not remote-v* tags) that were converted from pre-release - if: github.event.release.prerelease == false && !startsWith(github.event.release.tag_name, 'remote-') - steps: - - uses: actions/checkout@v6 - with: - ref: ${{ github.event.release.tag_name || inputs.tag_name }} - - - name: Setup Node - uses: ./.github/actions/setup-node - - - name: Upgrade npm for OIDC support - run: npm install -g npm@11.12.0 - - - name: Download release assets - uses: actions/github-script@v8 - env: - RELEASE_ID: ${{ inputs.release_id }} - with: - script: | - const fs = require('fs'); - const path = require('path'); - - const releaseId = context.payload.release?.id || process.env.RELEASE_ID; - console.log("releaseId:", releaseId); - - if (!releaseId) { - core.setFailed('No release ID found.'); - return; - } - - const release = await github.rest.repos.getRelease({ - owner: context.repo.owner, - repo: context.repo.repo, - release_id: releaseId - }); - - // Find the .tgz file - const tgzAsset = release.data.assets.find(asset => asset.name.endsWith('.tgz')); - - if (!tgzAsset) { - core.setFailed('No .tgz file found in release assets'); - return; - } - - // Download the asset - const response = await github.rest.repos.getReleaseAsset({ - owner: context.repo.owner, - repo: context.repo.repo, - asset_id: tgzAsset.id, - headers: { - Accept: 'application/octet-stream' - } - }); - - // Save to npx-cli directory - const filePath = path.join('npx-cli', tgzAsset.name); - fs.writeFileSync(filePath, Buffer.from(response.data)); - - console.log(`Downloaded ${tgzAsset.name} to ${filePath}`); - - // Set output for next step - core.setOutput('package-file', filePath); - core.setOutput('package-name', tgzAsset.name); - - - name: Verify package integrity - id: verify - run: | - cd npx-cli - - # List files to confirm download - ls -la *.tgz - - # Verify the package can be read - npm pack --dry-run || echo "Note: This is expected to show differences since we're using the pre-built package" - - # Extract package name from the downloaded file - PACKAGE_FILE=$(ls *.tgz | head -n1) - echo "package-file=$PACKAGE_FILE" >> $GITHUB_OUTPUT - - - name: Publish to npm - run: | - cd npx-cli - - # Publish the exact same package that was tested - PACKAGE_FILE="${{ steps.verify.outputs.package-file }}" - - echo "Publishing $PACKAGE_FILE to npm..." - npm publish "$PACKAGE_FILE" --provenance --access public - - echo "āœ… Successfully published to npm!" - - - name: Update release description - uses: actions/github-script@v8 - env: - RELEASE_ID: ${{ inputs.release_id }} - with: - script: | - const releaseId = context.payload.release?.id || process.env.RELEASE_ID;; - - // Fetch the release to get the current body - const release = await github.rest.repos.getRelease({ - owner: context.repo.owner, - repo: context.repo.repo, - release_id: releaseId - }); - - const currentBody = release.data.body || ''; - await github.rest.repos.updateRelease({ - owner: context.repo.owner, - repo: context.repo.repo, - release_id: releaseId, - body: currentBody + '\n\nāœ… **Published to npm registry**' - }); - - # Promote the tag-specific Tauri update manifest to the fixed endpoint - # so existing desktop app users receive the update notification. - promote-tauri-update: - runs-on: ubuntu-latest - if: github.event.release.prerelease == false && !startsWith(github.event.release.tag_name, 'remote-') - steps: - - name: Configure AWS CLI for R2 - run: | - aws configure set aws_access_key_id ${{ secrets.R2_BINARIES_ACCESS_KEY_ID }} - aws configure set aws_secret_access_key ${{ secrets.R2_BINARIES_SECRET_ACCESS_KEY }} - aws configure set default.region auto - - - name: Copy update manifest to live endpoint - run: | - TAG="${{ github.event.release.tag_name || inputs.tag_name }}" - ENDPOINT="${{ secrets.R2_BINARIES_ENDPOINT }}" - BUCKET="${{ secrets.R2_BINARIES_BUCKET }}" - - echo "Promoting update manifest for $TAG to live endpoint..." - aws s3 cp \ - "s3://$BUCKET/binaries/$TAG/tauri/latest.json" \ - "s3://$BUCKET/binaries/tauri-update/latest.json" \ - --endpoint-url "$ENDPOINT" --content-type "application/json" - - echo "Update manifest promoted: binaries/tauri-update/latest.json" diff --git a/.github/workflows/relay-deploy-dev.yml b/.github/workflows/relay-deploy-dev.yml deleted file mode 100644 index 7f066b95..00000000 --- a/.github/workflows/relay-deploy-dev.yml +++ /dev/null @@ -1,28 +0,0 @@ -name: Relay Deploy Dev - -on: - push: - branches: - - main - paths: - - crates/relay-tunnel/** - workflow_dispatch: - -jobs: - run-relay-deploy: - name: Deploy Relay Dev - runs-on: ubuntu-latest - permissions: - contents: read - steps: - - name: Dispatch dev relay deployment workflow - uses: peter-evans/repository-dispatch@28959ce8df70de7be546dd1250a005dd32156697 # v4.0.1 - with: - token: ${{ secrets.REMOTE_DEPLOYMENT_TOKEN }} - repository: BloopAI/vibe-kanban-remote-deployment - event-type: vibe-kanban-relay-deploy-dev - client-payload: | - { - "ref": "${{ github.ref_name }}", - "sha": "${{ github.sha }}" - } diff --git a/.github/workflows/relay-deploy-prod.yml b/.github/workflows/relay-deploy-prod.yml deleted file mode 100644 index ce2295d5..00000000 --- a/.github/workflows/relay-deploy-prod.yml +++ /dev/null @@ -1,104 +0,0 @@ -name: Deploy Relay Prod - -on: - workflow_dispatch: - inputs: - version_type: - description: "Version bump type" - required: true - default: "patch" - type: choice - options: - - patch - - minor - - major - -concurrency: - group: relay-deploy-${{ github.ref_name }} - cancel-in-progress: true - -permissions: - contents: write - -env: - RUST_TOOLCHAIN: nightly-2025-12-04 - -jobs: - release-and-deploy: - runs-on: ubuntu-latest - steps: - - name: Install cargo-edit - uses: taiki-e/cache-cargo-install-action@34ce5120836e5f9f1508d8713d7fdea0e8facd6f # v3.0.1 - with: - tool: cargo-edit - git: https://github.com/killercup/cargo-edit - rev: 96a3879fe3bafda6d0f943b642997fbf03e235cd # v0.13.9 - - - uses: actions/checkout@v6 - with: - token: ${{ secrets.GITHUB_TOKEN }} - ssh-key: ${{ secrets.DEPLOY_KEY }} - - - name: Determine and update version - id: version - run: | - # Get current version from crates/relay-tunnel/Cargo.toml - current_version=$(grep '^version = ' crates/relay-tunnel/Cargo.toml | head -1 | sed 's/version = "\(.*\)"/\1/') - echo "Current relay-tunnel version: $current_version" - - # Parse version components - IFS='.' read -r major minor patch <<< "$current_version" - - # Bump based on type - case "${{ github.event.inputs.version_type }}" in - major) - major=$((major + 1)) - minor=0 - patch=0 - ;; - minor) - minor=$((minor + 1)) - patch=0 - ;; - patch) - patch=$((patch + 1)) - ;; - esac - - new_version="${major}.${minor}.${patch}" - new_tag="relay-v${new_version}" - - # Update version in crates/relay-tunnel/Cargo.toml - cd crates/relay-tunnel - cargo set-version "$new_version" - cargo update relay-tunnel - cd ../.. - - echo "New version: $new_version" - echo "New tag: $new_tag" - echo "new_version=$new_version" >> $GITHUB_OUTPUT - echo "new_tag=$new_tag" >> $GITHUB_OUTPUT - echo "new_ref=$new_tag" >> $GITHUB_OUTPUT - - - name: Commit changes and create tag - run: | - git config --local user.email "action@github.com" - git config --local user.name "GitHub Action" - git add crates/relay-tunnel/Cargo.toml crates/relay-tunnel/Cargo.lock - git commit -m "chore: bump relay-tunnel version to ${{ steps.version.outputs.new_version }}" - git tag -a ${{ steps.version.outputs.new_tag }} -m "Relay release ${{ steps.version.outputs.new_tag }}" - git push - git push --tags - - - name: Dispatch relay deployment workflow - uses: peter-evans/repository-dispatch@28959ce8df70de7be546dd1250a005dd32156697 # v4.0.1 - with: - token: ${{ secrets.REMOTE_DEPLOYMENT_TOKEN }} - repository: BloopAI/vibe-kanban-remote-deployment - event-type: vibe-kanban-relay-deploy-prod - client-payload: | - { - "ref": "${{ steps.version.outputs.new_ref }}", - "sha": "${{ github.sha }}", - "version": "${{ steps.version.outputs.new_version }}" - } diff --git a/.github/workflows/relay-release.yml b/.github/workflows/relay-release.yml deleted file mode 100644 index 0fbe71ab..00000000 --- a/.github/workflows/relay-release.yml +++ /dev/null @@ -1,22 +0,0 @@ -name: Create Relay Release - -on: - repository_dispatch: - types: [relay-deploy-success] - -jobs: - create-release: - runs-on: ubuntu-latest - permissions: - contents: write - steps: - - name: Create GitHub Release - uses: softprops/action-gh-release@153bb8e04406b158c6c84fc1615b65b24149a1fe # v2 - with: - tag_name: ${{ github.event.client_payload.tag }} - name: ${{ github.event.client_payload.tag }} - generate_release_notes: true - body: | - ## Relay Tunnel Service Release - - Deployed to ${{ github.event.client_payload.environment }} diff --git a/.github/workflows/remote-deploy-dev.yml b/.github/workflows/remote-deploy-dev.yml deleted file mode 100644 index 79a09834..00000000 --- a/.github/workflows/remote-deploy-dev.yml +++ /dev/null @@ -1,29 +0,0 @@ -name: Remote Deploy Dev - -on: - push: - branches: - - main - paths: - - crates/remote/** - - packages/remote-web/** - workflow_dispatch: - -jobs: - run-remote-deploy: - name: Deploy Remote Dev - runs-on: ubuntu-latest - permissions: - contents: read - steps: - - name: Dispatch dev remote deployment workflow - uses: peter-evans/repository-dispatch@28959ce8df70de7be546dd1250a005dd32156697 # v4.0.1 - with: - token: ${{ secrets.REMOTE_DEPLOYMENT_TOKEN }} - repository: BloopAI/vibe-kanban-remote-deployment - event-type: vibe-kanban-remote-deploy-dev - client-payload: | - { - "ref": "${{ github.ref_name }}", - "sha": "${{ github.sha }}" - } diff --git a/.github/workflows/remote-deploy-prod.yml b/.github/workflows/remote-deploy-prod.yml deleted file mode 100644 index 65a6d085..00000000 --- a/.github/workflows/remote-deploy-prod.yml +++ /dev/null @@ -1,112 +0,0 @@ -name: Deploy Remote Prod - -on: - workflow_dispatch: - inputs: - version_type: - description: "Version bump type" - required: true - default: "patch" - type: choice - options: - - patch - - minor - - major - -concurrency: - group: remote-deploy-${{ github.ref_name }} - cancel-in-progress: true - -permissions: - contents: write - -env: - RUST_TOOLCHAIN: nightly-2025-12-04 - -jobs: - release-and-deploy: - runs-on: ubuntu-latest - steps: - - name: Install cargo-edit - uses: taiki-e/cache-cargo-install-action@34ce5120836e5f9f1508d8713d7fdea0e8facd6f # v3.0.1 - with: - tool: cargo-edit - git: https://github.com/killercup/cargo-edit - rev: 96a3879fe3bafda6d0f943b642997fbf03e235cd # v0.13.9 - - - uses: actions/checkout@v6 - with: - token: ${{ secrets.GITHUB_TOKEN }} - ssh-key: ${{ secrets.DEPLOY_KEY }} - - - name: Setup SSH Agent for private dependencies - uses: webfactory/ssh-agent@dc588b651fe13675774614f8e6a936a468676387 # v0.9.0 - with: - ssh-private-key: ${{ secrets.VK_PRIVATE_DEPLOY_KEY }} - - - name: Determine and update version - id: version - run: | - # Get current version from crates/remote/Cargo.toml - current_version=$(grep '^version = ' crates/remote/Cargo.toml | head -1 | sed 's/version = "\(.*\)"/\1/') - echo "Current remote version: $current_version" - - # Parse version components - IFS='.' read -r major minor patch <<< "$current_version" - - # Bump based on type - case "${{ github.event.inputs.version_type }}" in - major) - major=$((major + 1)) - minor=0 - patch=0 - ;; - minor) - minor=$((minor + 1)) - patch=0 - ;; - patch) - patch=$((patch + 1)) - ;; - esac - - new_version="${major}.${minor}.${patch}" - new_tag="remote-v${new_version}" - - # Update version in crates/remote/Cargo.toml - cd crates/remote - cargo set-version "$new_version" - cargo update remote - cd ../.. - - echo "New version: $new_version" - echo "New tag: $new_tag" - echo "new_version=$new_version" >> $GITHUB_OUTPUT - echo "new_tag=$new_tag" >> $GITHUB_OUTPUT - echo "new_ref=$new_tag" >> $GITHUB_OUTPUT - - - name: Stop SSH agent - run: ssh-agent -k - - - name: Commit changes and create tag - run: | - git config --local user.email "action@github.com" - git config --local user.name "GitHub Action" - git add crates/remote/Cargo.toml crates/remote/Cargo.lock - git commit -m "chore: bump remote version to ${{ steps.version.outputs.new_version }}" - git tag -a ${{ steps.version.outputs.new_tag }} -m "Remote release ${{ steps.version.outputs.new_tag }}" - git push - git push --tags - - - name: Dispatch remote deployment workflow - uses: peter-evans/repository-dispatch@28959ce8df70de7be546dd1250a005dd32156697 # v4.0.1 - with: - token: ${{ secrets.REMOTE_DEPLOYMENT_TOKEN }} - repository: BloopAI/vibe-kanban-remote-deployment - event-type: vibe-kanban-remote-deploy-prod - client-payload: | - { - "ref": "${{ steps.version.outputs.new_ref }}", - "sha": "${{ github.sha }}", - "version": "${{ steps.version.outputs.new_version }}" - } diff --git a/.github/workflows/remote-release.yml b/.github/workflows/remote-release.yml deleted file mode 100644 index d61a0a41..00000000 --- a/.github/workflows/remote-release.yml +++ /dev/null @@ -1,22 +0,0 @@ -name: Create Remote Release - -on: - repository_dispatch: - types: [remote-deploy-success] - -jobs: - create-release: - runs-on: ubuntu-latest - permissions: - contents: write - steps: - - name: Create GitHub Release - uses: softprops/action-gh-release@153bb8e04406b158c6c84fc1615b65b24149a1fe # v2 - with: - tag_name: ${{ github.event.client_payload.tag }} - name: ${{ github.event.client_payload.tag }} - generate_release_notes: true - body: | - ## Remote Service Release - - āœ… Deployed to ${{ github.event.client_payload.environment }} diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml deleted file mode 100644 index 3c31b27a..00000000 --- a/.github/workflows/test.yml +++ /dev/null @@ -1,347 +0,0 @@ -name: Test - -on: - pull_request: - branches: - - main - paths-ignore: - - .github/workflows/** - - '!.github/workflows/test.yml' - push: - branches: - - main - workflow_dispatch: - -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: ${{ github.ref != 'refs/heads/main' }} - -env: - CARGO_TERM_COLOR: always - NODE_VERSION: 22 - PNPM_VERSION: 10.13.1 - RUST_TOOLCHAIN: nightly-2025-12-04 - RUNNER_LABEL: &runner_label ubuntu-24.04 - -jobs: - changes: - runs-on: *runner_label - if: github.event_name == 'pull_request' - permissions: - contents: read - pull-requests: read - outputs: - frontend: ${{ steps.filter.outputs.frontend }} - backend: ${{ steps.filter.outputs.backend }} - backend-remote: ${{ steps.filter.outputs['backend-remote'] }} - tauri: ${{ steps.filter.outputs.tauri }} - steps: - - uses: actions/checkout@v6 - - uses: dorny/paths-filter@0bc4621a3135347011ad047f9ecf449bf72ce2bd # v3.0.0 - id: filter - with: - filters: | - frontend: - - 'packages/local-web/**' - - 'packages/web-core/**' - - 'packages/remote-web/**' - - 'packages/ui/**' - - 'shared/**' - - 'scripts/check-i18n.sh' - - 'scripts/check-unused-i18n-keys.mjs' - - 'scripts/check-legacy-frontend-paths.sh' - - 'scripts/legacy-frontend-paths-allowlist.txt' - - 'pnpm-lock.yaml' - - 'pnpm-workspace.yaml' - - 'package.json' - - '.npmrc' - - '.github/workflows/test.yml' - - '.github/actions/**' - backend: - - 'crates/api-types/**' - - 'crates/client-info/**' - - 'crates/db/**' - - 'crates/deployment/**' - - 'crates/desktop-bridge/**' - - 'crates/embedded-ssh/**' - - 'crates/executors/**' - - 'crates/git/**' - - 'crates/git-host/**' - - 'crates/local-deployment/**' - - 'crates/mcp/**' - - 'crates/preview-proxy/**' - - 'crates/relay-client/**' - - 'crates/relay-control/**' - - 'crates/relay-hosts/**' - - 'crates/relay-protocol/**' - - 'crates/relay-tunnel-core/**' - - 'crates/relay-types/**' - - 'crates/relay-webrtc/**' - - 'crates/relay-ws/**' - - 'crates/remote-info/**' - - 'crates/review/**' - - 'crates/server/**' - - 'crates/services/**' - - 'crates/trusted-key-auth/**' - - 'crates/utils/**' - - 'crates/workspace-manager/**' - - 'crates/worktree-manager/**' - - 'crates/ws-bridge/**' - - 'Cargo.toml' - - 'Cargo.lock' - - 'shared/**' - - 'scripts/prepare-db.js' - - 'pnpm-lock.yaml' - - 'package.json' - - 'rustfmt.toml' - - 'rust-toolchain.toml' - - '.cargo/**' - - '.github/workflows/test.yml' - - '.github/actions/**' - backend-remote: - - 'crates/remote/**' - - 'crates/relay-tunnel/**' - - 'crates/relay-tunnel-core/**' - - 'crates/ws-bridge/**' - - 'crates/api-types/**' - - 'crates/relay-types/**' - - 'crates/utils/**' - - 'Cargo.toml' - - 'Cargo.lock' - - 'shared/**' - - 'rustfmt.toml' - - 'rust-toolchain.toml' - - '.cargo/**' - - 'pnpm-lock.yaml' - - 'package.json' - - '.github/workflows/test.yml' - - '.github/actions/**' - tauri: - - 'crates/tauri-app/**' - - 'crates/api-types/**' - - 'crates/client-info/**' - - 'crates/db/**' - - 'crates/deployment/**' - - 'crates/desktop-bridge/**' - - 'crates/embedded-ssh/**' - - 'crates/executors/**' - - 'crates/git/**' - - 'crates/git-host/**' - - 'crates/local-deployment/**' - - 'crates/mcp/**' - - 'crates/preview-proxy/**' - - 'crates/relay-client/**' - - 'crates/relay-control/**' - - 'crates/relay-hosts/**' - - 'crates/relay-protocol/**' - - 'crates/relay-tunnel-core/**' - - 'crates/relay-types/**' - - 'crates/relay-webrtc/**' - - 'crates/relay-ws/**' - - 'crates/remote-info/**' - - 'crates/review/**' - - 'crates/server/**' - - 'crates/services/**' - - 'crates/trusted-key-auth/**' - - 'crates/utils/**' - - 'crates/workspace-manager/**' - - 'crates/worktree-manager/**' - - 'crates/ws-bridge/**' - - 'Cargo.toml' - - 'Cargo.lock' - - 'rustfmt.toml' - - 'rust-toolchain.toml' - - '.cargo/**' - - 'package.json' - - 'pnpm-lock.yaml' - - 'pnpm-workspace.yaml' - - '.npmrc' - - '.github/workflows/test.yml' - - '.github/actions/**' - - frontend-checks: - needs: changes - if: always() && (needs.changes.outputs.frontend == 'true' || needs.changes.result == 'skipped') - runs-on: *runner_label - steps: - - uses: actions/checkout@v6 - - - name: Setup Node - uses: ./.github/actions/setup-node - - - name: Install dependencies - run: pnpm install - - - name: Run frontend checks - env: - NODE_OPTIONS: --max-old-space-size=8192 - run: | - npx concurrently \ - --kill-others-on-fail \ - --names "local:lint,local:fmt,local:build,remote:fmt,remote:build,ui:check,ui:lint,ui:fmt,core:check,core:fmt,i18n,i18n:unused,legacy" \ - --timings \ - "cd packages/local-web && npm run lint" \ - "cd packages/local-web && npm run format:check" \ - "cd packages/local-web && npm run build" \ - "cd packages/remote-web && npm run format:check" \ - "cd packages/remote-web && npm run build" \ - "cd packages/ui && npm run check" \ - "cd packages/ui && npm run lint" \ - "cd packages/ui && npm run format:check" \ - "cd packages/web-core && npm run check" \ - "cd packages/web-core && npm run format:check" \ - "GITHUB_BASE_REF=${{ github.base_ref || 'main' }} ./scripts/check-i18n.sh" \ - "node scripts/check-unused-i18n-keys.mjs" \ - "./scripts/check-legacy-frontend-paths.sh" - - backend-schema-checks: - needs: changes - if: always() && (needs.changes.outputs.backend == 'true' || needs.changes.result == 'skipped') - runs-on: *runner_label - env: - SCCACHE_GHA_ENABLED: "true" - RUSTC_WRAPPER: "sccache" - steps: - - uses: actions/checkout@v6 - - - name: Setup Rust - uses: ./.github/actions/cargo-checks-common-setup - with: - toolchain: ${{ env.RUST_TOOLCHAIN }} - cache-key: backend-schema-checks-${{ runner.os }}-${{ runner.arch }}-${{ env.RUNNER_LABEL }} - setup-node: 'true' - setup-sqlx-cli: 'true' - - - name: Check generated types - run: npm run generate-types:check - - - name: Sqlx checks - run: npm run prepare-db:check - - backend-remote-checks: - needs: changes - if: >- - always() - && (needs.changes.outputs['backend-remote'] == 'true' || needs.changes.result == 'skipped') - && (github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository) - runs-on: *runner_label - env: - SCCACHE_GHA_ENABLED: "true" - RUSTC_WRAPPER: "sccache" - steps: - - uses: actions/checkout@v6 - - - name: Setup Rust - uses: ./.github/actions/cargo-checks-common-setup - with: - toolchain: ${{ env.RUST_TOOLCHAIN }} - components: rustfmt, clippy - cache-key: backend-remote-checks-${{ runner.os }}-${{ runner.arch }}-${{ env.RUNNER_LABEL }} - setup-node: 'true' - setup-sqlx-cli: 'true' - - - name: Setup SSH Agent for private dependencies - uses: webfactory/ssh-agent@dc588b651fe13675774614f8e6a936a468676387 # v0.9.0 - with: - ssh-private-key: ${{ secrets.VK_PRIVATE_DEPLOY_KEY }} - - - name: Check remote Cargo.lock is consistent - run: | - cargo metadata --locked --format-version 1 --manifest-path crates/remote/Cargo.toml > /dev/null - cargo metadata --locked --format-version 1 --manifest-path crates/relay-tunnel/Cargo.toml > /dev/null - - - name: Check formatting - run: | - cargo fmt --all --manifest-path crates/remote/Cargo.toml -- --check - cargo fmt --all --manifest-path crates/relay-tunnel/Cargo.toml -- --check - - - name: Run Clippy - run: | - cargo clippy --all-targets --manifest-path crates/remote/Cargo.toml -- -D warnings - cargo clippy --all-targets --manifest-path crates/relay-tunnel/Cargo.toml -- -D warnings - - - name: Check generated types - run: npm run remote:generate-types:check - - - name: Sqlx checks - run: npm run remote:prepare-db:check - - backend-clippy: - needs: changes - if: always() && (needs.changes.outputs.backend == 'true' || needs.changes.result == 'skipped') - runs-on: *runner_label - env: - SCCACHE_GHA_ENABLED: "true" - RUSTC_WRAPPER: "sccache" - steps: - - uses: actions/checkout@v6 - - - name: Setup Rust - uses: ./.github/actions/cargo-checks-common-setup - with: - toolchain: ${{ env.RUST_TOOLCHAIN }} - components: rustfmt, clippy - cache-key: backend-clippy-${{ runner.os }}-${{ runner.arch }}-${{ env.RUNNER_LABEL }} - - - name: Run Clippy and fmt checks - run: | - set -x - cargo fmt --all -- --check & pid_fmt=$! - cargo clippy --workspace --all-targets --exclude vibe-kanban-tauri -- -D warnings - wait $pid_fmt - - backend-test: - needs: changes - if: always() && (needs.changes.outputs.backend == 'true' || needs.changes.result == 'skipped') - runs-on: *runner_label - env: - SCCACHE_GHA_ENABLED: "true" - RUSTC_WRAPPER: "sccache" - steps: - - uses: actions/checkout@v6 - - - name: Setup Rust - uses: ./.github/actions/cargo-checks-common-setup - with: - toolchain: ${{ env.RUST_TOOLCHAIN }} - cache-key: backend-test-${{ runner.os }}-${{ runner.arch }}-${{ env.RUNNER_LABEL }} - - - name: Install cargo-nextest - uses: taiki-e/cache-cargo-install-action@34ce5120836e5f9f1508d8713d7fdea0e8facd6f # v3.0.1 - with: - tool: cargo-nextest - git: https://github.com/nextest-rs/nextest - rev: 6e4a9d6f2c4964f30ff54a8cd5466f8869267daa # cargo-nextest-0.9.132 - - - name: Run Cargo tests - run: cargo nextest run --workspace --exclude vibe-kanban-tauri - - tauri-checks: - needs: changes - if: always() && (needs.changes.outputs.tauri == 'true' || needs.changes.result == 'skipped') - runs-on: *runner_label - env: - SCCACHE_GHA_ENABLED: "true" - RUSTC_WRAPPER: "sccache" - steps: - - uses: actions/checkout@v6 - - - name: Setup Rust - uses: ./.github/actions/cargo-checks-common-setup - with: - toolchain: ${{ env.RUST_TOOLCHAIN }} - components: rustfmt, clippy - cache-key: tauri-checks-${{ runner.os }}-${{ runner.arch }}-${{ env.RUNNER_LABEL }} - - - name: Install Linux dependencies - run: | - sudo apt-get update - sudo apt-get install -y libwebkit2gtk-4.1-dev build-essential \ - libssl-dev libayatana-appindicator3-dev librsvg2-dev \ - libxdo-dev file pkg-config xdg-utils - - - name: Run Tauri fmt, clippy, and compile checks - run: | - cargo fmt --all --manifest-path crates/tauri-app/Cargo.toml -- --check - cargo clippy --all-targets --manifest-path crates/tauri-app/Cargo.toml -- -D warnings - cargo check -p vibe-kanban-tauri