Add settings, source, and instance authoring workflows #291
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: CI | |
| on: | |
| pull_request: | |
| push: | |
| branches: | |
| - main | |
| workflow_dispatch: | |
| permissions: {} | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} | |
| cancel-in-progress: ${{ github.event_name == 'pull_request' }} | |
| env: | |
| CARGO_INCREMENTAL: 0 | |
| CARGO_PROFILE_TEST_DEBUG: 0 | |
| RUSTFLAGS: "-D warnings" | |
| jobs: | |
| # --------------------------------------------------------------------------- | |
| # Gate: detect which parts of the monorepo changed | |
| # --------------------------------------------------------------------------- | |
| detect-changes: | |
| name: Detect Changes | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| pull-requests: read | |
| outputs: | |
| rust: ${{ steps.filter.outputs.rust }} | |
| typescript: ${{ steps.filter.outputs.typescript }} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 1 | |
| - uses: dorny/paths-filter@v3 | |
| id: filter | |
| with: | |
| filters: | | |
| rust: | |
| - 'crates/**' | |
| - 'Cargo.toml' | |
| - 'Cargo.lock' | |
| - 'rust-toolchain.toml' | |
| typescript: | |
| - 'apps/**' | |
| - 'packages/**' | |
| - 'pnpm-lock.yaml' | |
| - 'tsconfig*.json' | |
| - 'turbo.json' | |
| # --------------------------------------------------------------------------- | |
| # TypeScript jobs (no submodules needed) | |
| # --------------------------------------------------------------------------- | |
| lint: | |
| name: Lint | |
| needs: detect-changes | |
| if: needs.detect-changes.outputs.typescript == 'true' | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 1 | |
| - uses: pnpm/action-setup@v4 | |
| - uses: actions/setup-node@v4 | |
| with: | |
| node-version: 20 | |
| cache: pnpm | |
| - name: Cache node_modules | |
| id: modules-cache | |
| uses: actions/cache@v4 | |
| with: | |
| path: | | |
| node_modules | |
| apps/*/node_modules | |
| packages/*/node_modules | |
| crates/*/node_modules | |
| key: node-modules-v2-${{ runner.os }}-${{ hashFiles('pnpm-lock.yaml') }} | |
| - name: Install dependencies | |
| run: pnpm install --frozen-lockfile --prefer-offline | |
| - name: Lint (oxlint) | |
| run: pnpm test:lint | |
| - name: Format check (oxfmt) | |
| run: pnpm format:check | |
| typecheck: | |
| name: Typecheck | |
| needs: detect-changes | |
| if: needs.detect-changes.outputs.typescript == 'true' | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 1 | |
| - uses: pnpm/action-setup@v4 | |
| - uses: actions/setup-node@v4 | |
| with: | |
| node-version: 20 | |
| cache: pnpm | |
| - name: Cache node_modules | |
| id: modules-cache | |
| uses: actions/cache@v4 | |
| with: | |
| path: | | |
| node_modules | |
| apps/*/node_modules | |
| packages/*/node_modules | |
| crates/*/node_modules | |
| key: node-modules-v2-${{ runner.os }}-${{ hashFiles('pnpm-lock.yaml') }} | |
| - name: Install dependencies | |
| run: pnpm install --frozen-lockfile --prefer-offline | |
| - uses: Swatinem/rust-cache@v2 | |
| with: | |
| shared-key: shift-rust | |
| - name: Typecheck | |
| run: pnpm typecheck | |
| unit-test: | |
| name: Unit Tests | |
| needs: detect-changes | |
| if: needs.detect-changes.outputs.typescript == 'true' | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 1 | |
| - uses: pnpm/action-setup@v4 | |
| - uses: actions/setup-node@v4 | |
| with: | |
| node-version: 20 | |
| cache: pnpm | |
| - name: Cache node_modules | |
| id: modules-cache | |
| uses: actions/cache@v4 | |
| with: | |
| path: | | |
| node_modules | |
| apps/*/node_modules | |
| packages/*/node_modules | |
| crates/*/node_modules | |
| key: node-modules-v2-${{ runner.os }}-${{ hashFiles('pnpm-lock.yaml') }} | |
| - name: Install dependencies | |
| run: pnpm install --frozen-lockfile --prefer-offline | |
| - uses: Swatinem/rust-cache@v2 | |
| with: | |
| shared-key: shift-rust | |
| - name: Cache native module binary | |
| id: native-cache | |
| uses: actions/cache@v4 | |
| with: | |
| path: crates/shift-bridge/*.node | |
| key: native-module-${{ runner.os }}-${{ hashFiles('crates/**', 'Cargo.lock') }} | |
| - name: Build native module | |
| if: steps.native-cache.outputs.cache-hit != 'true' | |
| run: pnpm build:native | |
| - name: Run unit tests | |
| run: pnpm test:unit | |
| deadcode: | |
| name: Dead Code | |
| needs: detect-changes | |
| if: needs.detect-changes.outputs.typescript == 'true' | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 1 | |
| - uses: pnpm/action-setup@v4 | |
| - uses: actions/setup-node@v4 | |
| with: | |
| node-version: 20 | |
| cache: pnpm | |
| - name: Cache node_modules | |
| id: modules-cache | |
| uses: actions/cache@v4 | |
| with: | |
| path: | | |
| node_modules | |
| apps/*/node_modules | |
| packages/*/node_modules | |
| crates/*/node_modules | |
| key: node-modules-v2-${{ runner.os }}-${{ hashFiles('pnpm-lock.yaml') }} | |
| - name: Install dependencies | |
| run: pnpm install --frozen-lockfile --prefer-offline | |
| - name: Dead code check (knip) | |
| run: pnpm deadcode:strict | |
| # --------------------------------------------------------------------------- | |
| # Rust jobs (toolchain pinned via rust-toolchain.toml) | |
| # --------------------------------------------------------------------------- | |
| rust-fmt: | |
| name: Rust Format | |
| needs: detect-changes | |
| if: needs.detect-changes.outputs.rust == 'true' | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 1 | |
| - name: Install toolchain | |
| run: rustup show | |
| - name: Check formatting | |
| run: cargo fmt --all --check | |
| rust-check: | |
| name: Rust Clippy & Tests | |
| needs: detect-changes | |
| if: needs.detect-changes.outputs.rust == 'true' | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 1 | |
| submodules: true | |
| - name: Install toolchain | |
| run: rustup show | |
| - uses: Swatinem/rust-cache@v2 | |
| with: | |
| save-if: ${{ github.ref == 'refs/heads/main' }} | |
| shared-key: shift-rust | |
| - name: Run clippy | |
| run: cargo clippy --workspace --all-targets -- -D warnings | |
| - name: Run tests | |
| run: cargo test --workspace --exclude shift-bridge | |
| integration: | |
| name: Integration Tests | |
| needs: detect-changes | |
| if: needs.detect-changes.outputs.rust == 'true' | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 1 | |
| submodules: true | |
| - uses: pnpm/action-setup@v4 | |
| - uses: actions/setup-node@v4 | |
| with: | |
| node-version: 20 | |
| cache: pnpm | |
| - name: Install toolchain | |
| run: rustup show | |
| - uses: Swatinem/rust-cache@v2 | |
| with: | |
| save-if: ${{ github.ref == 'refs/heads/main' }} | |
| shared-key: shift-rust | |
| - name: Cache node_modules | |
| id: modules-cache | |
| uses: actions/cache@v4 | |
| with: | |
| path: | | |
| node_modules | |
| apps/*/node_modules | |
| packages/*/node_modules | |
| crates/*/node_modules | |
| key: node-modules-v2-${{ runner.os }}-${{ hashFiles('pnpm-lock.yaml') }} | |
| - name: Install dependencies | |
| run: pnpm install --frozen-lockfile --prefer-offline | |
| - name: Build native module | |
| run: pnpm build:native | |
| - name: Run shift-bridge tests | |
| run: pnpm test:native | |
| # --------------------------------------------------------------------------- | |
| # Optional / manual jobs | |
| # --------------------------------------------------------------------------- | |
| playwright: | |
| name: Playwright (Manual) | |
| if: github.event_name == 'workflow_dispatch' | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 1 | |
| submodules: true | |
| - uses: pnpm/action-setup@v4 | |
| - uses: actions/setup-node@v4 | |
| with: | |
| node-version: 20 | |
| cache: pnpm | |
| - name: Install toolchain | |
| run: rustup show | |
| - uses: Swatinem/rust-cache@v2 | |
| with: | |
| shared-key: shift-rust | |
| - name: Cache node_modules | |
| id: modules-cache | |
| uses: actions/cache@v4 | |
| with: | |
| path: | | |
| node_modules | |
| apps/*/node_modules | |
| packages/*/node_modules | |
| crates/*/node_modules | |
| key: node-modules-v2-${{ runner.os }}-${{ hashFiles('pnpm-lock.yaml') }} | |
| - name: Install dependencies | |
| run: pnpm install --frozen-lockfile --prefer-offline | |
| - name: Cache Playwright browsers | |
| id: playwright-cache | |
| uses: actions/cache@v4 | |
| with: | |
| path: ~/.cache/ms-playwright | |
| key: playwright-${{ runner.os }}-${{ hashFiles('apps/desktop/node_modules/@playwright/test/package.json') }} | |
| - name: Install Playwright browsers | |
| if: steps.playwright-cache.outputs.cache-hit != 'true' | |
| run: pnpm --filter @shift/desktop exec playwright install | |
| - name: Cache native module binary | |
| id: native-cache | |
| uses: actions/cache@v4 | |
| with: | |
| path: crates/shift-bridge/*.node | |
| key: native-module-${{ runner.os }}-${{ hashFiles('crates/**', 'Cargo.lock') }} | |
| - name: Build native module | |
| if: steps.native-cache.outputs.cache-hit != 'true' | |
| run: pnpm build:native | |
| - name: Run Playwright tests | |
| run: xvfb-run pnpm test:playwright | |
| env: | |
| LIBGL_ALWAYS_SOFTWARE: "true" | |
| - name: Upload snapshots on failure | |
| if: failure() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: playwright-results | |
| path: apps/desktop/e2e/test-results/ | |
| retention-days: 7 | |
| # --------------------------------------------------------------------------- | |
| # Gate: all required checks must pass | |
| # --------------------------------------------------------------------------- | |
| ci-passed: | |
| name: CI Passed | |
| if: always() | |
| needs: | |
| - detect-changes | |
| - lint | |
| - typecheck | |
| - unit-test | |
| - deadcode | |
| - rust-fmt | |
| - rust-check | |
| - integration | |
| runs-on: ubuntu-latest | |
| permissions: {} | |
| steps: | |
| - name: Check required jobs | |
| run: | | |
| echo "Results: ${{ toJSON(needs.*.result) }}" | |
| if [[ "${{ contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled') }}" == "true" ]]; then | |
| echo "One or more required jobs failed or were cancelled." | |
| exit 1 | |
| fi | |
| echo "All required checks passed." |