@invarn/cibuild 2.8.3 → 2.8.5
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 +11 -11
- package/dist/src/yaml/steps/android-variant-resolution.test.js +144 -1
- package/dist/src/yaml/steps/android.d.ts +8 -0
- package/dist/src/yaml/steps/android.d.ts.map +1 -1
- package/dist/src/yaml/steps/android.js +36 -11
- package/dist/src/yaml/steps/cocoapods-locked-bundler.test.d.ts +17 -0
- package/dist/src/yaml/steps/cocoapods-locked-bundler.test.d.ts.map +1 -0
- package/dist/src/yaml/steps/cocoapods-locked-bundler.test.js +145 -0
- package/dist/src/yaml/steps/cocoapods-skip-if-absent.test.js +1 -1
- package/dist/src/yaml/steps/ios-deps.d.ts.map +1 -1
- package/dist/src/yaml/steps/ios-deps.js +62 -10
- package/dist/src/yaml/steps/xcode-derived-data.test.js +70 -2
- package/dist/src/yaml/steps/xcode-new.test.js +1 -1
- package/dist/src/yaml/steps/xcode-resolve-retry.test.js +2 -2
- package/dist/src/yaml/steps/xcode.d.ts.map +1 -1
- package/dist/src/yaml/steps/xcode.js +40 -11
- package/package.json +1 -1
|
@@ -27,10 +27,14 @@
|
|
|
27
27
|
* left both `Debug` and `Debug-iphonesimulator` under Products.
|
|
28
28
|
*/
|
|
29
29
|
import { describe, test, expect } from '@jest/globals';
|
|
30
|
+
import { execFileSync } from 'child_process';
|
|
31
|
+
import { mkdtempSync, realpathSync } from 'fs';
|
|
32
|
+
import { tmpdir } from 'os';
|
|
33
|
+
import { join } from 'path';
|
|
30
34
|
import { XcodeBuildStepExecutor, XcodeBuildForTestStepExecutor, XcodeBuildForSimulatorStepExecutor, } from './xcode.js';
|
|
31
35
|
import { APP_PRODUCT_RESOLVER_SOURCE } from './xcode-app-product.js';
|
|
32
36
|
import { testConfig } from './test-config.js';
|
|
33
|
-
const DERIVED = '-derivedDataPath "$
|
|
37
|
+
const DERIVED = '-derivedDataPath "$DERIVED_DATA_PATH"';
|
|
34
38
|
const scriptFor = async (executor, inputs) => {
|
|
35
39
|
const result = await executor.execute({ project_path: 'MyApp.xcodeproj', scheme: 'MyApp', ...inputs }, {}, testConfig);
|
|
36
40
|
return result.script;
|
|
@@ -71,7 +75,7 @@ describe('xcode-build-for-simulator finds the .app where it now lands', () => {
|
|
|
71
75
|
const build = (inputs = {}) => scriptFor(new XcodeBuildForSimulatorStepExecutor(), inputs);
|
|
72
76
|
test('searches under the per-platform Products directory', async () => {
|
|
73
77
|
const script = await build();
|
|
74
|
-
expect(script).toContain('PRODUCTS_DIR="$
|
|
78
|
+
expect(script).toContain('PRODUCTS_DIR="$DERIVED_DATA_PATH/Build/Products"');
|
|
75
79
|
expect(script).toContain('find "$PRODUCTS_DIR"');
|
|
76
80
|
});
|
|
77
81
|
test('searches deep enough to reach <config>-<platform>/Foo.app', async () => {
|
|
@@ -165,4 +169,68 @@ describe('the output_dir input still steers where everything goes', () => {
|
|
|
165
169
|
expect(script).toContain(DERIVED);
|
|
166
170
|
});
|
|
167
171
|
});
|
|
172
|
+
/**
|
|
173
|
+
* Derived data lives outside the source tree.
|
|
174
|
+
*
|
|
175
|
+
* With `-derivedDataPath "$OUTPUT_DIR/DerivedData"` and an output_dir of
|
|
176
|
+
* `build/app`, every resolved SPM checkout sat at
|
|
177
|
+
* `<repo>/build/app/DerivedData/SourcePackages/checkouts/` — inside the
|
|
178
|
+
* working tree an app's own SwiftLint build phase lints. vinhnx/Clendar went red
|
|
179
|
+
* on 145 serious violations, every one of them in a third-party package, none
|
|
180
|
+
* in the app. A developer's Xcode keeps derived data under ~/Library, so no
|
|
181
|
+
* repository has a reason to exclude it.
|
|
182
|
+
*/
|
|
183
|
+
describe('derived data is outside the source tree', () => {
|
|
184
|
+
const definitionOf = (script) => {
|
|
185
|
+
const line = script.split('\n').find((l) => l.startsWith('DERIVED_DATA_PATH='));
|
|
186
|
+
expect(line).toBeDefined();
|
|
187
|
+
return line;
|
|
188
|
+
};
|
|
189
|
+
// Runs the step's own definition line, the way the step would.
|
|
190
|
+
const resolve = (script, env) => execFileSync('bash', ['-c', `${definitionOf(script)}\nprintf '%s' "$DERIVED_DATA_PATH"`], {
|
|
191
|
+
env: { PATH: process.env.PATH ?? '', ...env },
|
|
192
|
+
}).toString();
|
|
193
|
+
test.each(buildingExecutors())('%s never builds into the output dir', async (_name, executor) => {
|
|
194
|
+
expect(await scriptFor(executor, {})).not.toContain('$OUTPUT_DIR/DerivedData');
|
|
195
|
+
});
|
|
196
|
+
test.each(buildingExecutors())('%s puts derived data under the scratch root, not under the checkout', async (_name, executor) => {
|
|
197
|
+
const scratch = realpathSync(mkdtempSync(join(tmpdir(), 'scratch-')));
|
|
198
|
+
const repo = join(scratch, 'workspace', 'repo');
|
|
199
|
+
const path = resolve(await scriptFor(executor, { output_dir: 'build/app' }), {
|
|
200
|
+
CIBUILD_SCRATCH: scratch,
|
|
201
|
+
OUTPUT_DIR: join(repo, 'build', 'app'),
|
|
202
|
+
});
|
|
203
|
+
expect(path.startsWith(scratch + '/')).toBe(true);
|
|
204
|
+
expect(path.startsWith(repo + '/')).toBe(false);
|
|
205
|
+
});
|
|
206
|
+
test('falls back to TMPDIR outside a sandbox', async () => {
|
|
207
|
+
const tmp = realpathSync(mkdtempSync(join(tmpdir(), 'tmp-')));
|
|
208
|
+
const path = resolve(await scriptFor(new XcodeBuildStepExecutor(), {}), {
|
|
209
|
+
TMPDIR: tmp,
|
|
210
|
+
OUTPUT_DIR: '/work/repo/build',
|
|
211
|
+
});
|
|
212
|
+
expect(path.startsWith(tmp + '/')).toBe(true);
|
|
213
|
+
});
|
|
214
|
+
// The iOS template names the same output_dir on Build App and Build for
|
|
215
|
+
// Testing so the second step reads what the first compiled. That sharing has
|
|
216
|
+
// to survive the move: same output dir, same derived data.
|
|
217
|
+
test('two steps naming the same output_dir share derived data', async () => {
|
|
218
|
+
const env = { CIBUILD_SCRATCH: '/scratch', OUTPUT_DIR: '/work/repo/build/app' };
|
|
219
|
+
const app = resolve(await scriptFor(new XcodeBuildForSimulatorStepExecutor(), { output_dir: 'build/app' }), env);
|
|
220
|
+
const tests = resolve(await scriptFor(new XcodeBuildForTestStepExecutor(), { output_dir: 'build/app' }), env);
|
|
221
|
+
expect(tests).toBe(app);
|
|
222
|
+
});
|
|
223
|
+
test('two different output dirs stay apart', async () => {
|
|
224
|
+
const script = await scriptFor(new XcodeBuildStepExecutor(), {});
|
|
225
|
+
const a = resolve(script, { CIBUILD_SCRATCH: '/scratch', OUTPUT_DIR: '/work/repo/build/app' });
|
|
226
|
+
const b = resolve(script, { CIBUILD_SCRATCH: '/scratch', OUTPUT_DIR: '/work/repo/build' });
|
|
227
|
+
expect(a).not.toBe(b);
|
|
228
|
+
});
|
|
229
|
+
test('the product listing and the xctestrun search follow it', async () => {
|
|
230
|
+
const build = await scriptFor(new XcodeBuildStepExecutor(), {});
|
|
231
|
+
expect(build).toContain('ls -lhR "$DERIVED_DATA_PATH/Build/Products"');
|
|
232
|
+
const forTest = await scriptFor(new XcodeBuildForTestStepExecutor(), {});
|
|
233
|
+
expect(forTest).toContain('find "$DERIVED_DATA_PATH/Build/Products" -name "*.xctestrun"');
|
|
234
|
+
});
|
|
235
|
+
});
|
|
168
236
|
//# sourceMappingURL=xcode-derived-data.test.js.map
|
|
@@ -52,7 +52,7 @@ describe('XcodeBuildForTestStepExecutor', () => {
|
|
|
52
52
|
const executor = new XcodeBuildForTestStepExecutor();
|
|
53
53
|
const result = await executor.execute({ project_path: 'MyApp.xcodeproj', scheme: 'MyApp' }, {}, testConfig);
|
|
54
54
|
expect(result.script).toContain('-derivedDataPath');
|
|
55
|
-
expect(result.script).toContain('
|
|
55
|
+
expect(result.script).toContain('-derivedDataPath "$DERIVED_DATA_PATH"');
|
|
56
56
|
});
|
|
57
57
|
test('should locate .xctestrun file', async () => {
|
|
58
58
|
const executor = new XcodeBuildForTestStepExecutor();
|
|
@@ -29,7 +29,7 @@ describe('xcode-build-for-test resolves before it builds', () => {
|
|
|
29
29
|
const resolveLine = script
|
|
30
30
|
.split('\n')
|
|
31
31
|
.find((l) => l.includes('-resolvePackageDependencies'));
|
|
32
|
-
expect(resolveLine).toContain('-derivedDataPath "$
|
|
32
|
+
expect(resolveLine).toContain('-derivedDataPath "$DERIVED_DATA_PATH"');
|
|
33
33
|
});
|
|
34
34
|
test('passes the same project type and scheme as the build', async () => {
|
|
35
35
|
const resolveLine = (await build())
|
|
@@ -131,7 +131,7 @@ describe('cocoapods-install retries a refused pod source fetch', () => {
|
|
|
131
131
|
});
|
|
132
132
|
test('still chooses between bundle exec and bare pod', async () => {
|
|
133
133
|
const script = await build();
|
|
134
|
-
expect(script).toContain('
|
|
134
|
+
expect(script).toContain('$BUNDLE_CMD exec pod');
|
|
135
135
|
expect(script).toContain('USE_BUNDLE_EXEC');
|
|
136
136
|
});
|
|
137
137
|
test('runs the pod command exactly once in the script', async () => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"xcode.d.ts","sourceRoot":"","sources":["../../../../src/yaml/steps/xcode.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAI7C,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AACxD,OAAO,KAAK,EAAE,qBAAqB,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"xcode.d.ts","sourceRoot":"","sources":["../../../../src/yaml/steps/xcode.ts"],"names":[],"mappings":"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"}
|
|
@@ -6,6 +6,32 @@ import { BaseStepExecutor } from './base.js';
|
|
|
6
6
|
import { resolveDestinationInput } from './xcode-destination.js';
|
|
7
7
|
import { APP_PRODUCT_RESOLVER_SOURCE } from './xcode-app-product.js';
|
|
8
8
|
import { refusedFetchHelpers, retryOnRefusedFetch } from './git-fetch-retry.js';
|
|
9
|
+
/**
|
|
10
|
+
* Where derived data goes: outside the source tree, keyed by the output dir.
|
|
11
|
+
*
|
|
12
|
+
* It used to be "$DERIVED_DATA_PATH", and OUTPUT_DIR is inside the
|
|
13
|
+
* checkout — so every resolved SPM package sat in the working tree, where an
|
|
14
|
+
* app's own lint or format build phase walks it. vinhnx/Clendar's SwiftLint
|
|
15
|
+
* phase failed the build on 145 serious violations, all of them in
|
|
16
|
+
* third-party packages under build/app/DerivedData/SourcePackages/checkouts.
|
|
17
|
+
* A developer's Xcode keeps derived data under ~/Library, so no repository has
|
|
18
|
+
* a reason to exclude that directory, and it should not have to.
|
|
19
|
+
*
|
|
20
|
+
* CIBUILD_SCRATCH is the runner's per-build local root, which holds the
|
|
21
|
+
* checkout rather than sitting inside it; outside a sandbox it falls back to
|
|
22
|
+
* TMPDIR. The key is a checksum of the absolute output dir, so two steps that
|
|
23
|
+
* name the same output_dir still share derived data (the iOS template relies
|
|
24
|
+
* on that to avoid compiling the app twice) and two that name different ones
|
|
25
|
+
* stay apart, as they did before.
|
|
26
|
+
*/
|
|
27
|
+
function derivedDataPathLines() {
|
|
28
|
+
return [
|
|
29
|
+
'# Derived data outside the source tree, keyed by the output dir',
|
|
30
|
+
'DERIVED_DATA_PATH="${CIBUILD_SCRATCH:-${TMPDIR:-/tmp}}/cibuild-derived-data/$(printf \'%s\' "$OUTPUT_DIR" | cksum | cut -d\' \' -f1)"',
|
|
31
|
+
'mkdir -p "$DERIVED_DATA_PATH"',
|
|
32
|
+
'echo "Derived data: $DERIVED_DATA_PATH"',
|
|
33
|
+
];
|
|
34
|
+
}
|
|
9
35
|
/**
|
|
10
36
|
* Xcodebuild step executor
|
|
11
37
|
* Builds iOS/macOS projects using xcodebuild
|
|
@@ -64,6 +90,7 @@ export class XcodeBuildStepExecutor extends BaseStepExecutor {
|
|
|
64
90
|
commands.push('# Create output directory and resolve to absolute path');
|
|
65
91
|
commands.push(`mkdir -p '${this.escapeBash(outputDir)}'`);
|
|
66
92
|
commands.push(`OUTPUT_DIR="$(cd '${this.escapeBash(outputDir)}' && pwd)"`);
|
|
93
|
+
commands.push(...derivedDataPathLines());
|
|
67
94
|
// Create xcconfig file if content provided
|
|
68
95
|
if (xcconfigContent && xcconfigContent.trim() !== '') {
|
|
69
96
|
commands.push('');
|
|
@@ -97,7 +124,7 @@ export class XcodeBuildStepExecutor extends BaseStepExecutor {
|
|
|
97
124
|
command: 'xcodebuild -resolvePackageDependencies' +
|
|
98
125
|
` "$PROJECT_TYPE" '${escapedPath}'` +
|
|
99
126
|
` -scheme '${this.escapeBash(scheme)}'` +
|
|
100
|
-
' -derivedDataPath "$
|
|
127
|
+
' -derivedDataPath "$DERIVED_DATA_PATH"',
|
|
101
128
|
}));
|
|
102
129
|
// Build xcodebuild command
|
|
103
130
|
commands.push('');
|
|
@@ -112,14 +139,14 @@ export class XcodeBuildStepExecutor extends BaseStepExecutor {
|
|
|
112
139
|
xcodebuildCmd += ` -scheme '${this.escapeBash(scheme)}'`;
|
|
113
140
|
xcodebuildCmd += ` -configuration '${this.escapeBash(configuration)}'`;
|
|
114
141
|
xcodebuildCmd += ` -destination '${this.escapeBash(destination)}'`;
|
|
115
|
-
//
|
|
142
|
+
// A derived data path (see derivedDataPathLines), rather than CONFIGURATION_BUILD_DIR.
|
|
116
143
|
// Same reasoning as XcodeBuildForSimulatorStepExecutor below, where the
|
|
117
144
|
// full mechanism and the control are written up: the flat directory
|
|
118
145
|
// collapses xcodebuild's per-configuration/per-platform product separation
|
|
119
146
|
// and any graph with two tasks producing the same output name is refused
|
|
120
147
|
// with "Multiple commands produce". It also desynchronises CocoaPods, whose
|
|
121
148
|
// PODS_CONFIGURATION_BUILD_DIR follows BUILD_DIR and not this setting.
|
|
122
|
-
xcodebuildCmd += ` -derivedDataPath "$
|
|
149
|
+
xcodebuildCmd += ` -derivedDataPath "$DERIVED_DATA_PATH"`;
|
|
123
150
|
// Add xcconfig if provided
|
|
124
151
|
if (xcconfigContent && xcconfigContent.trim() !== '') {
|
|
125
152
|
xcodebuildCmd += ' -xcconfig "$XCCONFIG_FILE"';
|
|
@@ -132,8 +159,8 @@ export class XcodeBuildStepExecutor extends BaseStepExecutor {
|
|
|
132
159
|
// Products live under the per-platform Products directory now, not flat in
|
|
133
160
|
// $OUTPUT_DIR, so point the listing at where they actually are — otherwise
|
|
134
161
|
// the log says "artifacts in build/" above an empty directory.
|
|
135
|
-
commands.push('echo "Build artifacts in: $
|
|
136
|
-
commands.push('ls -lhR "$
|
|
162
|
+
commands.push('echo "Build artifacts in: $DERIVED_DATA_PATH/Build/Products"');
|
|
163
|
+
commands.push('ls -lhR "$DERIVED_DATA_PATH/Build/Products" 2>/dev/null || true');
|
|
137
164
|
const script = this.createBashScriptFromCommands(commands, stepName);
|
|
138
165
|
return this.createScriptStep(script, stepName);
|
|
139
166
|
}
|
|
@@ -806,6 +833,7 @@ export class XcodeBuildForTestStepExecutor extends BaseStepExecutor {
|
|
|
806
833
|
// Output directory
|
|
807
834
|
commands.push(`mkdir -p '${this.escapeBash(outputDir)}'`);
|
|
808
835
|
commands.push(`OUTPUT_DIR="$(cd '${this.escapeBash(outputDir)}' && pwd)"`);
|
|
836
|
+
commands.push(...derivedDataPathLines());
|
|
809
837
|
commands.push('');
|
|
810
838
|
// xcconfig
|
|
811
839
|
if (xcconfigContent.trim()) {
|
|
@@ -833,7 +861,7 @@ export class XcodeBuildForTestStepExecutor extends BaseStepExecutor {
|
|
|
833
861
|
command: 'xcodebuild -resolvePackageDependencies' +
|
|
834
862
|
` "$PROJECT_TYPE" '${escapedPath}'` +
|
|
835
863
|
` -scheme '${escapedScheme}'` +
|
|
836
|
-
' -derivedDataPath "$
|
|
864
|
+
' -derivedDataPath "$DERIVED_DATA_PATH"',
|
|
837
865
|
}));
|
|
838
866
|
// Build command
|
|
839
867
|
let cmd = 'xcodebuild build-for-testing';
|
|
@@ -841,7 +869,7 @@ export class XcodeBuildForTestStepExecutor extends BaseStepExecutor {
|
|
|
841
869
|
cmd += ` -scheme '${escapedScheme}'`;
|
|
842
870
|
cmd += ` -configuration '${this.escapeBash(configuration)}'`;
|
|
843
871
|
cmd += ` -destination '${this.escapeBash(destination)}'`;
|
|
844
|
-
cmd += ` -derivedDataPath "$
|
|
872
|
+
cmd += ` -derivedDataPath "$DERIVED_DATA_PATH"`;
|
|
845
873
|
if (testPlan) {
|
|
846
874
|
cmd += ` -testPlan '${this.escapeBash(testPlan)}'`;
|
|
847
875
|
}
|
|
@@ -855,7 +883,7 @@ export class XcodeBuildForTestStepExecutor extends BaseStepExecutor {
|
|
|
855
883
|
commands.push('');
|
|
856
884
|
// Locate .xctestrun file
|
|
857
885
|
commands.push('# Locate generated .xctestrun file');
|
|
858
|
-
commands.push('XCTESTRUN_PATH=$(find "$
|
|
886
|
+
commands.push('XCTESTRUN_PATH=$(find "$DERIVED_DATA_PATH/Build/Products" -name "*.xctestrun" | head -1)');
|
|
859
887
|
commands.push('if [ -z "$XCTESTRUN_PATH" ]; then');
|
|
860
888
|
commands.push(' echo "❌ Error: .xctestrun file not found"');
|
|
861
889
|
commands.push(' exit 1');
|
|
@@ -1007,6 +1035,7 @@ export class XcodeBuildForSimulatorStepExecutor extends BaseStepExecutor {
|
|
|
1007
1035
|
// Output dir
|
|
1008
1036
|
commands.push(`mkdir -p '${this.escapeBash(outputDir)}'`);
|
|
1009
1037
|
commands.push(`OUTPUT_DIR="$(cd '${this.escapeBash(outputDir)}' && pwd)"`);
|
|
1038
|
+
commands.push(...derivedDataPathLines());
|
|
1010
1039
|
commands.push('');
|
|
1011
1040
|
// xcconfig
|
|
1012
1041
|
commands.push('XCCONFIG_FILE="$(mktemp -t cibuild-xcconfig).xcconfig"');
|
|
@@ -1040,7 +1069,7 @@ export class XcodeBuildForSimulatorStepExecutor extends BaseStepExecutor {
|
|
|
1040
1069
|
command: 'xcodebuild -resolvePackageDependencies' +
|
|
1041
1070
|
` "$PROJECT_TYPE" '${escapedPath}'` +
|
|
1042
1071
|
` -scheme '${escapedScheme}'` +
|
|
1043
|
-
' -derivedDataPath "$
|
|
1072
|
+
' -derivedDataPath "$DERIVED_DATA_PATH"',
|
|
1044
1073
|
}));
|
|
1045
1074
|
// Build command
|
|
1046
1075
|
let cmd = 'xcodebuild';
|
|
@@ -1087,7 +1116,7 @@ export class XcodeBuildForSimulatorStepExecutor extends BaseStepExecutor {
|
|
|
1087
1116
|
// with no .app; -derivedDataPath reached BUILD SUCCEEDED in 2m06s and left
|
|
1088
1117
|
// both Debug and Debug-iphonesimulator under Products — the separation the
|
|
1089
1118
|
// flat directory destroys.
|
|
1090
|
-
cmd += ` -derivedDataPath "$
|
|
1119
|
+
cmd += ` -derivedDataPath "$DERIVED_DATA_PATH"`;
|
|
1091
1120
|
cmd += ' -xcconfig "$XCCONFIG_FILE"';
|
|
1092
1121
|
if (xcodebuildOptions) {
|
|
1093
1122
|
cmd += ` ${xcodebuildOptions}`;
|
|
@@ -1106,7 +1135,7 @@ export class XcodeBuildForSimulatorStepExecutor extends BaseStepExecutor {
|
|
|
1106
1135
|
// answer — a project with no shared scheme is ordinary and builds fine, so
|
|
1107
1136
|
// this resolves the same bundle it always did there.
|
|
1108
1137
|
commands.push('# Locate generated .app — the one this scheme builds');
|
|
1109
|
-
commands.push('PRODUCTS_DIR="$
|
|
1138
|
+
commands.push('PRODUCTS_DIR="$DERIVED_DATA_PATH/Build/Products"');
|
|
1110
1139
|
commands.push('APP_RESOLVER="$(mktemp -t cibuild-app-product).cjs"');
|
|
1111
1140
|
commands.push(`cat > "$APP_RESOLVER" << 'CIBUILD_APP_PRODUCT_EOF'`);
|
|
1112
1141
|
commands.push(APP_PRODUCT_RESOLVER_SOURCE.trim());
|