@invarn/cibuild 1.3.18 → 1.4.0
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/cli.cjs +1 -1
- package/dist/src/cli.js +32 -8
- package/dist/src/commands/build.d.ts +1 -1
- package/dist/src/commands/build.d.ts.map +1 -1
- package/dist/src/commands/build.js +33 -51
- package/dist/src/commands/edit.js +2 -2
- package/dist/src/yaml/parser.js +3 -3
- package/dist/src/yaml/platform-detector.d.ts +1 -1
- package/dist/src/yaml/platform-detector.js +2 -2
- package/dist/src/yaml/platform-detector.test.js +0 -19
- package/dist/src/yaml/steps/cache.js +4 -4
- package/dist/src/yaml/types.d.ts +2 -2
- package/dist/src/yaml/types.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/src/cli.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { resolve, extname } from "node:path";
|
|
3
3
|
import { pathToFileURL } from "node:url";
|
|
4
|
-
import { existsSync, readdirSync, mkdirSync, copyFileSync, readFileSync, writeFileSync, appendFileSync } from "node:fs";
|
|
4
|
+
import { existsSync, readdirSync, mkdirSync, copyFileSync, readFileSync, writeFileSync, appendFileSync, statSync } from "node:fs";
|
|
5
5
|
import { homedir } from "node:os";
|
|
6
6
|
import { execSync } from "node:child_process";
|
|
7
7
|
import prompts from "prompts";
|
|
@@ -26,7 +26,7 @@ import { generateGitHubActionsWorkflow } from "./commands/github-workflow.js";
|
|
|
26
26
|
* Returns the detected project type, or null if neither is found.
|
|
27
27
|
*/
|
|
28
28
|
function detectMobileProjectRoot(dir) {
|
|
29
|
-
// Android: must have build.gradle or build.gradle.kts at root
|
|
29
|
+
// Android/KMM: must have build.gradle or build.gradle.kts at root
|
|
30
30
|
const androidIndicators = [
|
|
31
31
|
"build.gradle",
|
|
32
32
|
"build.gradle.kts",
|
|
@@ -35,7 +35,22 @@ function detectMobileProjectRoot(dir) {
|
|
|
35
35
|
"gradlew",
|
|
36
36
|
];
|
|
37
37
|
const hasAndroidIndicator = androidIndicators.some((f) => existsSync(resolve(dir, f)));
|
|
38
|
+
// KMM: Gradle project with an iosApp/ directory or shared/ multiplatform module
|
|
39
|
+
// Must check before plain Android since KMM also has Gradle files
|
|
38
40
|
if (hasAndroidIndicator) {
|
|
41
|
+
const kmmIndicators = ["iosApp", "shared", "composeApp"];
|
|
42
|
+
const hasKmmIndicator = kmmIndicators.some((d) => {
|
|
43
|
+
const fullPath = resolve(dir, d);
|
|
44
|
+
try {
|
|
45
|
+
return existsSync(fullPath) && statSync(fullPath).isDirectory();
|
|
46
|
+
}
|
|
47
|
+
catch {
|
|
48
|
+
return false;
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
if (hasKmmIndicator) {
|
|
52
|
+
return "kmm";
|
|
53
|
+
}
|
|
39
54
|
return "android";
|
|
40
55
|
}
|
|
41
56
|
// iOS: must have a .xcodeproj or .xcworkspace directory, or a Podfile
|
|
@@ -88,9 +103,10 @@ async function handleInitCommand(opts = {}) {
|
|
|
88
103
|
const projectType = detectMobileProjectRoot(cwd);
|
|
89
104
|
if (!projectType) {
|
|
90
105
|
console.error("Error: Not a mobile project root.");
|
|
91
|
-
console.error("ci init must be run from the root folder of an Android or
|
|
92
|
-
console.error("\nAndroid projects must contain one of:");
|
|
106
|
+
console.error("ci init must be run from the root folder of an Android, iOS, or KMM project.");
|
|
107
|
+
console.error("\nAndroid/KMM projects must contain one of:");
|
|
93
108
|
console.error(" build.gradle, build.gradle.kts, settings.gradle, settings.gradle.kts, gradlew");
|
|
109
|
+
console.error("\nKMM projects additionally need: iosApp/, shared/, or composeApp/ directory");
|
|
94
110
|
console.error("\niOS projects must contain one of:");
|
|
95
111
|
console.error(" *.xcodeproj, *.xcworkspace, Podfile");
|
|
96
112
|
process.exit(1);
|
|
@@ -104,7 +120,8 @@ async function handleInitCommand(opts = {}) {
|
|
|
104
120
|
process.exit(1);
|
|
105
121
|
}
|
|
106
122
|
}
|
|
107
|
-
|
|
123
|
+
const projectTypeLabel = projectType === "kmm" ? "KMM (Kotlin Multiplatform)" : projectType === "android" ? "Android" : "iOS";
|
|
124
|
+
console.log(`\nDetected project type: ${projectTypeLabel}`);
|
|
108
125
|
console.log(`
|
|
109
126
|
╔══════════════════════════════════════════════════════════════╗
|
|
110
127
|
║ CI Build - Dependency Check ║
|
|
@@ -163,7 +180,7 @@ async function handleInitCommand(opts = {}) {
|
|
|
163
180
|
];
|
|
164
181
|
const dependencies = [
|
|
165
182
|
...commonDependencies,
|
|
166
|
-
...(projectType === "android" ? androidDependencies : iosDependencies),
|
|
183
|
+
...(projectType === "android" ? androidDependencies : projectType === "kmm" ? [...androidDependencies, ...iosDependencies] : iosDependencies),
|
|
167
184
|
];
|
|
168
185
|
let allRequired = true;
|
|
169
186
|
let missingOptional = false;
|
|
@@ -301,8 +318,8 @@ async function handleInitCommand(opts = {}) {
|
|
|
301
318
|
try {
|
|
302
319
|
const yamlPipeline = loadYAMLPipeline(destPath);
|
|
303
320
|
const meta = yamlPipeline.meta?.["cibuild.io"];
|
|
304
|
-
if (meta?.platform === "ios" || meta?.platform === "android") {
|
|
305
|
-
importedPlatform = meta.platform;
|
|
321
|
+
if (meta?.platform === "ios" || meta?.platform === "android" || meta?.platform === "kmm") {
|
|
322
|
+
importedPlatform = meta.platform === "kmm" ? "ios" : meta.platform;
|
|
306
323
|
}
|
|
307
324
|
}
|
|
308
325
|
catch { /* ignore parse errors — default to macos-latest */ }
|
|
@@ -438,6 +455,7 @@ Usage:
|
|
|
438
455
|
ci run <path> [-w <name>] --skip-validation Skip validation, run with interactive prompts
|
|
439
456
|
ci validate <path> [-w <name>] Validate pipeline (alias for --validate-only)
|
|
440
457
|
ci detect-platform <path> [-w <name>] Detect platform from YAML pipeline
|
|
458
|
+
ci detect-project Detect project type (android, ios, kmm)
|
|
441
459
|
ci reset [--force] Remove all cibuild files and folders
|
|
442
460
|
ci edit <path> [-w <name>] View pipeline and edit step inputs
|
|
443
461
|
ci secrets add <var_name> <path> [-w <name>] Add a secret (prompted interactively)
|
|
@@ -485,6 +503,12 @@ Examples:
|
|
|
485
503
|
await import("./envman/cli.js");
|
|
486
504
|
return;
|
|
487
505
|
}
|
|
506
|
+
// Handle detect-project command
|
|
507
|
+
if (args[0] === "detect-project") {
|
|
508
|
+
const projectType = detectMobileProjectRoot(process.cwd());
|
|
509
|
+
console.log(projectType ?? "unknown");
|
|
510
|
+
process.exit(projectType ? 0 : 1);
|
|
511
|
+
}
|
|
488
512
|
// Handle init command
|
|
489
513
|
if (args[0] === "init") {
|
|
490
514
|
const importIdx = args.indexOf("--import");
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export declare function handleBuildCommand(detectMobileProjectRoot: (dir: string) => "android" | "ios" | null, options?: {
|
|
1
|
+
export declare function handleBuildCommand(detectMobileProjectRoot: (dir: string) => "android" | "ios" | "kmm" | null, options?: {
|
|
2
2
|
createPipelinesDir?: boolean;
|
|
3
3
|
nonInteractive?: boolean;
|
|
4
4
|
}): Promise<void>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../../../src/commands/build.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../../../src/commands/build.ts"],"names":[],"mappings":"AAk8BA,wBAAsB,kBAAkB,CACtC,uBAAuB,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,SAAS,GAAG,KAAK,GAAG,KAAK,GAAG,IAAI,EAC1E,OAAO,GAAE;IAAE,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAAC,cAAc,CAAC,EAAE,OAAO,CAAA;CAAO,GACvE,OAAO,CAAC,IAAI,CAAC,CA4Bf"}
|
|
@@ -122,7 +122,7 @@ function detectSetupNeeds(warnings) {
|
|
|
122
122
|
artifactType: 'apk',
|
|
123
123
|
};
|
|
124
124
|
}
|
|
125
|
-
function generateAndroidPipeline(javaVersion = 17, setup = { keystore: false, keystoreProperties: false, googleServices: false, googlePlayDeploy: false, googlePlayPackageName: '', artifactType: 'apk', keystorePaths: {} }, variants = DEFAULT_VARIANTS) {
|
|
125
|
+
function generateAndroidPipeline(javaVersion = 17, setup = { keystore: false, keystoreProperties: false, googleServices: false, googlePlayDeploy: false, googlePlayPackageName: '', artifactType: 'apk', keystorePaths: {} }, variants = DEFAULT_VARIANTS, cacheTechnology = "gradle") {
|
|
126
126
|
const keystoreStepFor = (wf) => {
|
|
127
127
|
if (!setup.keystore)
|
|
128
128
|
return "";
|
|
@@ -199,13 +199,15 @@ function generateAndroidPipeline(javaVersion = 17, setup = { keystore: false, ke
|
|
|
199
199
|
const releaseGradleTask = isAab ? `bundle${rv.buildType}` : rv.gradleTask;
|
|
200
200
|
const releaseArtifactLabel = isAab ? 'AAB' : 'APK';
|
|
201
201
|
const releaseArtifactExt = isAab ? '*.aab' : '*.apk';
|
|
202
|
+
const stack = cacheTechnology === "kmm" ? "macos-xcode-26.4" : "linux-docker-android-22.04";
|
|
203
|
+
const platformMeta = cacheTechnology === "kmm" ? "kmm" : "android";
|
|
202
204
|
return `format_version: '1'
|
|
203
205
|
|
|
204
206
|
meta:
|
|
205
207
|
cibuild.io:
|
|
206
|
-
stack:
|
|
208
|
+
stack: ${stack}
|
|
207
209
|
machine_type: standard
|
|
208
|
-
platform:
|
|
210
|
+
platform: ${platformMeta}
|
|
209
211
|
|
|
210
212
|
app:
|
|
211
213
|
envs:
|
|
@@ -227,11 +229,7 @@ ${keystoreStepFor("primary")}${googleServicesStep}
|
|
|
227
229
|
|
|
228
230
|
- cache-pull@1.0.0:
|
|
229
231
|
inputs:
|
|
230
|
-
|
|
231
|
-
cache_paths:
|
|
232
|
-
- ~/.gradle/caches
|
|
233
|
-
- ~/.gradle/wrapper
|
|
234
|
-
- .gradle
|
|
232
|
+
technology: ${cacheTechnology}
|
|
235
233
|
|
|
236
234
|
- android-lint@1.0.0:
|
|
237
235
|
is_skippable: true
|
|
@@ -257,11 +255,7 @@ ${keystoreStepFor("primary")}${googleServicesStep}
|
|
|
257
255
|
|
|
258
256
|
- cache-push@1.0.0:
|
|
259
257
|
inputs:
|
|
260
|
-
|
|
261
|
-
cache_paths:
|
|
262
|
-
- ~/.gradle/caches
|
|
263
|
-
- ~/.gradle/wrapper
|
|
264
|
-
- .gradle
|
|
258
|
+
technology: ${cacheTechnology}
|
|
265
259
|
|
|
266
260
|
pull-request:
|
|
267
261
|
envs:
|
|
@@ -275,10 +269,7 @@ ${keystoreStepFor("pull-request")}${googleServicesStep}
|
|
|
275
269
|
|
|
276
270
|
- cache-pull@1.0.0:
|
|
277
271
|
inputs:
|
|
278
|
-
|
|
279
|
-
cache_paths:
|
|
280
|
-
- ~/.gradle/caches
|
|
281
|
-
- ~/.gradle/wrapper
|
|
272
|
+
technology: ${cacheTechnology}
|
|
282
273
|
|
|
283
274
|
- android-lint@1.0.0:
|
|
284
275
|
is_skippable: true
|
|
@@ -303,10 +294,7 @@ ${keystoreStepFor("pull-request")}${googleServicesStep}
|
|
|
303
294
|
|
|
304
295
|
- cache-push@1.0.0:
|
|
305
296
|
inputs:
|
|
306
|
-
|
|
307
|
-
cache_paths:
|
|
308
|
-
- ~/.gradle/caches
|
|
309
|
-
- ~/.gradle/wrapper
|
|
297
|
+
technology: ${cacheTechnology}
|
|
310
298
|
|
|
311
299
|
release:
|
|
312
300
|
envs:
|
|
@@ -416,10 +404,8 @@ function generateIosPipeline(projectPath, setup, variants) {
|
|
|
416
404
|
submit_for_review: 'no'
|
|
417
405
|
`
|
|
418
406
|
: "";
|
|
419
|
-
// Cache
|
|
420
|
-
const
|
|
421
|
-
? ` - Pods\n - Podfile.lock`
|
|
422
|
-
: ` - .build`;
|
|
407
|
+
// Cache technology depends on whether CocoaPods is used
|
|
408
|
+
const iosCacheTechnology = setup.cocoaPods ? "cocoapods" : "spm";
|
|
423
409
|
return `format_version: '1'
|
|
424
410
|
|
|
425
411
|
meta:
|
|
@@ -441,9 +427,7 @@ ${schemeEnvFor(pv.scheme)}${configEnvFor(pv.configuration)}
|
|
|
441
427
|
steps:
|
|
442
428
|
- cache-pull@1.0.0:
|
|
443
429
|
inputs:
|
|
444
|
-
|
|
445
|
-
cache_paths:
|
|
446
|
-
${cachePaths}
|
|
430
|
+
technology: ${iosCacheTechnology}
|
|
447
431
|
${podInstallStep}
|
|
448
432
|
- xcode-archive@1.0.0:
|
|
449
433
|
inputs:
|
|
@@ -463,9 +447,7 @@ ${podInstallStep}
|
|
|
463
447
|
|
|
464
448
|
- cache-push@1.0.0:
|
|
465
449
|
inputs:
|
|
466
|
-
|
|
467
|
-
cache_paths:
|
|
468
|
-
${cachePaths}
|
|
450
|
+
technology: ${iosCacheTechnology}
|
|
469
451
|
|
|
470
452
|
pull-request:
|
|
471
453
|
envs:
|
|
@@ -473,9 +455,7 @@ ${schemeEnvFor(prv.scheme)}${configEnvFor(prv.configuration)}
|
|
|
473
455
|
steps:
|
|
474
456
|
- cache-pull@1.0.0:
|
|
475
457
|
inputs:
|
|
476
|
-
|
|
477
|
-
cache_paths:
|
|
478
|
-
${cachePaths}
|
|
458
|
+
technology: ${iosCacheTechnology}
|
|
479
459
|
${podInstallStepPR}
|
|
480
460
|
- xcode-test@1.0.0:
|
|
481
461
|
is_skippable: true
|
|
@@ -493,9 +473,7 @@ ${podInstallStepPR}
|
|
|
493
473
|
|
|
494
474
|
- cache-push@1.0.0:
|
|
495
475
|
inputs:
|
|
496
|
-
|
|
497
|
-
cache_paths:
|
|
498
|
-
${cachePaths}
|
|
476
|
+
technology: ${iosCacheTechnology}
|
|
499
477
|
|
|
500
478
|
release:
|
|
501
479
|
envs:
|
|
@@ -505,9 +483,7 @@ ${schemeEnvFor(rv.scheme)}
|
|
|
505
483
|
${codeSigningStep}
|
|
506
484
|
- cache-pull@1.0.0:
|
|
507
485
|
inputs:
|
|
508
|
-
|
|
509
|
-
cache_paths:
|
|
510
|
-
${cachePaths}
|
|
486
|
+
technology: ${iosCacheTechnology}
|
|
511
487
|
${podInstallStep}
|
|
512
488
|
- xcode-archive@1.0.0:
|
|
513
489
|
inputs:
|
|
@@ -848,17 +824,23 @@ export async function handleBuildCommand(detectMobileProjectRoot, options = {})
|
|
|
848
824
|
await handleIosBuildCommand(cwd, options);
|
|
849
825
|
return;
|
|
850
826
|
}
|
|
851
|
-
if (projectType
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
console.error("\nAndroid projects must contain one of:");
|
|
855
|
-
console.error(" build.gradle, build.gradle.kts, settings.gradle, settings.gradle.kts, gradlew");
|
|
856
|
-
console.error("\niOS projects must contain one of:");
|
|
857
|
-
console.error(" *.xcodeproj, *.xcworkspace, Podfile");
|
|
858
|
-
process.exit(1);
|
|
827
|
+
if (projectType === "kmm" || projectType === "android") {
|
|
828
|
+
await handleAndroidBuildCommand(cwd, options, projectType === "kmm" ? "kmm" : "gradle");
|
|
829
|
+
return;
|
|
859
830
|
}
|
|
831
|
+
console.error("Error: Not a mobile project root.");
|
|
832
|
+
console.error("'ci build' must be run from the root folder of an Android, iOS, or KMM project.");
|
|
833
|
+
console.error("\nAndroid/KMM projects must contain one of:");
|
|
834
|
+
console.error(" build.gradle, build.gradle.kts, settings.gradle, settings.gradle.kts, gradlew");
|
|
835
|
+
console.error("\nKMM projects additionally need: iosApp/, shared/, or composeApp/ directory");
|
|
836
|
+
console.error("\niOS projects must contain one of:");
|
|
837
|
+
console.error(" *.xcodeproj, *.xcworkspace, Podfile");
|
|
838
|
+
process.exit(1);
|
|
839
|
+
}
|
|
840
|
+
async function handleAndroidBuildCommand(cwd, options, cacheTechnology) {
|
|
841
|
+
const platformLabel = cacheTechnology === "kmm" ? "KMM (Kotlin Multiplatform)" : "Android";
|
|
860
842
|
// 2. Scan the project for potential unknowns
|
|
861
|
-
console.log(
|
|
843
|
+
console.log(`\n🔍 Scanning ${platformLabel} project for potential unknowns...\n`);
|
|
862
844
|
const scanResult = await scanAndroidProject(cwd);
|
|
863
845
|
console.log(formatScanResult(scanResult));
|
|
864
846
|
// 3. Prompt for build variants per workflow
|
|
@@ -1059,10 +1041,10 @@ export async function handleBuildCommand(detectMobileProjectRoot, options = {})
|
|
|
1059
1041
|
// that exact JDK — a newer JDK can cross-compile. Enforce a minimum of 17
|
|
1060
1042
|
// since ubuntu-latest runners ship with JDK 17+ and JDK <17 is unavailable.
|
|
1061
1043
|
const javaVersion = Math.max(scanResult.detectedJavaVersion ?? 17, 17);
|
|
1062
|
-
const yaml = generateAndroidPipeline(javaVersion, setupOptions, variants);
|
|
1044
|
+
const yaml = generateAndroidPipeline(javaVersion, setupOptions, variants, cacheTechnology);
|
|
1063
1045
|
writeFileSync(outputPath, yaml, "utf-8");
|
|
1064
1046
|
console.log("\n✅ Generated .ci/pipelines/cibuild.yml");
|
|
1065
|
-
console.log(
|
|
1047
|
+
console.log(` Platform: ${platformLabel}`);
|
|
1066
1048
|
console.log(` Workflows: primary (${variants.primary.variant}), pull-request (${variants.pullRequest.variant}), release (${variants.release.variant})`);
|
|
1067
1049
|
if (setupOptions.keystore || setupOptions.keystoreProperties || setupOptions.googleServices || setupOptions.googlePlayDeploy) {
|
|
1068
1050
|
console.log(" Setup steps included:");
|
|
@@ -293,8 +293,8 @@ async function handleAddRegisteredStep(pipelinePath, workflowName, _pipeline, st
|
|
|
293
293
|
function detectWorkflowPlatform(pipeline, workflowName) {
|
|
294
294
|
// 1. Explicit platform declaration in meta
|
|
295
295
|
const metaPlatform = pipeline.meta?.['cibuild.io']?.platform;
|
|
296
|
-
if (metaPlatform === 'ios' || metaPlatform === 'android')
|
|
297
|
-
return metaPlatform;
|
|
296
|
+
if (metaPlatform === 'ios' || metaPlatform === 'android' || metaPlatform === 'kmm')
|
|
297
|
+
return metaPlatform === 'kmm' ? 'ios' : metaPlatform;
|
|
298
298
|
// 2. Scan existing steps as fallback
|
|
299
299
|
const workflow = pipeline.workflows[workflowName];
|
|
300
300
|
if (!workflow)
|
package/dist/src/yaml/parser.js
CHANGED
|
@@ -97,7 +97,7 @@ function validateYAMLPipeline(parsed, filePath) {
|
|
|
97
97
|
}
|
|
98
98
|
// Validate platform if specified
|
|
99
99
|
if (parsed.meta.platform) {
|
|
100
|
-
const validPlatforms = ['macos', 'linux'
|
|
100
|
+
const validPlatforms = ['macos', 'linux'];
|
|
101
101
|
if (!validPlatforms.includes(parsed.meta.platform)) {
|
|
102
102
|
throw new YAMLValidationError(`Invalid platform '${parsed.meta.platform}' in ${filePath}. Must be one of: ${validPlatforms.join(', ')}`);
|
|
103
103
|
}
|
|
@@ -110,9 +110,9 @@ function validateYAMLPipeline(parsed, filePath) {
|
|
|
110
110
|
}
|
|
111
111
|
// Validate stack pattern if specified
|
|
112
112
|
if (cibuildMeta.stack && typeof cibuildMeta.stack === 'string') {
|
|
113
|
-
const stackPattern = /^(macos|linux
|
|
113
|
+
const stackPattern = /^(macos|linux)-/;
|
|
114
114
|
if (cibuildMeta.stack !== 'local' && !stackPattern.test(cibuildMeta.stack)) {
|
|
115
|
-
throw new YAMLValidationError(`Invalid stack '${cibuildMeta.stack}' in ${filePath}. Stack must be 'local' or start with 'macos-'
|
|
115
|
+
throw new YAMLValidationError(`Invalid stack '${cibuildMeta.stack}' in ${filePath}. Stack must be 'local' or start with 'macos-' or 'linux-'`);
|
|
116
116
|
}
|
|
117
117
|
}
|
|
118
118
|
// Validate machine_type if specified
|
|
@@ -20,7 +20,7 @@ export declare class PlatformDetector {
|
|
|
20
20
|
* Priority 2: meta.platform
|
|
21
21
|
* Priority 3: auto-detect from workflow steps
|
|
22
22
|
*
|
|
23
|
-
* @returns Detected platform ('macos'
|
|
23
|
+
* @returns Detected platform ('macos' or 'linux')
|
|
24
24
|
* @throws PlatformDetectionError if detection fails or mixed platforms detected
|
|
25
25
|
*/
|
|
26
26
|
getPlatform(): Platform;
|
|
@@ -29,7 +29,7 @@ export class PlatformDetector {
|
|
|
29
29
|
* Priority 2: meta.platform
|
|
30
30
|
* Priority 3: auto-detect from workflow steps
|
|
31
31
|
*
|
|
32
|
-
* @returns Detected platform ('macos'
|
|
32
|
+
* @returns Detected platform ('macos' or 'linux')
|
|
33
33
|
* @throws PlatformDetectionError if detection fails or mixed platforms detected
|
|
34
34
|
*/
|
|
35
35
|
getPlatform() {
|
|
@@ -84,7 +84,7 @@ export class PlatformDetector {
|
|
|
84
84
|
return null;
|
|
85
85
|
}
|
|
86
86
|
const platformPrefix = parts[0];
|
|
87
|
-
if (platformPrefix === 'macos' || platformPrefix === 'linux'
|
|
87
|
+
if (platformPrefix === 'macos' || platformPrefix === 'linux') {
|
|
88
88
|
return platformPrefix;
|
|
89
89
|
}
|
|
90
90
|
return null;
|
|
@@ -45,25 +45,6 @@ describe('PlatformDetector', () => {
|
|
|
45
45
|
expect(detector.getStack()).toBe('linux-docker-android-22.04');
|
|
46
46
|
expect(detector.getMachineType()).toBe('standard');
|
|
47
47
|
});
|
|
48
|
-
test('should detect windows from stack', () => {
|
|
49
|
-
const pipeline = {
|
|
50
|
-
format_version: '4',
|
|
51
|
-
meta: {
|
|
52
|
-
'cibuild.io': {
|
|
53
|
-
stack: 'windows-server-2022',
|
|
54
|
-
},
|
|
55
|
-
},
|
|
56
|
-
workflows: {
|
|
57
|
-
primary: {
|
|
58
|
-
steps: [{ 'script@1.0.0': { inputs: { content: 'echo "test"' } } }],
|
|
59
|
-
},
|
|
60
|
-
},
|
|
61
|
-
};
|
|
62
|
-
const detector = new PlatformDetector(pipeline, pipeline.workflows.primary, 'primary');
|
|
63
|
-
expect(detector.getPlatform()).toBe('windows');
|
|
64
|
-
expect(detector.getStack()).toBe('windows-server-2022');
|
|
65
|
-
expect(detector.getMachineType()).toBeNull();
|
|
66
|
-
});
|
|
67
48
|
});
|
|
68
49
|
describe('Priority 2: Use meta.platform field', () => {
|
|
69
50
|
test('should use meta.platform when stack not specified', () => {
|
|
@@ -80,7 +80,7 @@ export class CachePullStepExecutor extends BaseStepExecutor {
|
|
|
80
80
|
commands.push(' echo "Restored paths:"');
|
|
81
81
|
for (const path of cachePaths) {
|
|
82
82
|
commands.push(` EXPANDED_PATH="${this.escapeBash(path)}"`);
|
|
83
|
-
commands.push(' EXPANDED_PATH="${EXPANDED_PATH/#~/$HOME}"');
|
|
83
|
+
commands.push(' EXPANDED_PATH="${EXPANDED_PATH/#~/${CIBUILD_USER_HOME:-$HOME}}"');
|
|
84
84
|
commands.push(' if [ -e "$EXPANDED_PATH" ]; then');
|
|
85
85
|
commands.push(' echo " ✓ $EXPANDED_PATH"');
|
|
86
86
|
commands.push(' else');
|
|
@@ -137,7 +137,7 @@ export class CachePullStepExecutor extends BaseStepExecutor {
|
|
|
137
137
|
commands.push(' echo "Restored paths:"');
|
|
138
138
|
for (const p of preset.paths) {
|
|
139
139
|
commands.push(` EXPANDED="${this.escapeBash(p)}"`);
|
|
140
|
-
commands.push(' EXPANDED="${EXPANDED/#~/$HOME}"');
|
|
140
|
+
commands.push(' EXPANDED="${EXPANDED/#~/${CIBUILD_USER_HOME:-$HOME}}"');
|
|
141
141
|
commands.push(' if [ -e "$EXPANDED" ]; then');
|
|
142
142
|
commands.push(' echo " ✓ $EXPANDED"');
|
|
143
143
|
commands.push(' else');
|
|
@@ -234,7 +234,7 @@ export class CachePushStepExecutor extends BaseStepExecutor {
|
|
|
234
234
|
}
|
|
235
235
|
// Expand tilde by using parameter expansion
|
|
236
236
|
commands.push(`EXPANDED_PATH="${this.escapeBash(resolvedPath)}"`);
|
|
237
|
-
commands.push('EXPANDED_PATH="${EXPANDED_PATH/#~/$HOME}"');
|
|
237
|
+
commands.push('EXPANDED_PATH="${EXPANDED_PATH/#~/${CIBUILD_USER_HOME:-$HOME}}"');
|
|
238
238
|
commands.push('');
|
|
239
239
|
commands.push('# Expand glob patterns and check each match');
|
|
240
240
|
commands.push('FOUND_MATCH=false');
|
|
@@ -319,7 +319,7 @@ export class CachePushStepExecutor extends BaseStepExecutor {
|
|
|
319
319
|
commands.push('PATHS_TO_CACHE=()');
|
|
320
320
|
for (const p of preset.paths) {
|
|
321
321
|
commands.push(`EXPANDED="${this.escapeBash(p)}"`);
|
|
322
|
-
commands.push('EXPANDED="${EXPANDED/#~/$HOME}"');
|
|
322
|
+
commands.push('EXPANDED="${EXPANDED/#~/${CIBUILD_USER_HOME:-$HOME}}"');
|
|
323
323
|
commands.push('if [ -e "$EXPANDED" ]; then');
|
|
324
324
|
commands.push(' PATHS_TO_CACHE+=("$EXPANDED")');
|
|
325
325
|
if (isDebugMode) {
|
package/dist/src/yaml/types.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* TypeScript interfaces for Bitrise-compatible YAML pipeline structure
|
|
3
3
|
*/
|
|
4
|
-
export type Platform = 'macos' | 'linux'
|
|
4
|
+
export type Platform = 'macos' | 'linux';
|
|
5
5
|
export type MachineType = 'standard' | 'performance';
|
|
6
6
|
export interface YAMLEnvVar {
|
|
7
7
|
[key: string]: string;
|
|
@@ -10,7 +10,7 @@ export interface YAMLCIBuildMeta {
|
|
|
10
10
|
stack?: string;
|
|
11
11
|
machine_type?: MachineType;
|
|
12
12
|
machine_type_id?: string;
|
|
13
|
-
platform?: 'ios' | 'android';
|
|
13
|
+
platform?: 'ios' | 'android' | 'kmm';
|
|
14
14
|
}
|
|
15
15
|
export interface YAMLMeta {
|
|
16
16
|
'cibuild.io'?: YAMLCIBuildMeta;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/yaml/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,MAAM,MAAM,QAAQ,GAAG,OAAO,GAAG,OAAO,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/yaml/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,MAAM,MAAM,QAAQ,GAAG,OAAO,GAAG,OAAO,CAAC;AACzC,MAAM,MAAM,WAAW,GAAG,UAAU,GAAG,aAAa,CAAC;AAGrD,MAAM,WAAW,UAAU;IACzB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAC;CACvB;AAGD,MAAM,WAAW,eAAe;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,WAAW,CAAC;IAC3B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,EAAE,KAAK,GAAG,SAAS,GAAG,KAAK,CAAC;CACtC;AAED,MAAM,WAAW,QAAQ;IACvB,YAAY,CAAC,EAAE,eAAe,CAAC;IAC/B,YAAY,CAAC,EAAE,eAAe,CAAC;IAC/B,QAAQ,CAAC,EAAE,QAAQ,CAAC;CACrB;AAGD,MAAM,WAAW,cAAc;IAC7B,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;CACpB;AAGD,MAAM,WAAW,QAAQ;IACvB,CAAC,mBAAmB,EAAE,MAAM,GAAG;QAC7B,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,MAAM,CAAC,EAAE,cAAc,CAAC;QACxB,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,aAAa,CAAC,EAAE,OAAO,CAAC;QACxB,YAAY,CAAC,EAAE,OAAO,CAAC;KACxB,CAAC;CACH;AAGD,MAAM,WAAW,YAAY;IAC3B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,UAAU,EAAE,CAAC;IACpB,KAAK,EAAE,QAAQ,EAAE,CAAC;CACnB;AAGD,MAAM,WAAW,OAAO;IACtB,IAAI,CAAC,EAAE,UAAU,EAAE,CAAC;CACrB;AAGD,MAAM,WAAW,WAAW;IAC1B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,0BAA0B,CAAC,EAAE,MAAM,CAAC;IACpC,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAGD,MAAM,WAAW,YAAY;IAC3B,cAAc,EAAE,MAAM,CAAC;IACvB,IAAI,CAAC,EAAE,QAAQ,CAAC;IAChB,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,SAAS,EAAE;QAAE,CAAC,IAAI,EAAE,MAAM,GAAG,YAAY,CAAA;KAAE,CAAC;IAC5C,WAAW,CAAC,EAAE,WAAW,EAAE,CAAC;CAC7B;AAGD,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,cAAc,CAAC;IACvB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAGD,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,QAAQ,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,WAAW,CAAC;CAC3B"}
|