fix(mobile): address F-Droid review — forky node, module subdir, drop… #194
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
| # .github/workflows/guardian.yml | |
| # | |
| # Sidecoin Monorepo CI Suite | |
| # Runs on every push/PR to master across all packages. | |
| # | |
| # IMPORTANT: All cargo commands use --locked to ensure deterministic | |
| # builds from the committed Cargo.lock. Without --locked, Cargo may | |
| # resolve newer transitive dependencies (e.g. tauri-runtime) that | |
| # introduce breaking trait changes and fail compilation. | |
| name: Sidecoin CI Suite | |
| on: | |
| push: | |
| branches: ["master"] | |
| pull_request: | |
| branches: ["master"] | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.ref }} | |
| cancel-in-progress: true | |
| # Force any remaining JavaScript actions onto the Node.js 24 runtime. | |
| # After replacing pnpm/action-setup (corepack) and wrangler-action | |
| # (npx wrangler) below, the only Node-20 action left is the transitive | |
| # actions/github-script pulled in by codecov-action — which we cannot | |
| # version-pin directly. This flag keeps it running on Node 24 so it does | |
| # not break after the Sept 16 2026 Node-20 removal. Drop once codecov | |
| # ships a Node 24 release. | |
| env: | |
| FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: "true" | |
| jobs: | |
| guardian: | |
| name: desktop-client (${{ matrix.platform }}) | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| platform: [ubuntu-latest, macos-latest, windows-latest] | |
| runs-on: ${{ matrix.platform }} | |
| env: | |
| WEBVIEW2_LINK_STATIC: "1" | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v5 | |
| with: | |
| fetch-depth: 0 | |
| - name: Enable Corepack | |
| run: corepack enable | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v5 | |
| with: | |
| node-version: "22" | |
| cache: "pnpm" | |
| - name: Setup Rust | |
| uses: dtolnay/rust-toolchain@stable | |
| with: | |
| components: clippy, rustfmt, llvm-tools-preview | |
| - name: Install cargo-llvm-cov | |
| uses: taiki-e/install-action@cargo-llvm-cov | |
| - name: Rust Cache | |
| uses: Swatinem/rust-cache@v2 | |
| with: | |
| key: ${{ runner.os }}-v2 | |
| workspaces: "./apps/desktop/src-tauri -> target" | |
| - name: Install Linux dependencies | |
| if: matrix.platform == 'ubuntu-latest' | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y \ | |
| libwebkit2gtk-4.1-dev \ | |
| libappindicator3-dev \ | |
| librsvg2-dev \ | |
| patchelf \ | |
| xvfb \ | |
| webkit2gtk-driver | |
| cargo install tauri-driver | |
| - name: Install Frontend dependencies | |
| run: pnpm install --frozen-lockfile | |
| # ── Shared ────────────────────────────────────────────── | |
| - name: Type-check Shared | |
| run: pnpm --filter @sidecoin/shared build | |
| # ── Desktop — Placeholder Dist ────────────────────────── | |
| # | |
| # Tauri's generate_context!() proc macro validates that | |
| # frontendDist ("../dist") exists at compile time. This | |
| # placeholder must exist BEFORE any cargo command that | |
| # compiles the Tauri app (clippy, build, llvm-cov, etc.). | |
| # It is replaced by the real frontend build later. | |
| # ──────────────────────────────────────────────────────── | |
| - name: Create Placeholder Dist | |
| shell: bash | |
| run: mkdir -p apps/desktop/dist && touch apps/desktop/dist/index.html | |
| # ── Desktop — Rust Quality Gates ──────────────────────── | |
| - name: Check Rust Formatting | |
| working-directory: apps/desktop/src-tauri | |
| run: cargo fmt --all -- --check | |
| - name: Clippy Lint | |
| working-directory: apps/desktop/src-tauri | |
| run: cargo clippy --locked --all-features --lib -- -D warnings | |
| # ── Desktop — Build ───────────────────────────────────── | |
| - name: Generate Types (Specta) | |
| shell: bash | |
| working-directory: apps/desktop/src-tauri | |
| run: | | |
| cargo run --locked --bin export_types | |
| node -e " | |
| const fs = require('fs'); | |
| const path = require('path'); | |
| const f = path.join('..', 'src', 'bindings.ts'); | |
| if (fs.existsSync(f)) { | |
| const content = fs.readFileSync(f, 'utf8'); | |
| if (!content.startsWith('//@ts-nocheck')) { | |
| fs.writeFileSync(f, '//@ts-nocheck\n' + content); | |
| } | |
| } | |
| " | |
| - name: Build Desktop Frontend | |
| run: pnpm --filter @sidecoin/desktop exec vite build | |
| - name: Build Tauri App | |
| working-directory: apps/desktop/src-tauri | |
| run: cargo build --locked | |
| # ── Desktop — Tests ───────────────────────────────────── | |
| - name: Run Rust Unit Tests (with coverage) | |
| if: matrix.platform != 'windows-latest' | |
| working-directory: apps/desktop/src-tauri | |
| shell: bash | |
| run: cargo llvm-cov --locked --all-features --lib --lcov --output-path lcov-rust.info | |
| - name: Run Desktop Frontend Tests | |
| run: pnpm --filter @sidecoin/desktop test | |
| - name: Run Desktop Type Check | |
| run: pnpm --filter @sidecoin/desktop exec vue-tsc --noEmit --skipLibCheck | |
| # ── Desktop — E2E ─────────────────────────────────────── | |
| - name: Run E2E Tests | |
| if: matrix.platform == 'ubuntu-latest' | |
| continue-on-error: true | |
| env: | |
| CI: true | |
| GDK_BACKEND: x11 | |
| WEBKIT_DISABLE_COMPOSITING_MODE: "1" | |
| shell: bash | |
| run: xvfb-run --auto-servernum pnpm --filter @sidecoin/desktop test:e2e | |
| # ── Coverage Upload ───────────────────────────────────── | |
| - name: Verify coverage file exists | |
| if: matrix.platform == 'ubuntu-latest' | |
| working-directory: apps/desktop/src-tauri | |
| shell: bash | |
| run: | | |
| if [ -f lcov-rust.info ]; then | |
| echo "✅ Coverage file found ($(wc -l < lcov-rust.info) lines)" | |
| head -5 lcov-rust.info | |
| else | |
| echo "❌ Coverage file NOT found" | |
| ls -la | |
| exit 1 | |
| fi | |
| - name: Upload Rust Coverage | |
| if: matrix.platform == 'ubuntu-latest' | |
| uses: codecov/codecov-action@v5 | |
| with: | |
| files: apps/desktop/src-tauri/lcov-rust.info | |
| flags: rust | |
| fail_ci_if_error: false | |
| verbose: true | |
| token: ${{ secrets.CODECOV_TOKEN }} | |
| - name: Upload Desktop Frontend Coverage | |
| if: matrix.platform == 'ubuntu-latest' | |
| uses: codecov/codecov-action@v5 | |
| with: | |
| files: apps/desktop/coverage/lcov.info | |
| flags: desktop-frontend | |
| fail_ci_if_error: false | |
| verbose: true | |
| token: ${{ secrets.CODECOV_TOKEN }} | |
| # ── Wallet (standalone, labeled job) ───────────────────── | |
| # | |
| # Pure TS/Vite — runs once on ubuntu (no Rust/matrix needed). | |
| # Appears as its own "wallet" entry in the Actions sidebar so | |
| # a failure here is immediately distinguishable from the | |
| # desktop/web/mobile/api legs. Builds @sidecoin/shared first | |
| # (wallet depends on it). deploy-wallet gates on this job. | |
| # | |
| # Test runs with --coverage.reporter=lcov so the v8 provider | |
| # emits coverage/lcov.info for the Codecov upload below. lcov | |
| # is NOT a default vitest reporter, so it must be requested | |
| # explicitly on the CLI (keeps local `pnpm test` coverage-free). | |
| # The `--` separator forwards the flags to vitest rather than | |
| # letting pnpm try to parse them as its own options. | |
| # ───────────────────────────────────────────────────────── | |
| wallet: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v5 | |
| - name: Enable Corepack | |
| run: corepack enable | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v5 | |
| with: | |
| node-version: "22" | |
| cache: "pnpm" | |
| - name: Install dependencies | |
| run: pnpm install --frozen-lockfile | |
| - name: Build Shared | |
| run: pnpm --filter @sidecoin/shared build | |
| - name: Build Wallet | |
| run: pnpm --filter @sidecoin/wallet build | |
| - name: Test Wallet | |
| run: pnpm --filter @sidecoin/wallet test -- --coverage --coverage.reporter=lcov | |
| - name: Type-check Wallet | |
| run: pnpm --filter @sidecoin/wallet type-check | |
| - name: Upload Wallet Coverage | |
| uses: codecov/codecov-action@v5 | |
| with: | |
| files: apps/wallet/coverage/lcov.info | |
| flags: wallet | |
| fail_ci_if_error: false | |
| verbose: true | |
| token: ${{ secrets.CODECOV_TOKEN }} | |
| # ── Mobile (standalone, labeled job) ───────────────────── | |
| # | |
| # React Native / Jest — runs once on ubuntu (no Rust/matrix | |
| # needed). Appears as its own "mobile" entry in the Actions | |
| # sidebar so a failure here is immediately distinguishable | |
| # from the desktop/web/api legs. | |
| # | |
| # Builds @sidecoin/shared first: the App test imports | |
| # @sidecoin/shared/chain and @sidecoin/shared/sidechains. | |
| # ───────────────────────────────────────────────────────── | |
| mobile: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v5 | |
| - name: Enable Corepack | |
| run: corepack enable | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v5 | |
| with: | |
| node-version: "22" | |
| cache: "pnpm" | |
| - name: Install dependencies | |
| run: pnpm install --frozen-lockfile | |
| - name: Build Shared | |
| run: pnpm --filter @sidecoin/shared build | |
| - name: Test Mobile | |
| run: pnpm --filter @sidecoin/mobile test | |
| # ── Web — Landing Site (standalone, labeled job) ───────── | |
| # | |
| # Pure TS/Vite — runs once on ubuntu. Appears as its own | |
| # "web" entry in the Actions sidebar. Builds @sidecoin/shared | |
| # first (web depends on it), then builds + tests the site. | |
| # deploy-web gates on this job. | |
| # ───────────────────────────────────────────────────────── | |
| web: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v5 | |
| - name: Enable Corepack | |
| run: corepack enable | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v5 | |
| with: | |
| node-version: "22" | |
| cache: "pnpm" | |
| - name: Install dependencies | |
| run: pnpm install --frozen-lockfile | |
| - name: Build Shared | |
| run: pnpm --filter @sidecoin/shared build | |
| - name: Build Web | |
| run: pnpm --filter @sidecoin/web build | |
| - name: Test Web | |
| run: pnpm --filter @sidecoin/web test | |
| # ── Explorer — Chain-aware Block Explorer (standalone, labeled job) ── | |
| # | |
| # Pure TS/Vite/Vue — runs once on ubuntu. Appears as its own | |
| # "explorer" entry in the Actions sidebar so explorer regressions | |
| # are immediately distinguishable from wallet/web/api failures. | |
| # Builds @sidecoin/shared first for consistency with other frontend | |
| # packages, then builds + tests + type-checks the explorer app. | |
| # Deployment is intentionally added in a separate commit. | |
| # ───────────────────────────────────────────────────────── | |
| explorer: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v5 | |
| - name: Enable Corepack | |
| run: corepack enable | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v5 | |
| with: | |
| node-version: "22" | |
| cache: "pnpm" | |
| - name: Install dependencies | |
| run: pnpm install --frozen-lockfile | |
| - name: Build Shared | |
| run: pnpm --filter @sidecoin/shared build | |
| - name: Build Explorer | |
| run: pnpm --filter @sidecoin/explorer build | |
| - name: Test Explorer | |
| run: pnpm --filter @sidecoin/explorer test -- --coverage --coverage.reporter=lcov | |
| - name: Type-check Explorer | |
| run: pnpm --filter @sidecoin/explorer type-check | |
| - name: Upload Explorer Coverage | |
| uses: codecov/codecov-action@v5 | |
| with: | |
| files: apps/explorer/coverage/lcov.info | |
| flags: explorer | |
| fail_ci_if_error: false | |
| verbose: true | |
| token: ${{ secrets.CODECOV_TOKEN }} | |
| # ── Smart Hub — Secure Portal Challenge (standalone, labeled job) ── | |
| # | |
| # Pure TS/Vite/Vue — runs once on ubuntu. Appears as its own | |
| # "smarthub" entry in the Actions sidebar so portal regressions | |
| # are immediately distinguishable from wallet/web/explorer/api failures. | |
| # Builds + tests + type-checks the Smart Hub landing page. | |
| # deploy-smarthub gates on this job. | |
| # ───────────────────────────────────────────────────────── | |
| smarthub: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v5 | |
| - name: Enable Corepack | |
| run: corepack enable | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v5 | |
| with: | |
| node-version: "22" | |
| cache: "pnpm" | |
| - name: Install dependencies | |
| run: pnpm install --frozen-lockfile | |
| - name: Build Smart Hub | |
| run: pnpm --filter @sidecoin/smarthub build | |
| - name: Test Smart Hub | |
| run: pnpm --filter @sidecoin/smarthub test -- --coverage --coverage.reporter=lcov | |
| - name: Type-check Smart Hub | |
| run: pnpm --filter @sidecoin/smarthub type-check | |
| - name: Upload Smart Hub Coverage | |
| uses: codecov/codecov-action@v5 | |
| with: | |
| files: apps/smarthub/coverage/lcov.info | |
| flags: smarthub | |
| fail_ci_if_error: false | |
| verbose: true | |
| token: ${{ secrets.CODECOV_TOKEN }} | |
| # ── API client (standalone, labeled job) ───────────────── | |
| # | |
| # Pure TS — runs once on ubuntu (no Rust/matrix needed). | |
| # Appears as its own "api" entry in the Actions sidebar so | |
| # a failure here is immediately distinguishable from the | |
| # desktop/web/wallet legs. Each named step (Test/Type-check) | |
| # pinpoints exactly which check broke. | |
| # | |
| # NOTE: the API adapter (formerly @sidecoin/api, the Cloudflare | |
| # Worker) has been extracted to its own repository: | |
| # https://github.com/APECSdev/sidecoin-api — it is no longer | |
| # built or deployed from this monorepo. This job now covers only | |
| # the @sidecoin/api-client package that remains here. | |
| # ───────────────────────────────────────────────────────── | |
| api: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v5 | |
| - name: Enable Corepack | |
| run: corepack enable | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v5 | |
| with: | |
| node-version: "22" | |
| cache: "pnpm" | |
| - name: Install dependencies | |
| run: pnpm install --frozen-lockfile | |
| - name: Test API client | |
| run: pnpm --filter @sidecoin/api-client test | |
| - name: Type-check API client | |
| run: pnpm --filter @sidecoin/api-client typecheck | |
| # ── Cloudflare Pages — Landing Site ────────────────────── | |
| # | |
| # Deploys on every push to master after all CI jobs pass. | |
| # PRs do NOT deploy — only merged commits to master. | |
| # ───────────────────────────────────────────────────────── | |
| deploy-web: | |
| needs: web | |
| if: github.event_name == 'push' && github.ref == 'refs/heads/master' | |
| runs-on: ubuntu-latest | |
| environment: | |
| name: production-web | |
| url: https://sidecoin.app | |
| steps: | |
| - uses: actions/checkout@v5 | |
| - name: Enable Corepack | |
| run: corepack enable | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v5 | |
| with: | |
| node-version: "22" | |
| cache: "pnpm" | |
| - name: Install dependencies | |
| run: pnpm install --frozen-lockfile | |
| - name: Build Shared | |
| run: pnpm --filter @sidecoin/shared build | |
| - name: Build Web | |
| run: pnpm --filter @sidecoin/web build | |
| - name: Deploy to Cloudflare Pages | |
| run: npx wrangler pages deploy apps/web/dist --project-name=sidecoin --commit-dirty=true | |
| env: | |
| CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }} | |
| CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} | |
| # ── Cloudflare Pages — Wallet App ──────────────────────── | |
| deploy-wallet: | |
| needs: wallet | |
| if: github.event_name == 'push' && github.ref == 'refs/heads/master' | |
| runs-on: ubuntu-latest | |
| environment: | |
| name: production-wallet | |
| url: https://wallet.sidecoin.app | |
| steps: | |
| - uses: actions/checkout@v5 | |
| - name: Enable Corepack | |
| run: corepack enable | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v5 | |
| with: | |
| node-version: "22" | |
| cache: "pnpm" | |
| - name: Install dependencies | |
| run: pnpm install --frozen-lockfile | |
| - name: Build Shared | |
| run: pnpm --filter @sidecoin/shared build | |
| - name: Build Wallet | |
| run: pnpm --filter @sidecoin/wallet build | |
| - name: Deploy to Cloudflare Pages | |
| run: npx wrangler pages deploy apps/wallet/dist --project-name=sidecoin-wallet --commit-dirty=true | |
| env: | |
| CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }} | |
| CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} | |
| # ── Cloudflare Pages — Explorer App ────────────────────── | |
| deploy-explorer: | |
| needs: explorer | |
| if: github.event_name == 'push' && github.ref == 'refs/heads/master' | |
| runs-on: ubuntu-latest | |
| environment: | |
| name: production-explorer | |
| url: https://explorer.sidecoin.app | |
| steps: | |
| - uses: actions/checkout@v5 | |
| - name: Enable Corepack | |
| run: corepack enable | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v5 | |
| with: | |
| node-version: "22" | |
| cache: "pnpm" | |
| - name: Install dependencies | |
| run: pnpm install --frozen-lockfile | |
| - name: Build Shared | |
| run: pnpm --filter @sidecoin/shared build | |
| - name: Build Explorer | |
| run: pnpm --filter @sidecoin/explorer build | |
| - name: Deploy to Cloudflare Pages | |
| run: npx wrangler pages deploy apps/explorer/dist --project-name=sidecoin-explorer --commit-dirty=true | |
| env: | |
| CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }} | |
| CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} | |
| # ── Cloudflare Pages — Smart Hub ───────────────────────── | |
| deploy-smarthub: | |
| needs: smarthub | |
| if: github.event_name == 'push' && github.ref == 'refs/heads/master' | |
| runs-on: ubuntu-latest | |
| environment: | |
| name: production-smarthub | |
| url: https://hub.sidecoin.app | |
| steps: | |
| - uses: actions/checkout@v5 | |
| - name: Enable Corepack | |
| run: corepack enable | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v5 | |
| with: | |
| node-version: "22" | |
| cache: "pnpm" | |
| - name: Install dependencies | |
| run: pnpm install --frozen-lockfile | |
| - name: Build Smart Hub | |
| run: pnpm --filter @sidecoin/smarthub build | |
| - name: Deploy to Cloudflare Pages | |
| run: npx wrangler pages deploy apps/smarthub/dist --project-name=sidecoin-hub --commit-dirty=true | |
| env: | |
| CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }} | |
| CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} |