@invarn/cibuild 2.9.1 → 2.9.4
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 +173 -11
- package/dist/src/yaml/steps/android.d.ts.map +1 -1
- package/dist/src/yaml/steps/android.js +5 -0
- package/dist/src/yaml/steps/cocoapods-deployment-floor.d.ts +42 -0
- package/dist/src/yaml/steps/cocoapods-deployment-floor.d.ts.map +1 -0
- package/dist/src/yaml/steps/cocoapods-deployment-floor.js +140 -0
- package/dist/src/yaml/steps/cocoapods-deployment-floor.test.d.ts +11 -0
- package/dist/src/yaml/steps/cocoapods-deployment-floor.test.d.ts.map +1 -0
- package/dist/src/yaml/steps/cocoapods-deployment-floor.test.js +176 -0
- package/dist/src/yaml/steps/gradle-sdk-cmake.d.ts +28 -0
- package/dist/src/yaml/steps/gradle-sdk-cmake.d.ts.map +1 -0
- package/dist/src/yaml/steps/gradle-sdk-cmake.js +107 -0
- package/dist/src/yaml/steps/gradle-sdk-cmake.test.d.ts +2 -0
- package/dist/src/yaml/steps/gradle-sdk-cmake.test.d.ts.map +1 -0
- package/dist/src/yaml/steps/gradle-sdk-cmake.test.js +183 -0
- package/dist/src/yaml/steps/ios-deps.d.ts.map +1 -1
- package/dist/src/yaml/steps/ios-deps.js +2 -0
- package/dist/src/yaml/steps/xcode-derived-data.test.js +18 -1
- package/dist/src/yaml/steps/xcode-simulator-archs.d.ts +53 -0
- package/dist/src/yaml/steps/xcode-simulator-archs.d.ts.map +1 -0
- package/dist/src/yaml/steps/xcode-simulator-archs.js +98 -0
- package/dist/src/yaml/steps/xcode-simulator-archs.test.d.ts +21 -0
- package/dist/src/yaml/steps/xcode-simulator-archs.test.d.ts.map +1 -0
- package/dist/src/yaml/steps/xcode-simulator-archs.test.js +155 -0
- package/dist/src/yaml/steps/xcode.d.ts.map +1 -1
- package/dist/src/yaml/steps/xcode.js +31 -2
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"android.d.ts","sourceRoot":"","sources":["../../../../src/yaml/steps/android.ts"],"names":[],"mappings":"AAAA;;GAEG;AAUH,OAAO,EAAE,gBAAgB,EAAuB,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"android.d.ts","sourceRoot":"","sources":["../../../../src/yaml/steps/android.ts"],"names":[],"mappings":"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"}
|
|
@@ -10,6 +10,7 @@ import { existsSync, readFileSync } from 'node:fs';
|
|
|
10
10
|
import { execSync } from 'node:child_process';
|
|
11
11
|
import { BaseStepExecutor, javaHomeVersionSpec } from './base.js';
|
|
12
12
|
import { gradleMemoryCommands } from './gradle-memory.js';
|
|
13
|
+
import { gradleSdkCmakeCommands } from './gradle-sdk-cmake.js';
|
|
13
14
|
/**
|
|
14
15
|
* Set Java version step executor
|
|
15
16
|
* Sets the Java version to use for Android builds
|
|
@@ -461,6 +462,7 @@ export class GradleBuildStepExecutor extends BaseStepExecutor {
|
|
|
461
462
|
commands.push(' exit 1');
|
|
462
463
|
commands.push('fi');
|
|
463
464
|
commands.push(...gradleMemoryCommands(this.getInput(inputs, 'jvmargs', ''), (v) => this.escapeBash(v), String(this.getInput(inputs, 'max_workers', '')).trim()));
|
|
465
|
+
commands.push(...gradleSdkCmakeCommands());
|
|
464
466
|
// Build gradle command
|
|
465
467
|
commands.push('');
|
|
466
468
|
commands.push('# Timestamp marker — used to collect only artifacts from this build');
|
|
@@ -783,6 +785,7 @@ export class AndroidLintStepExecutor extends BaseStepExecutor {
|
|
|
783
785
|
commands.push(' exit 1');
|
|
784
786
|
commands.push('fi');
|
|
785
787
|
commands.push(...gradleMemoryCommands(this.getInput(inputs, 'jvmargs', ''), (v) => this.escapeBash(v), String(this.getInput(inputs, 'max_workers', '')).trim()));
|
|
788
|
+
commands.push(...gradleSdkCmakeCommands());
|
|
786
789
|
// Build lint task name
|
|
787
790
|
commands.push('');
|
|
788
791
|
commands.push('# Run lint');
|
|
@@ -973,6 +976,7 @@ export class AndroidUnitTestStepExecutor extends BaseStepExecutor {
|
|
|
973
976
|
commands.push(' exit 1');
|
|
974
977
|
commands.push('fi');
|
|
975
978
|
commands.push(...gradleMemoryCommands(this.getInput(inputs, 'jvmargs', ''), (v) => this.escapeBash(v), String(this.getInput(inputs, 'max_workers', '')).trim()));
|
|
979
|
+
commands.push(...gradleSdkCmakeCommands());
|
|
976
980
|
// Build test task name
|
|
977
981
|
commands.push('');
|
|
978
982
|
commands.push('# Run unit tests');
|
|
@@ -1041,6 +1045,7 @@ export class AndroidBuildForUITestingStepExecutor extends BaseStepExecutor {
|
|
|
1041
1045
|
commands.push(' GRADLE_CMD="gradle"');
|
|
1042
1046
|
commands.push('fi');
|
|
1043
1047
|
commands.push(...gradleMemoryCommands(this.getInput(inputs, 'jvmargs', ''), (v) => this.escapeBash(v), String(this.getInput(inputs, 'max_workers', '')).trim()));
|
|
1048
|
+
commands.push(...gradleSdkCmakeCommands());
|
|
1044
1049
|
commands.push('');
|
|
1045
1050
|
// Build both app and test APKs
|
|
1046
1051
|
const appTask = gradleTaskPath(this.escapeBash(module), `assemble${variantCap}`);
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* After `pod install`: raise every pod target whose deployment target is below
|
|
3
|
+
* the app's own to the app's.
|
|
4
|
+
*
|
|
5
|
+
* A pod target below iOS 9 links ARC Lite, and Xcode 14.3 removed
|
|
6
|
+
* `libarclite`: `clang: error: SDK does not contain 'libarclite' at …
|
|
7
|
+
* libarclite_iphonesimulator.a; try increasing the minimum deployment
|
|
8
|
+
* target`. CocoaPods gives each pod target the deployment target its podspec
|
|
9
|
+
* declares, so an old pod (SwiftLinkPreview 3.1.0, `ios: '8.0'`) stops an app
|
|
10
|
+
* that itself targets iOS 12 (YuigaWada/MissCat, nightly-baseline issue 53).
|
|
11
|
+
* The usual fix lives in the app's own Podfile, a `post_install` that raises
|
|
12
|
+
* the pods; a repository whose Podfile has none cannot build under any
|
|
13
|
+
* current Xcode.
|
|
14
|
+
*
|
|
15
|
+
* RULED 2026-10-01 (Alex): raise every pod target below the app target's own
|
|
16
|
+
* deployment target to it, in the step, always. Never the app target, never
|
|
17
|
+
* past what the app promises: the floor is the lowest deployment target among
|
|
18
|
+
* the user targets CocoaPods integrated (each found by its `Pods-*.xcconfig`
|
|
19
|
+
* base configuration), so an extension that targets lower than the app keeps
|
|
20
|
+
* its pods buildable for it. A pod cannot run below the app that embeds it, so
|
|
21
|
+
* the raise changes nothing a user of the app could observe. Only the
|
|
22
|
+
* generated `Pods/*.xcodeproj` is edited; it is the checkout's, never
|
|
23
|
+
* committed back.
|
|
24
|
+
*
|
|
25
|
+
* Measured on a clone, Xcode 26.4, 2026-10-01: MissCat @ 574355469ebb, app
|
|
26
|
+
* targets MissCat and MissCatShare at 12.0, 74 pod build configurations raised
|
|
27
|
+
* from 8.0–9.3; SwiftLinkPreview then compiled at ios12.0-simulator and the
|
|
28
|
+
* build log never mentioned libarclite.
|
|
29
|
+
*
|
|
30
|
+
* Never a reason the step fails: a Ruby that cannot load `xcodeproj`, a Pods
|
|
31
|
+
* project it cannot read, a workspace it cannot find — each is a line in the
|
|
32
|
+
* log and the pods as CocoaPods left them.
|
|
33
|
+
*/
|
|
34
|
+
/** Ruby; argv[0] is the Pods directory. Prints what it read and what it raised. */
|
|
35
|
+
export declare const POD_DEPLOYMENT_FLOOR_SOURCE: string;
|
|
36
|
+
/**
|
|
37
|
+
* Bash lines that run the raise in the step's directory, after `pod install`.
|
|
38
|
+
* They expect `$USE_BUNDLE_EXEC` and `$BUNDLE_CMD` from the step, and never
|
|
39
|
+
* fail it.
|
|
40
|
+
*/
|
|
41
|
+
export declare function podDeploymentFloorLines(): string[];
|
|
42
|
+
//# sourceMappingURL=cocoapods-deployment-floor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cocoapods-deployment-floor.d.ts","sourceRoot":"","sources":["../../../../src/yaml/steps/cocoapods-deployment-floor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAEH,mFAAmF;AACnF,eAAO,MAAM,2BAA2B,EAAE,MAgEzC,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,uBAAuB,IAAI,MAAM,EAAE,CAkClD"}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* After `pod install`: raise every pod target whose deployment target is below
|
|
3
|
+
* the app's own to the app's.
|
|
4
|
+
*
|
|
5
|
+
* A pod target below iOS 9 links ARC Lite, and Xcode 14.3 removed
|
|
6
|
+
* `libarclite`: `clang: error: SDK does not contain 'libarclite' at …
|
|
7
|
+
* libarclite_iphonesimulator.a; try increasing the minimum deployment
|
|
8
|
+
* target`. CocoaPods gives each pod target the deployment target its podspec
|
|
9
|
+
* declares, so an old pod (SwiftLinkPreview 3.1.0, `ios: '8.0'`) stops an app
|
|
10
|
+
* that itself targets iOS 12 (YuigaWada/MissCat, nightly-baseline issue 53).
|
|
11
|
+
* The usual fix lives in the app's own Podfile, a `post_install` that raises
|
|
12
|
+
* the pods; a repository whose Podfile has none cannot build under any
|
|
13
|
+
* current Xcode.
|
|
14
|
+
*
|
|
15
|
+
* RULED 2026-10-01 (Alex): raise every pod target below the app target's own
|
|
16
|
+
* deployment target to it, in the step, always. Never the app target, never
|
|
17
|
+
* past what the app promises: the floor is the lowest deployment target among
|
|
18
|
+
* the user targets CocoaPods integrated (each found by its `Pods-*.xcconfig`
|
|
19
|
+
* base configuration), so an extension that targets lower than the app keeps
|
|
20
|
+
* its pods buildable for it. A pod cannot run below the app that embeds it, so
|
|
21
|
+
* the raise changes nothing a user of the app could observe. Only the
|
|
22
|
+
* generated `Pods/*.xcodeproj` is edited; it is the checkout's, never
|
|
23
|
+
* committed back.
|
|
24
|
+
*
|
|
25
|
+
* Measured on a clone, Xcode 26.4, 2026-10-01: MissCat @ 574355469ebb, app
|
|
26
|
+
* targets MissCat and MissCatShare at 12.0, 74 pod build configurations raised
|
|
27
|
+
* from 8.0–9.3; SwiftLinkPreview then compiled at ios12.0-simulator and the
|
|
28
|
+
* build log never mentioned libarclite.
|
|
29
|
+
*
|
|
30
|
+
* Never a reason the step fails: a Ruby that cannot load `xcodeproj`, a Pods
|
|
31
|
+
* project it cannot read, a workspace it cannot find — each is a line in the
|
|
32
|
+
* log and the pods as CocoaPods left them.
|
|
33
|
+
*/
|
|
34
|
+
/** Ruby; argv[0] is the Pods directory. Prints what it read and what it raised. */
|
|
35
|
+
export const POD_DEPLOYMENT_FLOOR_SOURCE = String.raw `
|
|
36
|
+
require 'xcodeproj'
|
|
37
|
+
pods_dir = File.expand_path(ARGV[0] || 'Pods')
|
|
38
|
+
pod_projects = Dir.glob(File.join(pods_dir, '*.xcodeproj'))
|
|
39
|
+
if pod_projects.empty?
|
|
40
|
+
puts "No Pods project under #{pods_dir}; pods' deployment targets left as they are"
|
|
41
|
+
exit 0
|
|
42
|
+
end
|
|
43
|
+
root = File.expand_path('..', pods_dir)
|
|
44
|
+
KEYS = %w[IPHONEOS_DEPLOYMENT_TARGET MACOSX_DEPLOYMENT_TARGET TVOS_DEPLOYMENT_TARGET WATCHOS_DEPLOYMENT_TARGET XROS_DEPLOYMENT_TARGET]
|
|
45
|
+
def version_of(value)
|
|
46
|
+
value.to_s.strip =~ /\A\d+(\.\d+){0,2}\z/ ? Gem::Version.new(value.to_s.strip) : nil
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
floors = {}
|
|
50
|
+
Dir.glob(File.join(root, '*.xcworkspace')).each do |ws|
|
|
51
|
+
Xcodeproj::Workspace.new_from_xcworkspace(ws).file_references.each do |ref|
|
|
52
|
+
path = File.expand_path(ref.absolute_path(File.expand_path('..', ws)))
|
|
53
|
+
next if path.start_with?(pods_dir + File::SEPARATOR) || !File.directory?(path)
|
|
54
|
+
project = Xcodeproj::Project.open(path)
|
|
55
|
+
project.native_targets.each do |target|
|
|
56
|
+
target.build_configurations.each do |config|
|
|
57
|
+
base = config.base_configuration_reference
|
|
58
|
+
next unless base && File.basename(base.path.to_s) =~ /\APods-.*\.xcconfig\z/
|
|
59
|
+
project_settings = project.build_configuration_list.build_settings(config.name) || {}
|
|
60
|
+
KEYS.each do |key|
|
|
61
|
+
v = version_of(config.build_settings[key]) || version_of(project_settings[key])
|
|
62
|
+
next unless v
|
|
63
|
+
floors[key] = v if floors[key].nil? || v < floors[key]
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
if floors.empty?
|
|
70
|
+
puts "No app target CocoaPods integrated declares a deployment target; pods' deployment targets left as they are"
|
|
71
|
+
exit 0
|
|
72
|
+
end
|
|
73
|
+
puts "The app's own deployment target: #{floors.map { |k, v| "#{k} #{v}" }.join(', ')}"
|
|
74
|
+
|
|
75
|
+
raised = []
|
|
76
|
+
pod_projects.each do |path|
|
|
77
|
+
project = Xcodeproj::Project.open(path)
|
|
78
|
+
changed = false
|
|
79
|
+
project.targets.each do |target|
|
|
80
|
+
next if target.name.start_with?('Pods-')
|
|
81
|
+
target.build_configurations.each do |config|
|
|
82
|
+
floors.each do |key, floor|
|
|
83
|
+
v = version_of(config.build_settings[key])
|
|
84
|
+
next unless v && v < floor
|
|
85
|
+
config.build_settings[key] = floor.to_s
|
|
86
|
+
raised << "#{target.name} #{v}"
|
|
87
|
+
changed = true
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
project.save if changed
|
|
92
|
+
end
|
|
93
|
+
if raised.empty?
|
|
94
|
+
puts "No pod target is below it"
|
|
95
|
+
else
|
|
96
|
+
names = raised.uniq
|
|
97
|
+
puts "Raised #{names.size} pod target(s) below the app's deployment target to it: #{names.join(', ')}"
|
|
98
|
+
end
|
|
99
|
+
`;
|
|
100
|
+
/**
|
|
101
|
+
* Bash lines that run the raise in the step's directory, after `pod install`.
|
|
102
|
+
* They expect `$USE_BUNDLE_EXEC` and `$BUNDLE_CMD` from the step, and never
|
|
103
|
+
* fail it.
|
|
104
|
+
*/
|
|
105
|
+
export function podDeploymentFloorLines() {
|
|
106
|
+
return [
|
|
107
|
+
"# Raise pods below the app's own deployment target to it — see",
|
|
108
|
+
'# cocoapods-deployment-floor.ts. Never fails the step.',
|
|
109
|
+
'if [ -d Pods ]; then',
|
|
110
|
+
' POD_FLOOR_SCRIPT="$(mktemp -t cibuild-pod-floor).rb"',
|
|
111
|
+
` cat > "$POD_FLOOR_SCRIPT" << 'CIBUILD_POD_FLOOR_EOF'`,
|
|
112
|
+
POD_DEPLOYMENT_FLOOR_SOURCE.trim(),
|
|
113
|
+
'CIBUILD_POD_FLOOR_EOF',
|
|
114
|
+
' # A Ruby that can load xcodeproj: the bundle CocoaPods ran from, the',
|
|
115
|
+
" # ruby on PATH, or a Homebrew pod wrapper's own interpreter and gems.",
|
|
116
|
+
' POD_FLOOR_RUN=""',
|
|
117
|
+
' if [ "$USE_BUNDLE_EXEC" = "true" ] && $BUNDLE_CMD exec ruby -e "require %q(xcodeproj)" >/dev/null 2>&1; then',
|
|
118
|
+
' POD_FLOOR_RUN="$BUNDLE_CMD exec ruby"',
|
|
119
|
+
' elif ruby -e "require %q(xcodeproj)" >/dev/null 2>&1; then',
|
|
120
|
+
' POD_FLOOR_RUN="ruby"',
|
|
121
|
+
' else',
|
|
122
|
+
' POD_WRAPPER="$(command -v pod 2>/dev/null || true)"',
|
|
123
|
+
' POD_GEM_HOME="$( [ -n "$POD_WRAPPER" ] && sed -n \'s/^GEM_HOME="\\([^"]*\\)".*/\\1/p\' "$POD_WRAPPER" | head -n 1)"',
|
|
124
|
+
' POD_REAL="$( [ -n "$POD_WRAPPER" ] && sed -n \'s/.*exec "\\([^"]*\\)".*/\\1/p\' "$POD_WRAPPER" | head -n 1)"',
|
|
125
|
+
' POD_RUBY="$( [ -n "$POD_REAL" ] && [ -f "$POD_REAL" ] && head -n 1 "$POD_REAL" | sed -n \'s/^#!//p\')"',
|
|
126
|
+
' if [ -n "$POD_GEM_HOME" ] && [ -n "$POD_RUBY" ] && GEM_HOME="$POD_GEM_HOME" $POD_RUBY -e "require %q(xcodeproj)" >/dev/null 2>&1; then',
|
|
127
|
+
' POD_FLOOR_RUN="env GEM_HOME=$POD_GEM_HOME $POD_RUBY"',
|
|
128
|
+
' fi',
|
|
129
|
+
' fi',
|
|
130
|
+
' if [ -n "$POD_FLOOR_RUN" ]; then',
|
|
131
|
+
' $POD_FLOOR_RUN "$POD_FLOOR_SCRIPT" Pods || echo "⚠️ Could not raise pods to the app\'s deployment target; left as CocoaPods wrote them"',
|
|
132
|
+
' else',
|
|
133
|
+
' echo "⚠️ No Ruby here loads xcodeproj; pods\' deployment targets left as CocoaPods wrote them"',
|
|
134
|
+
' fi',
|
|
135
|
+
' rm -f "$POD_FLOOR_SCRIPT"',
|
|
136
|
+
'fi',
|
|
137
|
+
'',
|
|
138
|
+
];
|
|
139
|
+
}
|
|
140
|
+
//# sourceMappingURL=cocoapods-deployment-floor.js.map
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pods below the app's own deployment target are raised to it, after pod
|
|
3
|
+
* install, and nothing else moves. Witness: YuigaWada/MissCat (nightly-baseline
|
|
4
|
+
* issue 53) — SwiftLinkPreview 3.1.0 at iOS 8.0 linked libarclite, which
|
|
5
|
+
* Xcode 14.3 removed, in an app that targets iOS 12.0.
|
|
6
|
+
*
|
|
7
|
+
* The Ruby runs for real against projects the xcodeproj gem writes, when this
|
|
8
|
+
* machine's ruby can load it; otherwise those tests are skipped and say so.
|
|
9
|
+
*/
|
|
10
|
+
export {};
|
|
11
|
+
//# sourceMappingURL=cocoapods-deployment-floor.test.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cocoapods-deployment-floor.test.d.ts","sourceRoot":"","sources":["../../../../src/yaml/steps/cocoapods-deployment-floor.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG"}
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pods below the app's own deployment target are raised to it, after pod
|
|
3
|
+
* install, and nothing else moves. Witness: YuigaWada/MissCat (nightly-baseline
|
|
4
|
+
* issue 53) — SwiftLinkPreview 3.1.0 at iOS 8.0 linked libarclite, which
|
|
5
|
+
* Xcode 14.3 removed, in an app that targets iOS 12.0.
|
|
6
|
+
*
|
|
7
|
+
* The Ruby runs for real against projects the xcodeproj gem writes, when this
|
|
8
|
+
* machine's ruby can load it; otherwise those tests are skipped and say so.
|
|
9
|
+
*/
|
|
10
|
+
import { describe, test, expect } from '@jest/globals';
|
|
11
|
+
import { execFileSync } from 'node:child_process';
|
|
12
|
+
import { mkdtempSync, readFileSync, rmSync, writeFileSync } from 'node:fs';
|
|
13
|
+
import { tmpdir } from 'node:os';
|
|
14
|
+
import { join } from 'node:path';
|
|
15
|
+
import { POD_DEPLOYMENT_FLOOR_SOURCE, podDeploymentFloorLines } from './cocoapods-deployment-floor.js';
|
|
16
|
+
import { CocoapodsInstallStepExecutor } from './ios-deps.js';
|
|
17
|
+
import { testConfig } from './test-config.js';
|
|
18
|
+
const hasXcodeproj = (() => {
|
|
19
|
+
try {
|
|
20
|
+
execFileSync('ruby', ['-e', 'require %q(xcodeproj)'], { stdio: 'ignore' });
|
|
21
|
+
return true;
|
|
22
|
+
}
|
|
23
|
+
catch {
|
|
24
|
+
return false;
|
|
25
|
+
}
|
|
26
|
+
})();
|
|
27
|
+
/**
|
|
28
|
+
* MissCat's shape: an app at 12.0 and a share extension at 11.0, both
|
|
29
|
+
* integrated by CocoaPods; pods at 8.0 (SwiftLinkPreview), 11.0 and 13.0; a
|
|
30
|
+
* library target in the app's project that CocoaPods does not integrate, at 8.0.
|
|
31
|
+
*/
|
|
32
|
+
const FIXTURE = String.raw `
|
|
33
|
+
require 'xcodeproj'
|
|
34
|
+
require 'fileutils'
|
|
35
|
+
dir = ARGV[0]
|
|
36
|
+
FileUtils.mkdir_p(File.join(dir, 'Pods', 'Target Support Files', 'Pods-App'))
|
|
37
|
+
app = Xcodeproj::Project.new(File.join(dir, 'App.xcodeproj'))
|
|
38
|
+
xc = app.new_file('Pods/Target Support Files/Pods-App/Pods-App.debug.xcconfig')
|
|
39
|
+
[['App', :application, '12.0', true], ['Share', :app_extension, '11.0', true], ['Unpodded', :framework, '8.0', false]].each do |name, type, dt, podded|
|
|
40
|
+
t = app.new_target(type, name, :ios, dt)
|
|
41
|
+
t.build_configurations.each { |c| c.base_configuration_reference = xc if podded }
|
|
42
|
+
end
|
|
43
|
+
app.save
|
|
44
|
+
pods = Xcodeproj::Project.new(File.join(dir, 'Pods', 'Pods.xcodeproj'))
|
|
45
|
+
pods.new_target(:framework, 'Pods-App', :ios, '12.0')
|
|
46
|
+
[['SwiftLinkPreview', '8.0'], ['MidPod', '11.0'], ['NewPod', '13.0']].each { |n, dt| pods.new_target(:framework, n, :ios, dt) }
|
|
47
|
+
pods.save
|
|
48
|
+
ws = Xcodeproj::Workspace.new(nil)
|
|
49
|
+
ws << 'App.xcodeproj'
|
|
50
|
+
ws << 'Pods/Pods.xcodeproj'
|
|
51
|
+
ws.save_as(File.join(dir, 'App.xcworkspace'))
|
|
52
|
+
`;
|
|
53
|
+
const DUMP = String.raw `
|
|
54
|
+
require 'xcodeproj'
|
|
55
|
+
p = Xcodeproj::Project.open(ARGV[0])
|
|
56
|
+
p.targets.each { |t| t.build_configurations.each { |c| puts "#{t.name} #{c.name} #{c.build_settings['IPHONEOS_DEPLOYMENT_TARGET']}" } }
|
|
57
|
+
`;
|
|
58
|
+
const ruby = (source, args, cwd) => {
|
|
59
|
+
const dir = mkdtempSync(join(tmpdir(), 'pod-floor-rb-'));
|
|
60
|
+
try {
|
|
61
|
+
const f = join(dir, 's.rb');
|
|
62
|
+
writeFileSync(f, source);
|
|
63
|
+
return execFileSync('ruby', [f, ...args], { encoding: 'utf8', cwd });
|
|
64
|
+
}
|
|
65
|
+
finally {
|
|
66
|
+
rmSync(dir, { recursive: true, force: true });
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
(hasXcodeproj ? describe : describe.skip)('the raise, on projects the xcodeproj gem wrote', () => {
|
|
70
|
+
const withFixture = (fn) => {
|
|
71
|
+
const dir = mkdtempSync(join(tmpdir(), 'pod-floor-'));
|
|
72
|
+
try {
|
|
73
|
+
ruby(FIXTURE, [dir]);
|
|
74
|
+
fn(dir);
|
|
75
|
+
}
|
|
76
|
+
finally {
|
|
77
|
+
rmSync(dir, { recursive: true, force: true });
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
const settings = (projectPath) => Object.fromEntries(ruby(DUMP, [projectPath])
|
|
81
|
+
.trim()
|
|
82
|
+
.split('\n')
|
|
83
|
+
.map((l) => {
|
|
84
|
+
const [t, c, v] = l.split(' ');
|
|
85
|
+
return [`${t} ${c}`, v];
|
|
86
|
+
}));
|
|
87
|
+
test('raises pods below the lowest integrated user target to it, and only those', () => {
|
|
88
|
+
withFixture((dir) => {
|
|
89
|
+
const out = ruby(POD_DEPLOYMENT_FLOOR_SOURCE, ['Pods'], dir);
|
|
90
|
+
const pods = settings(join(dir, 'Pods', 'Pods.xcodeproj'));
|
|
91
|
+
// The floor is the share extension's 11.0, the lowest the app promises.
|
|
92
|
+
expect(pods['SwiftLinkPreview Debug']).toBe('11.0');
|
|
93
|
+
expect(pods['SwiftLinkPreview Release']).toBe('11.0');
|
|
94
|
+
expect(pods['MidPod Debug']).toBe('11.0');
|
|
95
|
+
expect(pods['NewPod Debug']).toBe('13.0');
|
|
96
|
+
expect(pods['Pods-App Debug']).toBe('12.0');
|
|
97
|
+
expect(out).toContain('IPHONEOS_DEPLOYMENT_TARGET 11.0');
|
|
98
|
+
expect(out).toContain('Raised 1 pod target(s)');
|
|
99
|
+
expect(out).toContain('SwiftLinkPreview 8.0');
|
|
100
|
+
});
|
|
101
|
+
});
|
|
102
|
+
test("never touches the app's own project, not even a target CocoaPods does not integrate", () => {
|
|
103
|
+
withFixture((dir) => {
|
|
104
|
+
const before = readFileSync(join(dir, 'App.xcodeproj', 'project.pbxproj'), 'utf8');
|
|
105
|
+
ruby(POD_DEPLOYMENT_FLOOR_SOURCE, ['Pods'], dir);
|
|
106
|
+
expect(readFileSync(join(dir, 'App.xcodeproj', 'project.pbxproj'), 'utf8')).toBe(before);
|
|
107
|
+
// ...and the unintegrated 8.0 library is not the floor: the pod was raised.
|
|
108
|
+
expect(settings(join(dir, 'Pods', 'Pods.xcodeproj'))['SwiftLinkPreview Debug']).toBe('11.0');
|
|
109
|
+
});
|
|
110
|
+
});
|
|
111
|
+
test('a second run changes nothing', () => {
|
|
112
|
+
withFixture((dir) => {
|
|
113
|
+
ruby(POD_DEPLOYMENT_FLOOR_SOURCE, ['Pods'], dir);
|
|
114
|
+
const once = readFileSync(join(dir, 'Pods', 'Pods.xcodeproj', 'project.pbxproj'), 'utf8');
|
|
115
|
+
expect(ruby(POD_DEPLOYMENT_FLOOR_SOURCE, ['Pods'], dir)).toContain('No pod target is below it');
|
|
116
|
+
expect(readFileSync(join(dir, 'Pods', 'Pods.xcodeproj', 'project.pbxproj'), 'utf8')).toBe(once);
|
|
117
|
+
});
|
|
118
|
+
});
|
|
119
|
+
test('no workspace to read the app from: says so, raises nothing, exits 0', () => {
|
|
120
|
+
withFixture((dir) => {
|
|
121
|
+
rmSync(join(dir, 'App.xcworkspace'), { recursive: true, force: true });
|
|
122
|
+
const before = readFileSync(join(dir, 'Pods', 'Pods.xcodeproj', 'project.pbxproj'), 'utf8');
|
|
123
|
+
expect(ruby(POD_DEPLOYMENT_FLOOR_SOURCE, ['Pods'], dir)).toContain('left as they are');
|
|
124
|
+
expect(readFileSync(join(dir, 'Pods', 'Pods.xcodeproj', 'project.pbxproj'), 'utf8')).toBe(before);
|
|
125
|
+
});
|
|
126
|
+
});
|
|
127
|
+
});
|
|
128
|
+
if (!hasXcodeproj) {
|
|
129
|
+
test.skip('the raise on real projects — this ruby cannot load xcodeproj', () => { });
|
|
130
|
+
}
|
|
131
|
+
describe('cocoapods-install runs the raise after pod install', () => {
|
|
132
|
+
const script = async (inputs = {}) => (await new CocoapodsInstallStepExecutor().execute(inputs, {}, testConfig)).script;
|
|
133
|
+
test('after the pod command, before the step reports done', async () => {
|
|
134
|
+
const s = await script();
|
|
135
|
+
const raise = s.indexOf('cibuild-pod-floor');
|
|
136
|
+
expect(raise).toBeGreaterThan(s.indexOf('$POD_INVOCATION $POD_CMD'));
|
|
137
|
+
expect(raise).toBeLessThan(s.indexOf('✅ CocoaPods'));
|
|
138
|
+
});
|
|
139
|
+
test('carries the Ruby verbatim, in a quoted heredoc', async () => {
|
|
140
|
+
const s = await script();
|
|
141
|
+
expect(s).toContain(`<< 'CIBUILD_POD_FLOOR_EOF'`);
|
|
142
|
+
expect(s).toContain(POD_DEPLOYMENT_FLOOR_SOURCE.trim());
|
|
143
|
+
});
|
|
144
|
+
test('never fails the step', () => {
|
|
145
|
+
const lines = podDeploymentFloorLines().join('\n');
|
|
146
|
+
expect(lines).toContain('|| echo "⚠️ Could not raise pods');
|
|
147
|
+
expect(lines).not.toMatch(/\bexit 1\b/);
|
|
148
|
+
});
|
|
149
|
+
test('the emitted script is valid bash', async () => {
|
|
150
|
+
const dir = mkdtempSync(join(tmpdir(), 'pod-floor-sh-'));
|
|
151
|
+
try {
|
|
152
|
+
const f = join(dir, 's.sh');
|
|
153
|
+
writeFileSync(f, await script({ skip_if_absent: true }));
|
|
154
|
+
expect(() => execFileSync('bash', ['-n', f])).not.toThrow();
|
|
155
|
+
}
|
|
156
|
+
finally {
|
|
157
|
+
rmSync(dir, { recursive: true, force: true });
|
|
158
|
+
}
|
|
159
|
+
});
|
|
160
|
+
test('the emitted lines run end to end: the raise happens through the bash', () => {
|
|
161
|
+
if (!hasXcodeproj)
|
|
162
|
+
return;
|
|
163
|
+
const dir = mkdtempSync(join(tmpdir(), 'pod-floor-e2e-'));
|
|
164
|
+
try {
|
|
165
|
+
ruby(FIXTURE, [dir]);
|
|
166
|
+
const f = join(dir, 'raise.sh');
|
|
167
|
+
writeFileSync(f, ['USE_BUNDLE_EXEC=false', 'BUNDLE_CMD=bundle', ...podDeploymentFloorLines()].join('\n'));
|
|
168
|
+
const out = execFileSync('bash', [f], { cwd: dir, encoding: 'utf8' });
|
|
169
|
+
expect(out).toContain('Raised 1 pod target(s)');
|
|
170
|
+
}
|
|
171
|
+
finally {
|
|
172
|
+
rmSync(dir, { recursive: true, force: true });
|
|
173
|
+
}
|
|
174
|
+
});
|
|
175
|
+
});
|
|
176
|
+
//# sourceMappingURL=cocoapods-deployment-floor.test.js.map
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The SDK CMake a build file pins, installed before Gradle runs.
|
|
3
|
+
*
|
|
4
|
+
* A module may pin its CMake (`android { externalNativeBuild { cmake {
|
|
5
|
+
* version = "3.31.6" } } }`). AGP downloads a pinned CMake it lacks, but only
|
|
6
|
+
* when it configures CMake, and a build's own Gradle task can need it first.
|
|
7
|
+
* IacobIonut01/ReFra's `buildHeifEncodeNative*` tasks run
|
|
8
|
+
* `scripts/native/build-heif-encode.sh`, which requires
|
|
9
|
+
* `$SDK/cmake/3.31.6/bin/cmake` and stops with "cmake 3.31.6 not found". The
|
|
10
|
+
* build images bake no SDK CMake, and a runner image cannot carry every
|
|
11
|
+
* version, so the version the project pins is installed with the SDK's own
|
|
12
|
+
* `sdkmanager` (its licences are accepted when the image is baked).
|
|
13
|
+
*
|
|
14
|
+
* Only literal versions inside a `cmake { }` block count. When there is no SDK
|
|
15
|
+
* or no sdkmanager, or the install fails, one line says so and the step goes
|
|
16
|
+
* on: AGP may still manage on its own.
|
|
17
|
+
*
|
|
18
|
+
* Written as shell functions so what ships is what the tests run. The shell
|
|
19
|
+
* is a raw string with no `${`, so every escape here is the one bash and awk
|
|
20
|
+
* read. Its lines start with "Android SDK:", never with a step-progress marker.
|
|
21
|
+
*/
|
|
22
|
+
export declare const GRADLE_SDK_CMAKE_FUNCTIONS: string;
|
|
23
|
+
/**
|
|
24
|
+
* The commands a Gradle step runs in the project directory before Gradle, so
|
|
25
|
+
* a CMake the project pins is in the SDK when its own tasks look for it.
|
|
26
|
+
*/
|
|
27
|
+
export declare function gradleSdkCmakeCommands(): string[];
|
|
28
|
+
//# sourceMappingURL=gradle-sdk-cmake.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gradle-sdk-cmake.d.ts","sourceRoot":"","sources":["../../../../src/yaml/steps/gradle-sdk-cmake.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,eAAO,MAAM,0BAA0B,QA6ErC,CAAC;AAEH;;;GAGG;AACH,wBAAgB,sBAAsB,IAAI,MAAM,EAAE,CAEjD"}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The SDK CMake a build file pins, installed before Gradle runs.
|
|
3
|
+
*
|
|
4
|
+
* A module may pin its CMake (`android { externalNativeBuild { cmake {
|
|
5
|
+
* version = "3.31.6" } } }`). AGP downloads a pinned CMake it lacks, but only
|
|
6
|
+
* when it configures CMake, and a build's own Gradle task can need it first.
|
|
7
|
+
* IacobIonut01/ReFra's `buildHeifEncodeNative*` tasks run
|
|
8
|
+
* `scripts/native/build-heif-encode.sh`, which requires
|
|
9
|
+
* `$SDK/cmake/3.31.6/bin/cmake` and stops with "cmake 3.31.6 not found". The
|
|
10
|
+
* build images bake no SDK CMake, and a runner image cannot carry every
|
|
11
|
+
* version, so the version the project pins is installed with the SDK's own
|
|
12
|
+
* `sdkmanager` (its licences are accepted when the image is baked).
|
|
13
|
+
*
|
|
14
|
+
* Only literal versions inside a `cmake { }` block count. When there is no SDK
|
|
15
|
+
* or no sdkmanager, or the install fails, one line says so and the step goes
|
|
16
|
+
* on: AGP may still manage on its own.
|
|
17
|
+
*
|
|
18
|
+
* Written as shell functions so what ships is what the tests run. The shell
|
|
19
|
+
* is a raw string with no `${`, so every escape here is the one bash and awk
|
|
20
|
+
* read. Its lines start with "Android SDK:", never with a step-progress marker.
|
|
21
|
+
*/
|
|
22
|
+
export const GRADLE_SDK_CMAKE_FUNCTIONS = String.raw `# The CMake versions the project's build files pin, one per line as
|
|
23
|
+
# "<file>:<line><TAB><version>", first pin of each version only. Build
|
|
24
|
+
# outputs, .git and .gradle are not read.
|
|
25
|
+
cibuild_pinned_cmake_versions() {
|
|
26
|
+
find . \( -name build -o -name .git -o -name .gradle -o -name node_modules \) -prune -o \
|
|
27
|
+
-type f \( -name build.gradle -o -name build.gradle.kts \) -print 2>/dev/null | sort |
|
|
28
|
+
while IFS= read -r f; do
|
|
29
|
+
awk -v file="$f" '
|
|
30
|
+
FNR == 1 { inblk = 0; depth = 0 }
|
|
31
|
+
{
|
|
32
|
+
line = $0
|
|
33
|
+
sub(/\/\/.*$/, "", line)
|
|
34
|
+
if (!inblk && line ~ /(^|[^A-Za-z0-9_])cmake[ \t]*\{/) {
|
|
35
|
+
inblk = 1; depth = 0
|
|
36
|
+
sub(/.*(^|[^A-Za-z0-9_])cmake[ \t]*\{/, "{", line)
|
|
37
|
+
}
|
|
38
|
+
if (!inblk) next
|
|
39
|
+
if (match(line, /(^|[^A-Za-z0-9_.])version[ \t]*=?[ \t]*["\047][0-9]+\.[0-9]+(\.[0-9]+)?["\047]/)) {
|
|
40
|
+
v = substr(line, RSTART, RLENGTH); sub(/^.*version/, "", v); gsub(/[^0-9.]/, "", v)
|
|
41
|
+
print file ":" FNR "\t" v
|
|
42
|
+
}
|
|
43
|
+
depth += gsub(/\{/, "{", line) - gsub(/\}/, "}", line)
|
|
44
|
+
if (depth <= 0) inblk = 0
|
|
45
|
+
}
|
|
46
|
+
' "$f"
|
|
47
|
+
done | awk -F '\t' '!seen[$2]++'
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
# The Android SDK: ANDROID_HOME, then ANDROID_SDK_ROOT, then local.properties'
|
|
51
|
+
# sdk.dir. Prints nothing when none names a directory.
|
|
52
|
+
cibuild_android_sdk_dir() {
|
|
53
|
+
local d
|
|
54
|
+
for d in "$ANDROID_HOME" "$ANDROID_SDK_ROOT"; do
|
|
55
|
+
if [ -n "$d" ] && [ -d "$d" ]; then echo "$d"; return 0; fi
|
|
56
|
+
done
|
|
57
|
+
if [ -f local.properties ]; then
|
|
58
|
+
d=$(sed -n 's/^[ \t]*sdk\.dir[ \t]*[=:][ \t]*//p' local.properties | tail -n 1 | sed 's/[ \t\r]*$//')
|
|
59
|
+
if [ -n "$d" ] && [ -d "$d" ]; then echo "$d"; return 0; fi
|
|
60
|
+
fi
|
|
61
|
+
return 0
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
# Installs every pinned CMake the SDK does not have. Never fails the step.
|
|
65
|
+
cibuild_install_pinned_cmake() {
|
|
66
|
+
local pins sdk sdkmanager at v out rc
|
|
67
|
+
pins=$(cibuild_pinned_cmake_versions)
|
|
68
|
+
[ -n "$pins" ] || return 0
|
|
69
|
+
sdk=$(cibuild_android_sdk_dir)
|
|
70
|
+
sdkmanager=""
|
|
71
|
+
if [ -n "$sdk" ] && [ -x "$sdk/cmdline-tools/latest/bin/sdkmanager" ]; then
|
|
72
|
+
sdkmanager="$sdk/cmdline-tools/latest/bin/sdkmanager"
|
|
73
|
+
elif [ -n "$sdk" ] && command -v sdkmanager >/dev/null 2>&1; then
|
|
74
|
+
sdkmanager=$(command -v sdkmanager)
|
|
75
|
+
fi
|
|
76
|
+
while IFS=' ' read -r at v; do
|
|
77
|
+
if [ -n "$sdk" ] && [ -x "$sdk/cmake/$v/bin/cmake" ]; then continue; fi
|
|
78
|
+
if [ -z "$sdk" ]; then
|
|
79
|
+
echo "Android SDK: $at pins cmake;$v, but no Android SDK was found (ANDROID_HOME, ANDROID_SDK_ROOT, local.properties sdk.dir), so it is not installed here."
|
|
80
|
+
continue
|
|
81
|
+
fi
|
|
82
|
+
if [ -z "$sdkmanager" ]; then
|
|
83
|
+
echo "Android SDK: $at pins cmake;$v, but $sdk has no sdkmanager, so it is not installed here."
|
|
84
|
+
continue
|
|
85
|
+
fi
|
|
86
|
+
echo "Android SDK: installing cmake;$v, which $at pins (externalNativeBuild cmake version) and this SDK does not have."
|
|
87
|
+
# Licences are answered from a process substitution, not a pipe, so
|
|
88
|
+
# neither set -e nor pipefail turns yes's SIGPIPE into a failure.
|
|
89
|
+
rc=0
|
|
90
|
+
out=$("$sdkmanager" "--sdk_root=$sdk" "cmake;$v" < <(yes 2>/dev/null) 2>&1) || rc=$?
|
|
91
|
+
if [ "$rc" -eq 0 ] && [ -x "$sdk/cmake/$v/bin/cmake" ]; then
|
|
92
|
+
echo "Android SDK: cmake;$v installed."
|
|
93
|
+
else
|
|
94
|
+
echo "Android SDK: installing cmake;$v failed (sdkmanager exit $rc); Gradle runs anyway:"
|
|
95
|
+
printf '%s\n' "$out" | tail -n 5 | sed 's/^/ /'
|
|
96
|
+
fi
|
|
97
|
+
done <<< "$pins"
|
|
98
|
+
return 0
|
|
99
|
+
}`;
|
|
100
|
+
/**
|
|
101
|
+
* The commands a Gradle step runs in the project directory before Gradle, so
|
|
102
|
+
* a CMake the project pins is in the SDK when its own tasks look for it.
|
|
103
|
+
*/
|
|
104
|
+
export function gradleSdkCmakeCommands() {
|
|
105
|
+
return ['', GRADLE_SDK_CMAKE_FUNCTIONS, '', 'cibuild_install_pinned_cmake'];
|
|
106
|
+
}
|
|
107
|
+
//# sourceMappingURL=gradle-sdk-cmake.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gradle-sdk-cmake.test.d.ts","sourceRoot":"","sources":["../../../../src/yaml/steps/gradle-sdk-cmake.test.ts"],"names":[],"mappings":""}
|