@tamagui/native-ci 2.7.7 → 3.0.0-beta.637.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/android-utils.mjs +62 -0
- package/dist/android-utils.mjs.map +1 -0
- package/dist/cache.mjs +54 -70
- package/dist/cache.mjs.map +1 -1
- package/dist/cli.mjs +378 -403
- package/dist/cli.mjs.map +1 -1
- package/dist/constants.mjs +3 -2
- package/dist/constants.mjs.map +1 -1
- package/dist/deps.mjs +52 -64
- package/dist/deps.mjs.map +1 -1
- package/dist/detox.mjs +220 -202
- package/dist/detox.mjs.map +1 -1
- package/dist/fingerprint.mjs +35 -33
- package/dist/fingerprint.mjs.map +1 -1
- package/dist/index.js +10 -10
- package/dist/index.mjs +10 -10
- package/dist/ios-utils.mjs +318 -0
- package/dist/ios-utils.mjs.map +1 -0
- package/dist/metro.mjs +137 -139
- package/dist/metro.mjs.map +1 -1
- package/dist/runner.mjs +62 -65
- package/dist/runner.mjs.map +1 -1
- package/package.json +4 -4
- package/src/cli.ts +3 -3
- package/src/constants.ts +1 -1
- package/src/detox.ts +1 -0
- package/src/index.ts +2 -2
- package/src/metro.ts +2 -2
- package/src/run-detox-android.ts +1 -1
- package/src/run-detox-ios.ts +1 -1
- package/types/{android.d.ts → android-utils.d.ts} +1 -1
- package/types/android-utils.d.ts.map +1 -0
- package/types/cli.d.ts +1 -1
- package/types/constants.d.ts +2 -2
- package/types/detox.d.ts.map +1 -1
- package/types/index.d.ts +2 -2
- package/types/index.d.ts.map +1 -1
- package/types/{ios.d.ts → ios-utils.d.ts} +1 -1
- package/types/ios-utils.d.ts.map +1 -0
- package/dist/index.js.map +0 -1
- package/dist/index.mjs.map +0 -1
- package/types/android.d.ts.map +0 -1
- package/types/ios.d.ts.map +0 -1
- /package/src/{android.ts → android-utils.ts} +0 -0
- /package/src/{ios.ts → ios-utils.ts} +0 -0
package/dist/metro.mjs
CHANGED
|
@@ -1,159 +1,157 @@
|
|
|
1
1
|
import { execSync } from "node:child_process";
|
|
2
|
-
import {
|
|
2
|
+
import { DEFAULT_METRO_WAIT_ATTEMPTS, DEFAULT_METRO_WAIT_INTERVAL_MS, METRO_PORT, METRO_URL } from "./constants.mjs";
|
|
3
|
+
|
|
4
|
+
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, { get: (a, b) => (typeof require !== "undefined" ? require : a)[b] }) : x)(function(x) {
|
|
5
|
+
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
6
|
+
throw Error("Calling `require` for \"" + x + "\" in an environment that doesn't expose the `require` function. See https://rolldown.rs/in-depth/bundling-cjs#require-external-modules for more details.");
|
|
7
|
+
});
|
|
8
|
+
|
|
3
9
|
async function waitForMetro(options) {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
console.info("Metro is responding!");
|
|
19
|
-
return true;
|
|
20
|
-
}
|
|
21
|
-
} catch {}
|
|
22
|
-
console.info(`Waiting for Metro... (${i}/${maxAttempts})`);
|
|
23
|
-
await Bun.sleep(intervalMs);
|
|
24
|
-
}
|
|
25
|
-
return false;
|
|
10
|
+
const { platform, maxAttempts = DEFAULT_METRO_WAIT_ATTEMPTS, intervalMs = DEFAULT_METRO_WAIT_INTERVAL_MS } = options;
|
|
11
|
+
console.info("Waiting for Metro to start...");
|
|
12
|
+
for (let i = 1; i <= maxAttempts; i++) {
|
|
13
|
+
try {
|
|
14
|
+
const response = await fetch(`${METRO_URL}/`, { headers: { "Expo-Platform": platform } });
|
|
15
|
+
if (response.ok) {
|
|
16
|
+
console.info("Metro is responding!");
|
|
17
|
+
return true;
|
|
18
|
+
}
|
|
19
|
+
} catch {}
|
|
20
|
+
console.info(`Waiting for Metro... (${i}/${maxAttempts})`);
|
|
21
|
+
await Bun.sleep(intervalMs);
|
|
22
|
+
}
|
|
23
|
+
return false;
|
|
26
24
|
}
|
|
27
25
|
async function prewarmBundle(platform) {
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
}
|
|
46
|
-
} catch (error) {
|
|
47
|
-
console.info("Bundle pre-warm completed (with error, continuing)");
|
|
48
|
-
}
|
|
26
|
+
console.info("Pre-warming bundle...");
|
|
27
|
+
try {
|
|
28
|
+
const response = await fetch(`${METRO_URL}/`, { headers: { "Expo-Platform": platform } });
|
|
29
|
+
if (response.ok) {
|
|
30
|
+
const manifest = await response.json();
|
|
31
|
+
const bundleUrl = manifest?.launchAsset?.url;
|
|
32
|
+
if (bundleUrl) {
|
|
33
|
+
console.info(`Fetching bundle from: ${bundleUrl}`);
|
|
34
|
+
await fetch(bundleUrl);
|
|
35
|
+
console.info("Bundle pre-warmed!");
|
|
36
|
+
} else {
|
|
37
|
+
console.info("No bundle URL found in manifest, skipping pre-warm");
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
} catch (error) {
|
|
41
|
+
console.info("Bundle pre-warm completed (with error, continuing)");
|
|
42
|
+
}
|
|
49
43
|
}
|
|
50
44
|
function projectUsesDevClient() {
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
45
|
+
try {
|
|
46
|
+
const pkg = JSON.parse(__require("fs").readFileSync("package.json", "utf-8"));
|
|
47
|
+
const deps = {
|
|
48
|
+
...pkg.dependencies,
|
|
49
|
+
...pkg.devDependencies
|
|
50
|
+
};
|
|
51
|
+
if (deps["expo-dev-client"]) return true;
|
|
52
|
+
if (typeof pkg.scripts?.start === "string" && pkg.scripts.start.includes("--dev-client")) return true;
|
|
53
|
+
return false;
|
|
54
|
+
} catch {
|
|
55
|
+
return false;
|
|
56
|
+
}
|
|
63
57
|
}
|
|
64
58
|
function startMetro() {
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
59
|
+
console.info("\n--- Starting Metro bundler ---");
|
|
60
|
+
const isCI = !!process.env.CI;
|
|
61
|
+
const useDevClient = projectUsesDevClient();
|
|
62
|
+
const args = [
|
|
63
|
+
"bun",
|
|
64
|
+
"expo",
|
|
65
|
+
"start",
|
|
66
|
+
"--offline",
|
|
67
|
+
"--port",
|
|
68
|
+
String(METRO_PORT)
|
|
69
|
+
];
|
|
70
|
+
if (useDevClient) {
|
|
71
|
+
args.splice(3, 0, "--dev-client");
|
|
72
|
+
console.info("Dev client detected");
|
|
73
|
+
}
|
|
74
|
+
if (isCI) {
|
|
75
|
+
args.push("--clear");
|
|
76
|
+
console.info("CI detected: clearing Metro cache");
|
|
77
|
+
}
|
|
78
|
+
const proc = Bun.spawn(args, {
|
|
79
|
+
env: {
|
|
80
|
+
...process.env,
|
|
81
|
+
EXPO_NO_TELEMETRY: "true"
|
|
82
|
+
},
|
|
83
|
+
stdout: "inherit",
|
|
84
|
+
stderr: "inherit"
|
|
85
|
+
});
|
|
86
|
+
return {
|
|
87
|
+
proc,
|
|
88
|
+
kill: async () => {
|
|
89
|
+
const pid = proc.pid;
|
|
90
|
+
if (pid) {
|
|
91
|
+
try {
|
|
92
|
+
await Bun.spawn([
|
|
93
|
+
"pkill",
|
|
94
|
+
"-P",
|
|
95
|
+
String(pid)
|
|
96
|
+
], {
|
|
97
|
+
stdout: "ignore",
|
|
98
|
+
stderr: "ignore"
|
|
99
|
+
}).exited;
|
|
100
|
+
} catch {}
|
|
101
|
+
}
|
|
102
|
+
proc.kill("SIGKILL");
|
|
103
|
+
console.info("Metro stopped");
|
|
104
|
+
}
|
|
105
|
+
};
|
|
101
106
|
}
|
|
102
107
|
function setupSignalHandlers(metro) {
|
|
103
|
-
|
|
104
|
-
|
|
108
|
+
const cleanup = async (signal) => {
|
|
109
|
+
console.info(`
|
|
105
110
|
Received ${signal}, cleaning up...`);
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
+
await metro.kill();
|
|
112
|
+
process.exit(signal === "SIGINT" ? 130 : 143);
|
|
113
|
+
};
|
|
114
|
+
process.on("SIGINT", () => cleanup("SIGINT"));
|
|
115
|
+
process.on("SIGTERM", () => cleanup("SIGTERM"));
|
|
111
116
|
}
|
|
112
117
|
async function isMetroRunning(platform) {
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
return response.ok;
|
|
120
|
-
} catch {
|
|
121
|
-
return false;
|
|
122
|
-
}
|
|
118
|
+
try {
|
|
119
|
+
const response = await fetch(`${METRO_URL}/`, { headers: { "Expo-Platform": platform } });
|
|
120
|
+
return response.ok;
|
|
121
|
+
} catch {
|
|
122
|
+
return false;
|
|
123
|
+
}
|
|
123
124
|
}
|
|
124
125
|
function killPortProcess() {
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
}
|
|
133
|
-
} catch {}
|
|
126
|
+
try {
|
|
127
|
+
const pid = execSync(`lsof -ti tcp:${METRO_PORT} -sTCP:LISTEN`, { encoding: "utf-8" }).trim();
|
|
128
|
+
if (pid) {
|
|
129
|
+
console.info(`Killing process ${pid} on port ${METRO_PORT}...`);
|
|
130
|
+
process.kill(Number(pid), "SIGTERM");
|
|
131
|
+
}
|
|
132
|
+
} catch {}
|
|
134
133
|
}
|
|
135
134
|
async function withMetro(platform, fn) {
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
await metro.kill();
|
|
156
|
-
}
|
|
135
|
+
const alreadyRunning = await isMetroRunning(platform);
|
|
136
|
+
if (alreadyRunning) {
|
|
137
|
+
console.info("\n--- Metro already running, reusing existing instance ---");
|
|
138
|
+
await prewarmBundle(platform);
|
|
139
|
+
return await fn();
|
|
140
|
+
}
|
|
141
|
+
killPortProcess();
|
|
142
|
+
const metro = startMetro();
|
|
143
|
+
setupSignalHandlers(metro);
|
|
144
|
+
try {
|
|
145
|
+
const metroReady = await waitForMetro({ platform });
|
|
146
|
+
if (!metroReady) {
|
|
147
|
+
throw new Error("Metro failed to start within timeout");
|
|
148
|
+
}
|
|
149
|
+
await prewarmBundle(platform);
|
|
150
|
+
return await fn();
|
|
151
|
+
} finally {
|
|
152
|
+
await metro.kill();
|
|
153
|
+
}
|
|
157
154
|
}
|
|
155
|
+
|
|
158
156
|
export { prewarmBundle, setupSignalHandlers, startMetro, waitForMetro, withMetro };
|
|
159
157
|
//# sourceMappingURL=metro.mjs.map
|
package/dist/metro.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"
|
|
1
|
+
{"version":3,"file":"metro.js","names":[],"sources":["metro.js"],"sourcesContent":["import { execSync } from \"node:child_process\";\nimport {\n METRO_URL,\n METRO_PORT,\n DEFAULT_METRO_WAIT_ATTEMPTS,\n DEFAULT_METRO_WAIT_INTERVAL_MS\n} from \"./constants\";\nasync function waitForMetro(options) {\n const {\n platform,\n maxAttempts = DEFAULT_METRO_WAIT_ATTEMPTS,\n intervalMs = DEFAULT_METRO_WAIT_INTERVAL_MS\n } = options;\n console.info(\"Waiting for Metro to start...\");\n for (let i = 1; i <= maxAttempts; i++) {\n try {\n const response = await fetch(`${METRO_URL}/`, {\n headers: { \"Expo-Platform\": platform }\n });\n if (response.ok) {\n console.info(\"Metro is responding!\");\n return true;\n }\n } catch {\n }\n console.info(`Waiting for Metro... (${i}/${maxAttempts})`);\n await Bun.sleep(intervalMs);\n }\n return false;\n}\nasync function prewarmBundle(platform) {\n console.info(\"Pre-warming bundle...\");\n try {\n const response = await fetch(`${METRO_URL}/`, {\n headers: { \"Expo-Platform\": platform }\n });\n if (response.ok) {\n const manifest = await response.json();\n const bundleUrl = manifest?.launchAsset?.url;\n if (bundleUrl) {\n console.info(`Fetching bundle from: ${bundleUrl}`);\n await fetch(bundleUrl);\n console.info(\"Bundle pre-warmed!\");\n } else {\n console.info(\"No bundle URL found in manifest, skipping pre-warm\");\n }\n }\n } catch (error) {\n console.info(\"Bundle pre-warm completed (with error, continuing)\");\n }\n}\nfunction projectUsesDevClient() {\n try {\n const pkg = JSON.parse(require(\"fs\").readFileSync(\"package.json\", \"utf-8\"));\n const deps = { ...pkg.dependencies, ...pkg.devDependencies };\n if (deps[\"expo-dev-client\"]) return true;\n if (typeof pkg.scripts?.start === \"string\" && pkg.scripts.start.includes(\"--dev-client\"))\n return true;\n return false;\n } catch {\n return false;\n }\n}\nfunction startMetro() {\n console.info(\"\\n--- Starting Metro bundler ---\");\n const isCI = !!process.env.CI;\n const useDevClient = projectUsesDevClient();\n const args = [\"bun\", \"expo\", \"start\", \"--offline\", \"--port\", String(METRO_PORT)];\n if (useDevClient) {\n args.splice(3, 0, \"--dev-client\");\n console.info(\"Dev client detected\");\n }\n if (isCI) {\n args.push(\"--clear\");\n console.info(\"CI detected: clearing Metro cache\");\n }\n const proc = Bun.spawn(args, {\n env: { ...process.env, EXPO_NO_TELEMETRY: \"true\" },\n stdout: \"inherit\",\n stderr: \"inherit\"\n });\n return {\n proc,\n kill: async () => {\n const pid = proc.pid;\n if (pid) {\n try {\n await Bun.spawn([\"pkill\", \"-P\", String(pid)], {\n stdout: \"ignore\",\n stderr: \"ignore\"\n }).exited;\n } catch {\n }\n }\n proc.kill(\"SIGKILL\");\n console.info(\"Metro stopped\");\n }\n };\n}\nfunction setupSignalHandlers(metro) {\n const cleanup = async (signal) => {\n console.info(`\nReceived ${signal}, cleaning up...`);\n await metro.kill();\n process.exit(signal === \"SIGINT\" ? 130 : 143);\n };\n process.on(\"SIGINT\", () => cleanup(\"SIGINT\"));\n process.on(\"SIGTERM\", () => cleanup(\"SIGTERM\"));\n}\nasync function isMetroRunning(platform) {\n try {\n const response = await fetch(`${METRO_URL}/`, {\n headers: { \"Expo-Platform\": platform }\n });\n return response.ok;\n } catch {\n return false;\n }\n}\nfunction killPortProcess() {\n try {\n const pid = execSync(`lsof -ti tcp:${METRO_PORT} -sTCP:LISTEN`, {\n encoding: \"utf-8\"\n }).trim();\n if (pid) {\n console.info(`Killing process ${pid} on port ${METRO_PORT}...`);\n process.kill(Number(pid), \"SIGTERM\");\n }\n } catch {\n }\n}\nasync function withMetro(platform, fn) {\n const alreadyRunning = await isMetroRunning(platform);\n if (alreadyRunning) {\n console.info(\"\\n--- Metro already running, reusing existing instance ---\");\n await prewarmBundle(platform);\n return await fn();\n }\n killPortProcess();\n const metro = startMetro();\n setupSignalHandlers(metro);\n try {\n const metroReady = await waitForMetro({ platform });\n if (!metroReady) {\n throw new Error(\"Metro failed to start within timeout\");\n }\n await prewarmBundle(platform);\n return await fn();\n } finally {\n await metro.kill();\n }\n}\nexport {\n prewarmBundle,\n setupSignalHandlers,\n startMetro,\n waitForMetro,\n withMetro\n};\n//# sourceMappingURL=metro.js.map\n"],"mappings":"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"}
|
package/dist/runner.mjs
CHANGED
|
@@ -2,80 +2,77 @@ import { execSync } from "node:child_process";
|
|
|
2
2
|
import { appendFileSync } from "node:fs";
|
|
3
3
|
import { createCacheKey, loadCache, saveCache } from "./cache.mjs";
|
|
4
4
|
import { generateFingerprint } from "./fingerprint.mjs";
|
|
5
|
+
|
|
5
6
|
async function runWithCache(options) {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
try {
|
|
46
|
-
execSync(buildCommand, execOptions);
|
|
47
|
-
} catch (error) {
|
|
48
|
-
const err = error;
|
|
49
|
-
throw new Error(`Build failed: ${err.message}${err.stderr ? `
|
|
7
|
+
const { platform, buildCommand, outputPaths, projectRoot = process.cwd(), cachePrefix = "native-build", debug = false } = options;
|
|
8
|
+
const log = debug ? console.log : () => {};
|
|
9
|
+
log(`Generating ${platform} fingerprint...`);
|
|
10
|
+
const { hash: fingerprint } = await generateFingerprint({
|
|
11
|
+
platform,
|
|
12
|
+
projectRoot,
|
|
13
|
+
debug
|
|
14
|
+
});
|
|
15
|
+
log(`Fingerprint: ${fingerprint}`);
|
|
16
|
+
const cacheKey = createCacheKey({
|
|
17
|
+
platform,
|
|
18
|
+
fingerprint,
|
|
19
|
+
prefix: cachePrefix
|
|
20
|
+
});
|
|
21
|
+
log(`Cache key: ${cacheKey}`);
|
|
22
|
+
const cached = loadCache(cacheKey);
|
|
23
|
+
if (cached && cached.fingerprint === fingerprint) {
|
|
24
|
+
log("Cache hit! Skipping build.");
|
|
25
|
+
return {
|
|
26
|
+
cacheHit: true,
|
|
27
|
+
fingerprint,
|
|
28
|
+
cacheKey,
|
|
29
|
+
outputPaths
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
log(`Running build: ${buildCommand}`);
|
|
33
|
+
const execOptions = {
|
|
34
|
+
cwd: projectRoot,
|
|
35
|
+
stdio: debug ? "inherit" : [
|
|
36
|
+
"pipe",
|
|
37
|
+
"pipe",
|
|
38
|
+
"pipe"
|
|
39
|
+
]
|
|
40
|
+
};
|
|
41
|
+
try {
|
|
42
|
+
execSync(buildCommand, execOptions);
|
|
43
|
+
} catch (error) {
|
|
44
|
+
const err = error;
|
|
45
|
+
throw new Error(`Build failed: ${err.message}${err.stderr ? `
|
|
50
46
|
${err.stderr}` : ""}`);
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
47
|
+
}
|
|
48
|
+
saveCache(cacheKey, {
|
|
49
|
+
fingerprint,
|
|
50
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
51
|
+
platform,
|
|
52
|
+
outputPaths
|
|
53
|
+
});
|
|
54
|
+
return {
|
|
55
|
+
cacheHit: false,
|
|
56
|
+
fingerprint,
|
|
57
|
+
cacheKey,
|
|
58
|
+
outputPaths
|
|
59
|
+
};
|
|
64
60
|
}
|
|
65
61
|
function setGitHubOutput(name, value) {
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
62
|
+
const outputFile = process.env.GITHUB_OUTPUT;
|
|
63
|
+
if (outputFile) {
|
|
64
|
+
appendFileSync(outputFile, `${name}=${value}
|
|
69
65
|
`);
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
66
|
+
} else {
|
|
67
|
+
console.info(`[GitHub Output] ${name}=${value}`);
|
|
68
|
+
}
|
|
73
69
|
}
|
|
74
70
|
function isGitHubActions() {
|
|
75
|
-
|
|
71
|
+
return !!process.env.GITHUB_ACTIONS;
|
|
76
72
|
}
|
|
77
73
|
function isCI() {
|
|
78
|
-
|
|
74
|
+
return !!process.env.CI;
|
|
79
75
|
}
|
|
76
|
+
|
|
80
77
|
export { isCI, isGitHubActions, runWithCache, setGitHubOutput };
|
|
81
78
|
//# sourceMappingURL=runner.mjs.map
|
package/dist/runner.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["
|
|
1
|
+
{"version":3,"file":"runner.js","names":[],"sources":["runner.js"],"sourcesContent":["import { execSync } from \"node:child_process\";\nimport { appendFileSync } from \"node:fs\";\nimport { createCacheKey, loadCache, saveCache } from \"./cache\";\nimport { generateFingerprint } from \"./fingerprint\";\nasync function runWithCache(options) {\n const {\n platform,\n buildCommand,\n outputPaths,\n projectRoot = process.cwd(),\n cachePrefix = \"native-build\",\n debug = false\n } = options;\n const log = debug ? console.log : () => {\n };\n log(`Generating ${platform} fingerprint...`);\n const { hash: fingerprint } = await generateFingerprint({\n platform,\n projectRoot,\n debug\n });\n log(`Fingerprint: ${fingerprint}`);\n const cacheKey = createCacheKey({ platform, fingerprint, prefix: cachePrefix });\n log(`Cache key: ${cacheKey}`);\n const cached = loadCache(cacheKey);\n if (cached && cached.fingerprint === fingerprint) {\n log(\"Cache hit! Skipping build.\");\n return {\n cacheHit: true,\n fingerprint,\n cacheKey,\n outputPaths\n };\n }\n log(`Running build: ${buildCommand}`);\n const execOptions = {\n cwd: projectRoot,\n stdio: debug ? \"inherit\" : [\"pipe\", \"pipe\", \"pipe\"]\n };\n try {\n execSync(buildCommand, execOptions);\n } catch (error) {\n const err = error;\n throw new Error(`Build failed: ${err.message}${err.stderr ? `\n${err.stderr}` : \"\"}`);\n }\n saveCache(cacheKey, {\n fingerprint,\n timestamp: (/* @__PURE__ */ new Date()).toISOString(),\n platform,\n outputPaths\n });\n return {\n cacheHit: false,\n fingerprint,\n cacheKey,\n outputPaths\n };\n}\nfunction setGitHubOutput(name, value) {\n const outputFile = process.env.GITHUB_OUTPUT;\n if (outputFile) {\n appendFileSync(outputFile, `${name}=${value}\n`);\n } else {\n console.info(`[GitHub Output] ${name}=${value}`);\n }\n}\nfunction isGitHubActions() {\n return !!process.env.GITHUB_ACTIONS;\n}\nfunction isCI() {\n return !!process.env.CI;\n}\nexport {\n isCI,\n isGitHubActions,\n runWithCache,\n setGitHubOutput\n};\n//# sourceMappingURL=runner.js.map\n"],"mappings":";;;;;;AAIA,eAAe,aAAa,SAAS;CACnC,MAAM,EACJ,UACA,cACA,aACA,cAAc,QAAQ,IAAI,GAC1B,cAAc,gBACd,QAAQ,UACN;CACJ,MAAM,MAAM,QAAQ,QAAQ,YAAY,CACxC;CACA,IAAI,cAAc,SAAS,gBAAgB;CAC3C,MAAM,EAAE,MAAM,gBAAgB,MAAM,oBAAoB;EACtD;EACA;EACA;CACF,CAAC;CACD,IAAI,gBAAgB,aAAa;CACjC,MAAM,WAAW,eAAe;EAAE;EAAU;EAAa,QAAQ;CAAY,CAAC;CAC9E,IAAI,cAAc,UAAU;CAC5B,MAAM,SAAS,UAAU,QAAQ;CACjC,IAAI,UAAU,OAAO,gBAAgB,aAAa;EAChD,IAAI,4BAA4B;EAChC,OAAO;GACL,UAAU;GACV;GACA;GACA;EACF;CACF;CACA,IAAI,kBAAkB,cAAc;CACpC,MAAM,cAAc;EAClB,KAAK;EACL,OAAO,QAAQ,YAAY;GAAC;GAAQ;GAAQ;EAAM;CACpD;CACA,IAAI;EACF,SAAS,cAAc,WAAW;CACpC,SAAS,OAAO;EACd,MAAM,MAAM;EACZ,MAAM,IAAI,MAAM,iBAAiB,IAAI,UAAU,IAAI,SAAS;EAC9D,IAAI,WAAW,IAAI;CACnB;CACA,UAAU,UAAU;EAClB;EACA,4BAA4B,IAAI,KAAK,GAAG,YAAY;EACpD;EACA;CACF,CAAC;CACD,OAAO;EACL,UAAU;EACV;EACA;EACA;CACF;AACF;AACA,SAAS,gBAAgB,MAAM,OAAO;CACpC,MAAM,aAAa,QAAQ,IAAI;CAC/B,IAAI,YAAY;EACd,eAAe,YAAY,GAAG,KAAK,GAAG,MAAM;CAC/C;CACC,OAAO;EACL,QAAQ,KAAK,mBAAmB,KAAK,GAAG,OAAO;CACjD;AACF;AACA,SAAS,kBAAkB;CACzB,OAAO,CAAC,CAAC,QAAQ,IAAI;AACvB;AACA,SAAS,OAAO;CACd,OAAO,CAAC,CAAC,QAAQ,IAAI;AACvB"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tamagui/native-ci",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.0.0-beta.637.1",
|
|
4
4
|
"description": "Native CI/CD helpers for React Native apps with Expo - fingerprinting, caching, and build optimization",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -41,14 +41,14 @@
|
|
|
41
41
|
"clean:build": "tamagui-build clean:build"
|
|
42
42
|
},
|
|
43
43
|
"dependencies": {
|
|
44
|
-
"@expo/fingerprint": "~0.
|
|
44
|
+
"@expo/fingerprint": "~0.20.9"
|
|
45
45
|
},
|
|
46
46
|
"devDependencies": {
|
|
47
|
-
"@tamagui/build": "
|
|
47
|
+
"@tamagui/build": "3.0.0-beta.637.1",
|
|
48
48
|
"@types/bun": "^1.1.0",
|
|
49
49
|
"@types/node": "^22.1.0"
|
|
50
50
|
},
|
|
51
51
|
"engines": {
|
|
52
|
-
"
|
|
52
|
+
"bun": ">=1.1.0"
|
|
53
53
|
}
|
|
54
54
|
}
|
package/src/cli.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
#!/usr/bin/env
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
2
|
/**
|
|
3
3
|
* CLI for @tamagui/native-ci
|
|
4
4
|
*
|
|
@@ -33,8 +33,8 @@ import {
|
|
|
33
33
|
ensureAppInstalled,
|
|
34
34
|
getBootedSimulatorUDID,
|
|
35
35
|
getMaestroBundleId,
|
|
36
|
-
} from './ios'
|
|
37
|
-
import { setupAndroidDevice, ensureAndroidFolder } from './android'
|
|
36
|
+
} from './ios-utils'
|
|
37
|
+
import { setupAndroidDevice, ensureAndroidFolder } from './android-utils'
|
|
38
38
|
import type { Platform } from './constants'
|
|
39
39
|
import { chmodSync, mkdtempSync, rmSync, writeFileSync } from 'node:fs'
|
|
40
40
|
import { tmpdir } from 'node:os'
|
package/src/constants.ts
CHANGED
package/src/detox.ts
CHANGED
|
@@ -142,6 +142,7 @@ const CONNECT_FLAKE_SIGNATURES: RegExp[] = [
|
|
|
142
142
|
/skipping reload:/,
|
|
143
143
|
/FBSOpenApplicationServiceErrorDomain/,
|
|
144
144
|
/FBSOpenApplicationErrorDomain/,
|
|
145
|
+
/Waited for the root of the view hierarchy to have window focus/,
|
|
145
146
|
/Detox worker instance has not been installed/,
|
|
146
147
|
]
|
|
147
148
|
// Signatures that indicate a real test failure (assertion/logic error). When present,
|
package/src/index.ts
CHANGED
|
@@ -75,10 +75,10 @@ export {
|
|
|
75
75
|
setupAdbReverse,
|
|
76
76
|
setupAndroidDevice,
|
|
77
77
|
ensureAndroidFolder,
|
|
78
|
-
} from './android'
|
|
78
|
+
} from './android-utils'
|
|
79
79
|
|
|
80
80
|
// iOS utilities
|
|
81
|
-
export { ensureIOSFolder, ensureIOSApp, cleanupSimulators } from './ios'
|
|
81
|
+
export { ensureIOSFolder, ensureIOSApp, cleanupSimulators } from './ios-utils'
|
|
82
82
|
|
|
83
83
|
// Dependency management
|
|
84
84
|
export {
|
package/src/metro.ts
CHANGED
|
@@ -126,7 +126,7 @@ export function startMetro(): MetroProcess {
|
|
|
126
126
|
// Only clear cache in CI - locally we want fast startup using cached transforms
|
|
127
127
|
const isCI = !!process.env.CI
|
|
128
128
|
const useDevClient = projectUsesDevClient()
|
|
129
|
-
const args = ['bun', 'expo', 'start', '--offline']
|
|
129
|
+
const args = ['bun', 'expo', 'start', '--offline', '--port', String(METRO_PORT)]
|
|
130
130
|
if (useDevClient) {
|
|
131
131
|
args.splice(3, 0, '--dev-client')
|
|
132
132
|
console.info('Dev client detected')
|
|
@@ -196,7 +196,7 @@ async function isMetroRunning(platform: Platform): Promise<boolean> {
|
|
|
196
196
|
|
|
197
197
|
/**
|
|
198
198
|
* Kill whatever process is listening on the Metro port.
|
|
199
|
-
* Prevents conflicts with other projects' Metro instances
|
|
199
|
+
* Prevents conflicts with other projects' Metro instances on the dedicated Detox port.
|
|
200
200
|
*/
|
|
201
201
|
function killPortProcess(): void {
|
|
202
202
|
try {
|
package/src/run-detox-android.ts
CHANGED
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
|
|
15
15
|
import { withMetro } from './metro'
|
|
16
16
|
import { parseDetoxArgs, runDetoxTests } from './detox'
|
|
17
|
-
import { waitForDevice, setupAdbReverse, ensureAndroidFolder } from './android'
|
|
17
|
+
import { waitForDevice, setupAdbReverse, ensureAndroidFolder } from './android-utils'
|
|
18
18
|
|
|
19
19
|
const options = parseDetoxArgs('android')
|
|
20
20
|
|
package/src/run-detox-ios.ts
CHANGED
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
|
|
14
14
|
import { withMetro } from './metro'
|
|
15
15
|
import { parseDetoxArgs, runDetoxTests } from './detox'
|
|
16
|
-
import { ensureIOSFolder, ensureIOSApp } from './ios'
|
|
16
|
+
import { ensureIOSFolder, ensureIOSApp } from './ios-utils'
|
|
17
17
|
|
|
18
18
|
const options = parseDetoxArgs('ios')
|
|
19
19
|
|