@invarn/cibuild 1.8.0 → 1.9.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.
@@ -0,0 +1,227 @@
1
+ /**
2
+ * Tests for the shared "auto destination" resolver.
3
+ *
4
+ * The resolver consumes the JSON `xcrun simctl list devices available --json`
5
+ * would produce on a macOS runner, and returns the canonical
6
+ * `platform=iOS Simulator,OS=<v>,name=<name>` string to feed to xcodebuild.
7
+ */
8
+ import { describe, test, expect } from '@jest/globals';
9
+ import { AutoDestinationError, resolveAutoDestinationFromSimctlJson, resolveDestinationInput, } from './xcode-destination.js';
10
+ import { XcodeBuildStepExecutor, XcodeTestStepExecutor, XcodeBuildForTestStepExecutor, XcodeTestWithoutBuildingStepExecutor, XcodeBuildForSimulatorStepExecutor, } from './xcode.js';
11
+ import { testConfig } from './test-config.js';
12
+ describe('resolveAutoDestinationFromSimctlJson', () => {
13
+ test('picks the newest iPhone in the highest iOS runtime', () => {
14
+ const simctl = {
15
+ devices: {
16
+ 'com.apple.CoreSimulator.SimRuntime.iOS-18-0': [
17
+ {
18
+ name: 'iPhone 16',
19
+ isAvailable: true,
20
+ state: 'Shutdown',
21
+ udid: 'AAA',
22
+ },
23
+ ],
24
+ },
25
+ };
26
+ const resolved = resolveAutoDestinationFromSimctlJson(JSON.stringify(simctl));
27
+ expect(resolved).toBe('platform=iOS Simulator,OS=18.0,name=iPhone 16');
28
+ });
29
+ test('higher iOS runtime wins (iOS 18.0 beats iOS 17.5), even if older runtime has newer model', () => {
30
+ const simctl = {
31
+ devices: {
32
+ 'com.apple.CoreSimulator.SimRuntime.iOS-17-5': [
33
+ // Pretend iPhone 16 also shows up here — runtime version should still win.
34
+ { name: 'iPhone 16', isAvailable: true, udid: 'old' },
35
+ ],
36
+ 'com.apple.CoreSimulator.SimRuntime.iOS-18-0': [
37
+ { name: 'iPhone 15', isAvailable: true, udid: 'new' },
38
+ ],
39
+ },
40
+ };
41
+ const resolved = resolveAutoDestinationFromSimctlJson(JSON.stringify(simctl));
42
+ expect(resolved).toBe('platform=iOS Simulator,OS=18.0,name=iPhone 15');
43
+ });
44
+ test('Pro Max wins over Pro and plain at same model number', () => {
45
+ const simctl = {
46
+ devices: {
47
+ 'com.apple.CoreSimulator.SimRuntime.iOS-18-0': [
48
+ { name: 'iPhone 16', isAvailable: true, udid: '1' },
49
+ { name: 'iPhone 16 Pro', isAvailable: true, udid: '2' },
50
+ { name: 'iPhone 16 Pro Max', isAvailable: true, udid: '3' },
51
+ ],
52
+ },
53
+ };
54
+ const resolved = resolveAutoDestinationFromSimctlJson(JSON.stringify(simctl));
55
+ expect(resolved).toBe('platform=iOS Simulator,OS=18.0,name=iPhone 16 Pro Max');
56
+ });
57
+ test('Pro wins over plain when Pro Max is missing', () => {
58
+ const simctl = {
59
+ devices: {
60
+ 'com.apple.CoreSimulator.SimRuntime.iOS-18-0': [
61
+ { name: 'iPhone 16', isAvailable: true, udid: '1' },
62
+ { name: 'iPhone 16 Pro', isAvailable: true, udid: '2' },
63
+ ],
64
+ },
65
+ };
66
+ const resolved = resolveAutoDestinationFromSimctlJson(JSON.stringify(simctl));
67
+ expect(resolved).toBe('platform=iOS Simulator,OS=18.0,name=iPhone 16 Pro');
68
+ });
69
+ test('higher iPhone model number wins (iPhone 16 beats iPhone 15)', () => {
70
+ const simctl = {
71
+ devices: {
72
+ 'com.apple.CoreSimulator.SimRuntime.iOS-18-0': [
73
+ { name: 'iPhone 15', isAvailable: true, udid: '1' },
74
+ { name: 'iPhone 16', isAvailable: true, udid: '2' },
75
+ { name: 'iPhone 14', isAvailable: true, udid: '3' },
76
+ { name: 'iPhone SE (3rd generation)', isAvailable: true, udid: '4' },
77
+ ],
78
+ },
79
+ };
80
+ const resolved = resolveAutoDestinationFromSimctlJson(JSON.stringify(simctl));
81
+ expect(resolved).toBe('platform=iOS Simulator,OS=18.0,name=iPhone 16');
82
+ });
83
+ test('throws documented error when no iPhone simulator runtime is installed', () => {
84
+ const simctl = { devices: {} };
85
+ expect(() => resolveAutoDestinationFromSimctlJson(JSON.stringify(simctl))).toThrow(AutoDestinationError);
86
+ expect(() => resolveAutoDestinationFromSimctlJson(JSON.stringify(simctl))).toThrow(/no iPhone simulator runtimes are installed/);
87
+ });
88
+ test('throws documented error when iOS runtime has no iPhone devices (e.g. only iPads)', () => {
89
+ const simctl = {
90
+ devices: {
91
+ 'com.apple.CoreSimulator.SimRuntime.iOS-18-0': [
92
+ { name: 'iPad Pro (11-inch)', isAvailable: true, udid: '1' },
93
+ ],
94
+ },
95
+ };
96
+ expect(() => resolveAutoDestinationFromSimctlJson(JSON.stringify(simctl))).toThrow(/no iPhone simulator runtimes are installed/);
97
+ });
98
+ test('throws documented error on unparseable JSON', () => {
99
+ expect(() => resolveAutoDestinationFromSimctlJson('not-json')).toThrow(/xcrun simctl returned no usable output/);
100
+ });
101
+ test('resolveDestinationInput passes literal destinations through verbatim', () => {
102
+ const literal = 'platform=iOS Simulator,name=iPhone 14,OS=17.5';
103
+ expect(resolveDestinationInput(literal)).toBe(literal);
104
+ });
105
+ test('resolveDestinationInput delegates to injected resolver only when value === "auto"', () => {
106
+ const fakeResolver = () => 'platform=iOS Simulator,OS=99.9,name=iPhone Fixture';
107
+ expect(resolveDestinationInput('auto', fakeResolver)).toBe('platform=iOS Simulator,OS=99.9,name=iPhone Fixture');
108
+ // Pass-through still wins when value is anything else, even if a resolver is provided.
109
+ expect(resolveDestinationInput('generic/platform=iOS', fakeResolver)).toBe('generic/platform=iOS');
110
+ });
111
+ test('ignores unavailable iPhones', () => {
112
+ const simctl = {
113
+ devices: {
114
+ 'com.apple.CoreSimulator.SimRuntime.iOS-18-0': [
115
+ { name: 'iPhone 16', isAvailable: false, udid: '1' },
116
+ { name: 'iPhone 15', isAvailable: true, udid: '2' },
117
+ ],
118
+ },
119
+ };
120
+ const resolved = resolveAutoDestinationFromSimctlJson(JSON.stringify(simctl));
121
+ expect(resolved).toBe('platform=iOS Simulator,OS=18.0,name=iPhone 15');
122
+ });
123
+ });
124
+ /**
125
+ * Each affected executor must (a) embed a literal destination unchanged and
126
+ * (b) add an `xcrun` validation requirement only when destination === "auto".
127
+ *
128
+ * The "auto" execute() path is not exercised here — it shells out to xcrun.
129
+ * The pure parser tests above cover its correctness; the manual smoke test in
130
+ * the spike's "done criteria" covers the end-to-end shell-out.
131
+ */
132
+ describe('xcode-* executors — destination input wiring', () => {
133
+ const xcrunReq = (reqs) => reqs.find((r) => r.category === 'command' && r.name === 'xcrun');
134
+ describe('XcodeBuildStepExecutor', () => {
135
+ test('literal destination is embedded in the script unchanged', async () => {
136
+ const executor = new XcodeBuildStepExecutor();
137
+ const result = await executor.execute({
138
+ project_path: 'MyApp.xcodeproj',
139
+ scheme: 'MyApp',
140
+ destination: 'platform=iOS Simulator,name=iPhone 99,OS=99.0',
141
+ }, {}, testConfig);
142
+ expect(result.script).toContain('platform=iOS Simulator,name=iPhone 99,OS=99.0');
143
+ });
144
+ test('validation requires xcrun only when destination === "auto"', () => {
145
+ const executor = new XcodeBuildStepExecutor();
146
+ const autoReqs = executor.getValidationRequirements({ project_path: 'MyApp.xcodeproj', scheme: 'MyApp', destination: 'auto' }, {}, testConfig);
147
+ expect(xcrunReq(autoReqs)).toBeDefined();
148
+ const literalReqs = executor.getValidationRequirements({
149
+ project_path: 'MyApp.xcodeproj',
150
+ scheme: 'MyApp',
151
+ destination: 'platform=iOS Simulator,name=iPhone 16,OS=18.0',
152
+ }, {}, testConfig);
153
+ expect(xcrunReq(literalReqs)).toBeUndefined();
154
+ const defaultReqs = executor.getValidationRequirements({ project_path: 'MyApp.xcodeproj', scheme: 'MyApp' }, {}, testConfig);
155
+ expect(xcrunReq(defaultReqs)).toBeUndefined();
156
+ });
157
+ });
158
+ describe('XcodeTestStepExecutor', () => {
159
+ test('literal destination is embedded in the script unchanged', async () => {
160
+ const executor = new XcodeTestStepExecutor();
161
+ const result = await executor.execute({
162
+ project_path: 'MyApp.xcodeproj',
163
+ scheme: 'MyApp',
164
+ destination: 'platform=iOS Simulator,name=iPhone 99,OS=99.0',
165
+ }, {}, testConfig);
166
+ expect(result.script).toContain('platform=iOS Simulator,name=iPhone 99,OS=99.0');
167
+ });
168
+ test('validation requires xcrun only when destination === "auto"', () => {
169
+ const executor = new XcodeTestStepExecutor();
170
+ const autoReqs = executor.getValidationRequirements({ project_path: 'MyApp.xcodeproj', scheme: 'MyApp', destination: 'auto' }, {}, testConfig);
171
+ expect(xcrunReq(autoReqs)).toBeDefined();
172
+ const literalReqs = executor.getValidationRequirements({ project_path: 'MyApp.xcodeproj', scheme: 'MyApp' }, {}, testConfig);
173
+ expect(xcrunReq(literalReqs)).toBeUndefined();
174
+ });
175
+ });
176
+ describe('XcodeBuildForTestStepExecutor', () => {
177
+ test('literal destination is embedded in the script unchanged', async () => {
178
+ const executor = new XcodeBuildForTestStepExecutor();
179
+ const result = await executor.execute({
180
+ project_path: 'MyApp.xcodeproj',
181
+ scheme: 'MyApp',
182
+ destination: 'generic/platform=iOS Simulator',
183
+ }, {}, testConfig);
184
+ expect(result.script).toContain('generic/platform=iOS Simulator');
185
+ });
186
+ test('validation requires xcrun only when destination === "auto"', () => {
187
+ const executor = new XcodeBuildForTestStepExecutor();
188
+ const autoReqs = executor.getValidationRequirements({ project_path: 'MyApp.xcodeproj', scheme: 'MyApp', destination: 'auto' }, {}, testConfig);
189
+ expect(xcrunReq(autoReqs)).toBeDefined();
190
+ const literalReqs = executor.getValidationRequirements({ project_path: 'MyApp.xcodeproj', scheme: 'MyApp' }, {}, testConfig);
191
+ expect(xcrunReq(literalReqs)).toBeUndefined();
192
+ });
193
+ });
194
+ describe('XcodeTestWithoutBuildingStepExecutor', () => {
195
+ test('literal destination is embedded in the script unchanged', async () => {
196
+ const executor = new XcodeTestWithoutBuildingStepExecutor();
197
+ const result = await executor.execute({ destination: 'platform=iOS Simulator,name=iPhone 99,OS=99.0' }, {}, testConfig);
198
+ expect(result.script).toContain('platform=iOS Simulator,name=iPhone 99,OS=99.0');
199
+ });
200
+ test('validation requires xcrun only when destination === "auto"', () => {
201
+ const executor = new XcodeTestWithoutBuildingStepExecutor();
202
+ const autoReqs = executor.getValidationRequirements({ destination: 'auto' }, {}, testConfig);
203
+ expect(xcrunReq(autoReqs)).toBeDefined();
204
+ const literalReqs = executor.getValidationRequirements({}, {}, testConfig);
205
+ expect(xcrunReq(literalReqs)).toBeUndefined();
206
+ });
207
+ });
208
+ describe('XcodeBuildForSimulatorStepExecutor', () => {
209
+ test('literal destination is embedded in the script unchanged', async () => {
210
+ const executor = new XcodeBuildForSimulatorStepExecutor();
211
+ const result = await executor.execute({
212
+ project_path: 'MyApp.xcodeproj',
213
+ scheme: 'MyApp',
214
+ destination: 'generic/platform=watchOS Simulator',
215
+ }, {}, testConfig);
216
+ expect(result.script).toContain('generic/platform=watchOS Simulator');
217
+ });
218
+ test('validation requires xcrun only when destination === "auto"', () => {
219
+ const executor = new XcodeBuildForSimulatorStepExecutor();
220
+ const autoReqs = executor.getValidationRequirements({ project_path: 'MyApp.xcodeproj', scheme: 'MyApp', destination: 'auto' }, {}, testConfig);
221
+ expect(xcrunReq(autoReqs)).toBeDefined();
222
+ const literalReqs = executor.getValidationRequirements({ project_path: 'MyApp.xcodeproj', scheme: 'MyApp' }, {}, testConfig);
223
+ expect(xcrunReq(literalReqs)).toBeUndefined();
224
+ });
225
+ });
226
+ });
227
+ //# sourceMappingURL=xcode-destination.test.js.map
@@ -180,7 +180,7 @@ export interface XcodeTestWithoutBuildingInputs {
180
180
  * Runs pre-compiled tests from an .xctestrun file.
181
181
  */
182
182
  export declare class XcodeTestWithoutBuildingStepExecutor extends BaseStepExecutor {
183
- getValidationRequirements(_inputs: XcodeTestWithoutBuildingInputs, _env: Record<string, string>, _config: CIConfig): ValidationRequirement[];
183
+ getValidationRequirements(inputs: XcodeTestWithoutBuildingInputs, _env: Record<string, string>, _config: CIConfig): ValidationRequirement[];
184
184
  getOutputs(): StepOutput[];
185
185
  execute(inputs: XcodeTestWithoutBuildingInputs, _env: Record<string, string>, _config: CIConfig): Promise<StepDef>;
186
186
  }
@@ -1 +1 @@
1
- {"version":3,"file":"xcode.d.ts","sourceRoot":"","sources":["../../../../src/yaml/steps/xcode.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"xcode.d.ts","sourceRoot":"","sources":["../../../../src/yaml/steps/xcode.ts"],"names":[],"mappings":"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"}
@@ -3,6 +3,7 @@
3
3
  */
4
4
  import { existsSync } from 'node:fs';
5
5
  import { BaseStepExecutor } from './base.js';
6
+ import { resolveDestinationInput } from './xcode-destination.js';
6
7
  /**
7
8
  * Xcodebuild step executor
8
9
  * Builds iOS/macOS projects using xcodebuild
@@ -19,6 +20,9 @@ export class XcodeBuildStepExecutor extends BaseStepExecutor {
19
20
  if (inputs.project_path && !existsSync(inputs.project_path)) {
20
21
  requirements.push(this.runtimeRequirement(inputs.project_path, 'Xcode project/workspace file', 'file', 'git-clone'));
21
22
  }
23
+ if (inputs.destination === 'auto') {
24
+ requirements.push(this.requireCommand('xcrun', 'xcrun is required to resolve destination: auto via xcrun simctl', 'Install Xcode and run: xcode-select --install'));
25
+ }
22
26
  return requirements;
23
27
  }
24
28
  async execute(inputs, env, config) {
@@ -33,8 +37,9 @@ export class XcodeBuildStepExecutor extends BaseStepExecutor {
33
37
  const scheme = this.getRequiredInput(inputs, 'scheme', stepName);
34
38
  // Get configuration - defaults to Release
35
39
  const configuration = this.getInput(inputs, 'configuration', 'Release');
36
- // Get destination - defaults to generic/platform=iOS
37
- const destination = this.getInput(inputs, 'destination', 'generic/platform=iOS');
40
+ // Get destination - defaults to generic/platform=iOS.
41
+ // `auto` triggers runtime resolution via `xcrun simctl`.
42
+ const destination = resolveDestinationInput(this.getInput(inputs, 'destination', 'generic/platform=iOS'));
38
43
  // Get output directory - defaults to build
39
44
  const outputDir = this.getInput(inputs, 'output_dir', 'build');
40
45
  // Get clean build flag
@@ -119,6 +124,9 @@ export class XcodeTestStepExecutor extends BaseStepExecutor {
119
124
  if (inputs.project_path && !existsSync(inputs.project_path)) {
120
125
  requirements.push(this.runtimeRequirement(inputs.project_path, 'Xcode project/workspace file', 'file', 'git-clone'));
121
126
  }
127
+ if (inputs.destination === 'auto') {
128
+ requirements.push(this.requireCommand('xcrun', 'xcrun is required to resolve destination: auto via xcrun simctl', 'Install Xcode and run: xcode-select --install'));
129
+ }
122
130
  return requirements;
123
131
  }
124
132
  async execute(inputs, env, config) {
@@ -131,8 +139,9 @@ export class XcodeTestStepExecutor extends BaseStepExecutor {
131
139
  }
132
140
  // Get scheme - required
133
141
  const scheme = this.getRequiredInput(inputs, 'scheme', stepName);
134
- // Get destination - defaults to platform=iOS Simulator
135
- const destination = this.getInput(inputs, 'destination', 'platform=iOS Simulator,name=iPhone 14,OS=latest');
142
+ // Get destination - defaults to platform=iOS Simulator.
143
+ // `auto` triggers runtime resolution via `xcrun simctl`.
144
+ const destination = resolveDestinationInput(this.getInput(inputs, 'destination', 'platform=iOS Simulator,name=iPhone 14,OS=latest'));
136
145
  // Get test plan - optional
137
146
  const testPlan = this.getInput(inputs, 'test_plan', '');
138
147
  // Get code coverage flag
@@ -740,6 +749,9 @@ export class XcodeBuildForTestStepExecutor extends BaseStepExecutor {
740
749
  if (inputs.project_path && !existsSync(inputs.project_path)) {
741
750
  requirements.push(this.runtimeRequirement(inputs.project_path, 'Xcode project/workspace file', 'file', 'git-clone'));
742
751
  }
752
+ if (inputs.destination === 'auto') {
753
+ requirements.push(this.requireCommand('xcrun', 'xcrun is required to resolve destination: auto via xcrun simctl', 'Install Xcode and run: xcode-select --install'));
754
+ }
743
755
  return requirements;
744
756
  }
745
757
  getOutputs() {
@@ -753,7 +765,8 @@ export class XcodeBuildForTestStepExecutor extends BaseStepExecutor {
753
765
  const projectPath = this.getRequiredInput(inputs, 'project_path', stepName);
754
766
  const scheme = this.getRequiredInput(inputs, 'scheme', stepName);
755
767
  const configuration = this.getInput(inputs, 'configuration', 'Debug');
756
- const destination = this.getInput(inputs, 'destination', 'generic/platform=iOS Simulator');
768
+ // `auto` triggers runtime resolution via `xcrun simctl`.
769
+ const destination = resolveDestinationInput(this.getInput(inputs, 'destination', 'generic/platform=iOS Simulator'));
757
770
  const testPlan = this.getInput(inputs, 'test_plan', '');
758
771
  const xcconfigContent = this.getInput(inputs, 'xcconfig_content', '');
759
772
  const xcodebuildOptions = this.getInput(inputs, 'xcodebuild_options', '');
@@ -828,10 +841,14 @@ export class XcodeBuildForTestStepExecutor extends BaseStepExecutor {
828
841
  * Runs pre-compiled tests from an .xctestrun file.
829
842
  */
830
843
  export class XcodeTestWithoutBuildingStepExecutor extends BaseStepExecutor {
831
- getValidationRequirements(_inputs, _env, _config) {
832
- return [
844
+ getValidationRequirements(inputs, _env, _config) {
845
+ const requirements = [
833
846
  this.requireCommand('xcodebuild', 'Xcode Command Line Tools are required', 'Install Xcode, then run: xcode-select --install'),
834
847
  ];
848
+ if (inputs.destination === 'auto') {
849
+ requirements.push(this.requireCommand('xcrun', 'xcrun is required to resolve destination: auto via xcrun simctl', 'Install Xcode and run: xcode-select --install'));
850
+ }
851
+ return requirements;
835
852
  }
836
853
  getOutputs() {
837
854
  return [
@@ -841,7 +858,8 @@ export class XcodeTestWithoutBuildingStepExecutor extends BaseStepExecutor {
841
858
  async execute(inputs, _env, _config) {
842
859
  const stepName = 'xcode-test-without-building';
843
860
  const xctestrun = this.getInput(inputs, 'xctestrun', '$CIBUILD_XCTESTRUN_FILE_PATH');
844
- const destination = this.getInput(inputs, 'destination', 'platform=iOS Simulator,name=iPhone 15,OS=latest');
861
+ // `auto` triggers runtime resolution via `xcrun simctl`.
862
+ const destination = resolveDestinationInput(this.getInput(inputs, 'destination', 'platform=iOS Simulator,name=iPhone 15,OS=latest'));
845
863
  const onlyTesting = this.getInput(inputs, 'only_testing', '');
846
864
  const skipTesting = this.getInput(inputs, 'skip_testing', '');
847
865
  const repetitionMode = this.getInput(inputs, 'test_repetition_mode', 'none');
@@ -920,6 +938,9 @@ export class XcodeBuildForSimulatorStepExecutor extends BaseStepExecutor {
920
938
  if (inputs.project_path && !existsSync(inputs.project_path)) {
921
939
  requirements.push(this.runtimeRequirement(inputs.project_path, 'Xcode project/workspace file', 'file', 'git-clone'));
922
940
  }
941
+ if (inputs.destination === 'auto') {
942
+ requirements.push(this.requireCommand('xcrun', 'xcrun is required to resolve destination: auto via xcrun simctl', 'Install Xcode and run: xcode-select --install'));
943
+ }
923
944
  return requirements;
924
945
  }
925
946
  getOutputs() {
@@ -932,7 +953,8 @@ export class XcodeBuildForSimulatorStepExecutor extends BaseStepExecutor {
932
953
  const projectPath = this.getRequiredInput(inputs, 'project_path', stepName);
933
954
  const scheme = this.getRequiredInput(inputs, 'scheme', stepName);
934
955
  const configuration = this.getInput(inputs, 'configuration', '');
935
- const destination = this.getInput(inputs, 'destination', 'generic/platform=iOS Simulator');
956
+ // `auto` triggers runtime resolution via `xcrun simctl`.
957
+ const destination = resolveDestinationInput(this.getInput(inputs, 'destination', 'generic/platform=iOS Simulator'));
936
958
  const performClean = this.getInput(inputs, 'perform_clean_action', 'no');
937
959
  const xcconfigContent = this.getInput(inputs, 'xcconfig_content', 'CODE_SIGNING_ALLOWED=NO');
938
960
  const xcodebuildOptions = this.getInput(inputs, 'xcodebuild_options', '');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@invarn/cibuild",
3
- "version": "1.8.0",
3
+ "version": "1.9.0",
4
4
  "description": "CI Build CLI — local pipeline orchestration and validation",
5
5
  "type": "module",
6
6
  "main": "dist/cli.cjs",