Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
193 changes: 184 additions & 9 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,49 @@ on:
- main
pull_request:

concurrency:
group: ci-${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

env:
CARGO_INCREMENTAL: "0"

jobs:
ci:
rust:
name: Rust lint and unit tests
runs-on: macos-latest

steps:
- uses: actions/checkout@v4

- uses: dtolnay/rust-toolchain@stable
with:
components: rustfmt, clippy

- name: Cache Rust build outputs
uses: actions/cache@v4
with:
path: |
~/.cargo/git
~/.cargo/registry
server/target
key: rust-${{ runner.os }}-${{ hashFiles('server/Cargo.lock', 'server/Cargo.toml', 'server/build.rs', 'server/src/**/*.rs', 'cli/**/*.m') }}
restore-keys: |
rust-${{ runner.os }}-

- name: Check Rust formatting
run: cargo fmt --manifest-path server/Cargo.toml --check

- name: Clippy
run: cargo clippy --manifest-path server/Cargo.toml --all-targets -- -D warnings

- name: Rust unit tests
run: cargo test --manifest-path server/Cargo.toml

client:
name: Client lint, build, and tests
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4

Expand All @@ -20,32 +59,168 @@ jobs:
cache-dependency-path: |
package-lock.json
client/package-lock.json

- name: Install root dependencies
run: npm ci --ignore-scripts --force

- name: Install client dependencies
run: npm ci --prefix client

- name: Check Prettier formatting
run: npx prettier --check .

- name: Test studio provider bridge
run: npm run test:studio-provider

- name: Typecheck client
run: npm run --prefix client typecheck

- name: Test client
run: npm run --prefix client test

- name: Build client
run: npm run --prefix client build

packages:
name: Packages and VS Code extension
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4

- uses: actions/setup-node@v4
with:
node-version: 20
cache: npm
cache-dependency-path: |
package-lock.json
packages/react-native-inspector/package-lock.json
packages/nativescript-inspector/package-lock.json

- name: Install root dependencies
run: npm ci --ignore-scripts --force

- name: Install NativeScript inspector dependencies
run: npm ci --prefix packages/nativescript-inspector

- name: Install React Native inspector dependencies
run: npm ci --prefix packages/react-native-inspector

- name: Build inspector and test packages
run: npm run build:packages

- name: Package VS Code extension
run: npm run package:vscode-extension

build-artifacts:
name: Build integration artifacts
runs-on: macos-latest

steps:
- uses: actions/checkout@v4

- uses: actions/setup-node@v4
with:
node-version: 20
cache: npm
cache-dependency-path: |
package-lock.json
client/package-lock.json

- uses: dtolnay/rust-toolchain@stable

- name: Cache Rust build outputs and fixture app
uses: actions/cache@v4
with:
components: rustfmt, clippy
path: |
~/.cargo/git
~/.cargo/registry
server/target
.cache/simdeck/fixture
key: rust-${{ runner.os }}-${{ hashFiles('server/Cargo.lock', 'server/Cargo.toml', 'server/build.rs', 'server/src/**/*.rs', 'cli/**/*.m', 'scripts/integration/fixture.mjs') }}
restore-keys: |
rust-${{ runner.os }}-

- name: Install root dependencies
run: npm ci
run: npm ci --ignore-scripts

- name: Install client dependencies
run: npm ci --prefix client

- name: Install NativeScript inspector dependencies
run: npm ci --prefix packages/nativescript-inspector
- name: Build CLI, client, and JS test API
run: |
npm run build:cli
npm run build:client
npm run build:simdeck-test
npm run test:integration:fixture

- name: Install React Native inspector dependencies
run: npm ci --prefix packages/react-native-inspector
- name: Upload integration artifacts
uses: actions/upload-artifact@v4
with:
name: simdeck-integration-artifacts
if-no-files-found: error
include-hidden-files: true
path: |
build/simdeck
build/simdeck-bin
client/dist
packages/simdeck-test/dist
.cache/simdeck/fixture

integration-cli:
name: CLI simulator integration
runs-on: macos-latest
needs:
- rust
- client
- packages
- build-artifacts

- name: Lint, build, and test
run: npm run ci
steps:
- uses: actions/checkout@v4

- uses: actions/setup-node@v4
with:
node-version: 20

- name: Download integration artifacts
uses: actions/download-artifact@v4
with:
name: simdeck-integration-artifacts
path: .

- name: Make CLI executable
run: chmod +x build/simdeck build/simdeck-bin

- name: CLI simulator integration tests
run: npm run test:integration:cli
env:
SIMDECK_INTEGRATION_VERBOSE: "1"

integration-js-api:
name: JS API simulator integration
runs-on: macos-latest
needs:
- rust
- client
- packages
- build-artifacts

steps:
- uses: actions/checkout@v4

- uses: actions/setup-node@v4
with:
node-version: 20

- name: Download integration artifacts
uses: actions/download-artifact@v4
with:
name: simdeck-integration-artifacts
path: .

- name: Make CLI executable
run: chmod +x build/simdeck build/simdeck-bin

- name: JS API simulator integration tests
run: npm run test:integration:js-api
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ packages/react-native-inspector/dist/
docs/.vitepress/dist/
docs/.vitepress/cache/
cloud/
.cache/
.playwright-mcp/
simdeck-snapshot.md

Expand Down
4 changes: 2 additions & 2 deletions client/src/api/client.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { API_ROOT } from "../shared/constants";
import { apiUrl } from "./config";
import type { HealthResponse } from "./types";

export class ApiError extends Error {
Expand Down Expand Up @@ -32,7 +32,7 @@ export async function apiRequest<T>(
options: RequestInit = {},
): Promise<T> {
const { headers, ...rest } = options;
const response = await fetch(`${API_ROOT}${path}`, {
const response = await fetch(apiUrl(path), {
...rest,
headers: apiHeaders(headers),
});
Expand Down
31 changes: 31 additions & 0 deletions client/src/api/config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
export interface SimDeckClientConfig {
apiRoot?: string;
}

let clientConfig: Required<SimDeckClientConfig> = {
apiRoot: "",
};

export function configureSimDeckClient(config: SimDeckClientConfig): void {
clientConfig = {
...clientConfig,
...config,
apiRoot: normalizeRoot(config.apiRoot ?? clientConfig.apiRoot),
};
}

export function apiRoot(): string {
return clientConfig.apiRoot;
}

export function apiUrl(path: string): string {
const root = apiRoot();
if (!root) {
return path;
}
return `${root}${path.startsWith("/") ? path : `/${path}`}`;
}

function normalizeRoot(root: string): string {
return root.replace(/\/+$/, "");
}
3 changes: 2 additions & 1 deletion client/src/api/controls.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { accessTokenFromLocation, apiRequest } from "./client";
import { apiUrl } from "./config";
import type {
KeyPayload,
LaunchPayload,
Expand Down Expand Up @@ -58,7 +59,7 @@ export function sendKey(udid: string, payload: KeyPayload) {

export function simulatorControlSocketUrl(udid: string) {
const url = new URL(
`/api/simulators/${encodeURIComponent(udid)}/control`,
apiUrl(`/api/simulators/${encodeURIComponent(udid)}/control`),
window.location.href,
);
const token = accessTokenFromLocation();
Expand Down
Loading
Loading