Skip to content

Commit 8225d16

Browse files
authored
Improve CI caching and reliability coverage (#12)
* Improve CI caching and reliability coverage * Fix studio provider expose URL normalization * Support embedded client expose URLs
1 parent 7120d20 commit 8225d16

25 files changed

Lines changed: 1751 additions & 326 deletions

File tree

.github/workflows/ci.yml

Lines changed: 184 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,49 @@ on:
66
- main
77
pull_request:
88

9+
concurrency:
10+
group: ci-${{ github.workflow }}-${{ github.ref }}
11+
cancel-in-progress: true
12+
13+
env:
14+
CARGO_INCREMENTAL: "0"
15+
916
jobs:
10-
ci:
17+
rust:
18+
name: Rust lint and unit tests
1119
runs-on: macos-latest
1220

21+
steps:
22+
- uses: actions/checkout@v4
23+
24+
- uses: dtolnay/rust-toolchain@stable
25+
with:
26+
components: rustfmt, clippy
27+
28+
- name: Cache Rust build outputs
29+
uses: actions/cache@v4
30+
with:
31+
path: |
32+
~/.cargo/git
33+
~/.cargo/registry
34+
server/target
35+
key: rust-${{ runner.os }}-${{ hashFiles('server/Cargo.lock', 'server/Cargo.toml', 'server/build.rs', 'server/src/**/*.rs', 'cli/**/*.m') }}
36+
restore-keys: |
37+
rust-${{ runner.os }}-
38+
39+
- name: Check Rust formatting
40+
run: cargo fmt --manifest-path server/Cargo.toml --check
41+
42+
- name: Clippy
43+
run: cargo clippy --manifest-path server/Cargo.toml --all-targets -- -D warnings
44+
45+
- name: Rust unit tests
46+
run: cargo test --manifest-path server/Cargo.toml
47+
48+
client:
49+
name: Client lint, build, and tests
50+
runs-on: ubuntu-latest
51+
1352
steps:
1453
- uses: actions/checkout@v4
1554

@@ -20,32 +59,168 @@ jobs:
2059
cache-dependency-path: |
2160
package-lock.json
2261
client/package-lock.json
62+
63+
- name: Install root dependencies
64+
run: npm ci --ignore-scripts --force
65+
66+
- name: Install client dependencies
67+
run: npm ci --prefix client
68+
69+
- name: Check Prettier formatting
70+
run: npx prettier --check .
71+
72+
- name: Test studio provider bridge
73+
run: npm run test:studio-provider
74+
75+
- name: Typecheck client
76+
run: npm run --prefix client typecheck
77+
78+
- name: Test client
79+
run: npm run --prefix client test
80+
81+
- name: Build client
82+
run: npm run --prefix client build
83+
84+
packages:
85+
name: Packages and VS Code extension
86+
runs-on: ubuntu-latest
87+
88+
steps:
89+
- uses: actions/checkout@v4
90+
91+
- uses: actions/setup-node@v4
92+
with:
93+
node-version: 20
94+
cache: npm
95+
cache-dependency-path: |
96+
package-lock.json
2397
packages/react-native-inspector/package-lock.json
2498
packages/nativescript-inspector/package-lock.json
2599
100+
- name: Install root dependencies
101+
run: npm ci --ignore-scripts --force
102+
103+
- name: Install NativeScript inspector dependencies
104+
run: npm ci --prefix packages/nativescript-inspector
105+
106+
- name: Install React Native inspector dependencies
107+
run: npm ci --prefix packages/react-native-inspector
108+
109+
- name: Build inspector and test packages
110+
run: npm run build:packages
111+
112+
- name: Package VS Code extension
113+
run: npm run package:vscode-extension
114+
115+
build-artifacts:
116+
name: Build integration artifacts
117+
runs-on: macos-latest
118+
119+
steps:
120+
- uses: actions/checkout@v4
121+
122+
- uses: actions/setup-node@v4
123+
with:
124+
node-version: 20
125+
cache: npm
126+
cache-dependency-path: |
127+
package-lock.json
128+
client/package-lock.json
129+
26130
- uses: dtolnay/rust-toolchain@stable
131+
132+
- name: Cache Rust build outputs and fixture app
133+
uses: actions/cache@v4
27134
with:
28-
components: rustfmt, clippy
135+
path: |
136+
~/.cargo/git
137+
~/.cargo/registry
138+
server/target
139+
.cache/simdeck/fixture
140+
key: rust-${{ runner.os }}-${{ hashFiles('server/Cargo.lock', 'server/Cargo.toml', 'server/build.rs', 'server/src/**/*.rs', 'cli/**/*.m', 'scripts/integration/fixture.mjs') }}
141+
restore-keys: |
142+
rust-${{ runner.os }}-
29143
30144
- name: Install root dependencies
31-
run: npm ci
145+
run: npm ci --ignore-scripts
32146

33147
- name: Install client dependencies
34148
run: npm ci --prefix client
35149

36-
- name: Install NativeScript inspector dependencies
37-
run: npm ci --prefix packages/nativescript-inspector
150+
- name: Build CLI, client, and JS test API
151+
run: |
152+
npm run build:cli
153+
npm run build:client
154+
npm run build:simdeck-test
155+
npm run test:integration:fixture
38156
39-
- name: Install React Native inspector dependencies
40-
run: npm ci --prefix packages/react-native-inspector
157+
- name: Upload integration artifacts
158+
uses: actions/upload-artifact@v4
159+
with:
160+
name: simdeck-integration-artifacts
161+
if-no-files-found: error
162+
include-hidden-files: true
163+
path: |
164+
build/simdeck
165+
build/simdeck-bin
166+
client/dist
167+
packages/simdeck-test/dist
168+
.cache/simdeck/fixture
169+
170+
integration-cli:
171+
name: CLI simulator integration
172+
runs-on: macos-latest
173+
needs:
174+
- rust
175+
- client
176+
- packages
177+
- build-artifacts
41178

42-
- name: Lint, build, and test
43-
run: npm run ci
179+
steps:
180+
- uses: actions/checkout@v4
181+
182+
- uses: actions/setup-node@v4
183+
with:
184+
node-version: 20
185+
186+
- name: Download integration artifacts
187+
uses: actions/download-artifact@v4
188+
with:
189+
name: simdeck-integration-artifacts
190+
path: .
191+
192+
- name: Make CLI executable
193+
run: chmod +x build/simdeck build/simdeck-bin
44194

45195
- name: CLI simulator integration tests
46196
run: npm run test:integration:cli
47197
env:
48198
SIMDECK_INTEGRATION_VERBOSE: "1"
49199

200+
integration-js-api:
201+
name: JS API simulator integration
202+
runs-on: macos-latest
203+
needs:
204+
- rust
205+
- client
206+
- packages
207+
- build-artifacts
208+
209+
steps:
210+
- uses: actions/checkout@v4
211+
212+
- uses: actions/setup-node@v4
213+
with:
214+
node-version: 20
215+
216+
- name: Download integration artifacts
217+
uses: actions/download-artifact@v4
218+
with:
219+
name: simdeck-integration-artifacts
220+
path: .
221+
222+
- name: Make CLI executable
223+
run: chmod +x build/simdeck build/simdeck-bin
224+
50225
- name: JS API simulator integration tests
51226
run: npm run test:integration:js-api

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ packages/react-native-inspector/dist/
1212
docs/.vitepress/dist/
1313
docs/.vitepress/cache/
1414
cloud/
15+
.cache/
1516
.playwright-mcp/
1617
simdeck-snapshot.md
1718

client/src/api/client.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { API_ROOT } from "../shared/constants";
1+
import { apiUrl } from "./config";
22
import type { HealthResponse } from "./types";
33

44
export class ApiError extends Error {
@@ -32,7 +32,7 @@ export async function apiRequest<T>(
3232
options: RequestInit = {},
3333
): Promise<T> {
3434
const { headers, ...rest } = options;
35-
const response = await fetch(`${API_ROOT}${path}`, {
35+
const response = await fetch(apiUrl(path), {
3636
...rest,
3737
headers: apiHeaders(headers),
3838
});

client/src/api/config.ts

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
export interface SimDeckClientConfig {
2+
apiRoot?: string;
3+
}
4+
5+
let clientConfig: Required<SimDeckClientConfig> = {
6+
apiRoot: "",
7+
};
8+
9+
export function configureSimDeckClient(config: SimDeckClientConfig): void {
10+
clientConfig = {
11+
...clientConfig,
12+
...config,
13+
apiRoot: normalizeRoot(config.apiRoot ?? clientConfig.apiRoot),
14+
};
15+
}
16+
17+
export function apiRoot(): string {
18+
return clientConfig.apiRoot;
19+
}
20+
21+
export function apiUrl(path: string): string {
22+
const root = apiRoot();
23+
if (!root) {
24+
return path;
25+
}
26+
return `${root}${path.startsWith("/") ? path : `/${path}`}`;
27+
}
28+
29+
function normalizeRoot(root: string): string {
30+
return root.replace(/\/+$/, "");
31+
}

client/src/api/controls.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { accessTokenFromLocation, apiRequest } from "./client";
2+
import { apiUrl } from "./config";
23
import type {
34
KeyPayload,
45
LaunchPayload,
@@ -58,7 +59,7 @@ export function sendKey(udid: string, payload: KeyPayload) {
5859

5960
export function simulatorControlSocketUrl(udid: string) {
6061
const url = new URL(
61-
`/api/simulators/${encodeURIComponent(udid)}/control`,
62+
apiUrl(`/api/simulators/${encodeURIComponent(udid)}/control`),
6263
window.location.href,
6364
);
6465
const token = accessTokenFromLocation();

0 commit comments

Comments
 (0)