@absolutejs/absolute 0.20.0-beta.107 → 0.20.0-beta.109
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/CHANGELOG.md +12 -0
- package/README.md +5 -1
- package/changelog.json +28 -0
- package/dist/angular/components/core/streamingSlotRegistrar.js +1 -1
- package/dist/angular/components/core/streamingSlotRegistry.js +2 -2
- package/dist/build.js +696 -623
- package/dist/build.js.map +8 -7
- package/dist/cli/{compile-hsbs1xf6.js → compile-1d5arbqj.js} +2 -2
- package/dist/cli/{config-vy04mqce.js → config-vq2qcc4p.js} +1 -1
- package/dist/cli/{dev-f6b6hkke.js → dev-f0safhsr.js} +1 -1
- package/dist/cli/{index-rd2hbttb.js → index-df2mjbdy.js} +53 -0
- package/dist/cli/{index-hrzd7e5x.js → index-dfqzrznk.js} +1 -1
- package/dist/cli/{index-mazxtfh4.js → index-gps0zk0m.js} +2 -2
- package/dist/cli/index.js +5 -5
- package/dist/cli/{mobile-7v8hfmdq.js → mobile-e4ygngfk.js} +230 -24
- package/dist/cli/{start-5grq7nfr.js → start-8v6g2y31.js} +3 -3
- package/dist/index.js +654 -581
- package/dist/index.js.map +8 -7
- package/dist/mobile/index.js +198 -17
- package/dist/mobile/index.js.map +6 -6
- package/dist/mobile/remoteMacAgentEntry.js +182 -182
- package/dist/src/build/injectVueComposableTracking.d.ts +3 -28
- package/dist/src/build/vueModuleOutputPath.d.ts +7 -0
- package/dist/src/mobile/config.d.ts +7 -0
- package/dist/src/mobile/releaseCertification.d.ts +12 -3
- package/dist/src/mobile/releasePublisher.d.ts +13 -0
- package/dist/types/build.d.ts +13 -0
- package/package.json +2 -2
|
@@ -15,7 +15,7 @@ import {
|
|
|
15
15
|
createIslandRegistryDefinitionPlugin,
|
|
16
16
|
finalizeAbsoluteMobileCompatibilityBuild,
|
|
17
17
|
resolveServerBundleExternals
|
|
18
|
-
} from "./index-
|
|
18
|
+
} from "./index-dfqzrznk.js";
|
|
19
19
|
import {
|
|
20
20
|
loadIslandRegistryBuildInfo
|
|
21
21
|
} from "./index-bzs19w3r.js";
|
|
@@ -35,7 +35,7 @@ import {
|
|
|
35
35
|
import"./index-w5vswatm.js";
|
|
36
36
|
import {
|
|
37
37
|
normalizeAbsoluteMobileConfig
|
|
38
|
-
} from "./index-
|
|
38
|
+
} from "./index-df2mjbdy.js";
|
|
39
39
|
import"./index-0zcebhm4.js";
|
|
40
40
|
import {
|
|
41
41
|
ABSOLUTE_NATIVE_AUTH_CLIENTS_ENV,
|
|
@@ -1285,7 +1285,7 @@ var loadAbsoluteMobileDevModules = async () => {
|
|
|
1285
1285
|
iosNativeWatcher,
|
|
1286
1286
|
expoNativeWatcher
|
|
1287
1287
|
] = await Promise.all([
|
|
1288
|
-
import("./config-
|
|
1288
|
+
import("./config-vq2qcc4p.js"),
|
|
1289
1289
|
import("./expoProject-zkprmjjz.js"),
|
|
1290
1290
|
import("./expoDevController-zz516pdd.js"),
|
|
1291
1291
|
import("./nativeAuth-zx4tsb1f.js"),
|
|
@@ -8,6 +8,7 @@ var SCHEME_PATTERN = /^[a-z][a-z0-9+.-]*$/;
|
|
|
8
8
|
var APPLE_APP_ID_PREFIX_PATTERN = /^[A-Z0-9]{10}$/;
|
|
9
9
|
var CERTIFICATE_FINGERPRINT_PATTERN = /^[0-9A-F]{64}$/;
|
|
10
10
|
var UPDATE_NAME_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$/u;
|
|
11
|
+
var RELEASE_TARGET_PATTERN = /^[a-z0-9][a-z0-9._-]{0,63}$/u;
|
|
11
12
|
var UPDATE_PUBLIC_KEY_PATTERN = /^[A-Za-z0-9+/]+={0,2}$/u;
|
|
12
13
|
var ENVIRONMENT_NAME_PATTERN = /^[A-Za-z_][A-Za-z0-9_]*$/u;
|
|
13
14
|
var DEFAULT_UPDATE_BOOT_TIMEOUT_MS = 20000;
|
|
@@ -75,6 +76,57 @@ var normalizePlatforms = (platforms) => {
|
|
|
75
76
|
}
|
|
76
77
|
return normalized;
|
|
77
78
|
};
|
|
79
|
+
var normalizeAndroidCertificationPolicy = (value) => {
|
|
80
|
+
if (value === false || value === undefined)
|
|
81
|
+
return;
|
|
82
|
+
if (value !== "installed")
|
|
83
|
+
throw new TypeError("mobile.release.certification channel Android policy must be installed or false.");
|
|
84
|
+
return value;
|
|
85
|
+
};
|
|
86
|
+
var normalizeIosCertificationPolicy = (value) => {
|
|
87
|
+
if (value === false || value === undefined)
|
|
88
|
+
return;
|
|
89
|
+
if (!["simulator", "device", "store"].includes(value))
|
|
90
|
+
throw new TypeError("mobile.release.certification channel iOS policy must be simulator, device, store, or false.");
|
|
91
|
+
return value;
|
|
92
|
+
};
|
|
93
|
+
var normalizeReleaseCertification = (config) => {
|
|
94
|
+
const configured = config.release?.certification;
|
|
95
|
+
if (configured === false)
|
|
96
|
+
return { channels: {}, googlePlayTracks: {} };
|
|
97
|
+
const channels = {
|
|
98
|
+
production: { android: "installed", ios: "store" }
|
|
99
|
+
};
|
|
100
|
+
const googlePlayTracks = {
|
|
101
|
+
production: "installed"
|
|
102
|
+
};
|
|
103
|
+
for (const [name, policy] of Object.entries(configured?.channels ?? {})) {
|
|
104
|
+
if (!RELEASE_TARGET_PATTERN.test(name))
|
|
105
|
+
throw new TypeError("mobile.release.certification.channels contains an invalid channel.");
|
|
106
|
+
const normalized = {};
|
|
107
|
+
const android = normalizeAndroidCertificationPolicy(policy.android);
|
|
108
|
+
const ios = normalizeIosCertificationPolicy(policy.ios);
|
|
109
|
+
if (android)
|
|
110
|
+
normalized.android = android;
|
|
111
|
+
if (ios)
|
|
112
|
+
normalized.ios = ios;
|
|
113
|
+
channels[name] = normalized;
|
|
114
|
+
}
|
|
115
|
+
for (const [name, requirement] of Object.entries(configured?.googlePlayTracks ?? {})) {
|
|
116
|
+
if (!RELEASE_TARGET_PATTERN.test(name))
|
|
117
|
+
throw new TypeError("mobile.release.certification.googlePlayTracks contains an invalid track.");
|
|
118
|
+
if (requirement === false)
|
|
119
|
+
delete googlePlayTracks[name];
|
|
120
|
+
else if (requirement === "installed")
|
|
121
|
+
googlePlayTracks[name] = requirement;
|
|
122
|
+
else
|
|
123
|
+
throw new TypeError("mobile.release.certification Google Play policy must be installed or false.");
|
|
124
|
+
}
|
|
125
|
+
return {
|
|
126
|
+
channels: Object.fromEntries(Object.entries(channels).sort(([left], [right]) => left.localeCompare(right))),
|
|
127
|
+
googlePlayTracks: Object.fromEntries(Object.entries(googlePlayTracks).sort(([left], [right]) => left.localeCompare(right)))
|
|
128
|
+
};
|
|
129
|
+
};
|
|
78
130
|
var normalizeHosts = (hosts, productionOrigin) => {
|
|
79
131
|
const normalizeHostname = (host) => {
|
|
80
132
|
const value = requireText(host, "mobile.deepLinks.hosts").toLowerCase();
|
|
@@ -411,6 +463,7 @@ var normalizeAbsoluteMobileConfig = (config, projectRoot) => {
|
|
|
411
463
|
platforms: normalizePlatforms(config.platforms),
|
|
412
464
|
productionOrigin,
|
|
413
465
|
pushAndroidGoogleServicesFile: resolveProjectPath(projectRoot, config.pushNotifications?.android?.googleServicesFile ?? "google-services.json", "mobile.pushNotifications.android.googleServicesFile"),
|
|
466
|
+
releaseCertification: normalizeReleaseCertification(config),
|
|
414
467
|
...updates ? { updates } : {},
|
|
415
468
|
...updateServer ? { updateServer } : {}
|
|
416
469
|
};
|
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
createIslandRegistryDefinitionPlugin,
|
|
7
7
|
finalizeAbsoluteMobileCompatibilityBuild,
|
|
8
8
|
resolveServerBundleExternals
|
|
9
|
-
} from "./index-
|
|
9
|
+
} from "./index-dfqzrznk.js";
|
|
10
10
|
import {
|
|
11
11
|
loadIslandRegistryBuildInfo
|
|
12
12
|
} from "./index-bzs19w3r.js";
|
|
@@ -26,7 +26,7 @@ import {
|
|
|
26
26
|
} from "./index-9kwmb3c0.js";
|
|
27
27
|
import {
|
|
28
28
|
normalizeAbsoluteMobileConfig
|
|
29
|
-
} from "./index-
|
|
29
|
+
} from "./index-df2mjbdy.js";
|
|
30
30
|
import {
|
|
31
31
|
installAbsoluteMobileAuthEnvironment
|
|
32
32
|
} from "./index-ar4gz15x.js";
|
package/dist/cli/index.js
CHANGED
|
@@ -58,7 +58,7 @@ if (command === "dev") {
|
|
|
58
58
|
}
|
|
59
59
|
const positionalArgs = stripNamedArgs("--config", "--android-device", "--ios-device").filter((arg) => arg !== "--no-mobile" && arg !== "--eager");
|
|
60
60
|
const serverEntry = positionalArgs[0] ?? DEFAULT_SERVER_ENTRY;
|
|
61
|
-
const { dev } = await import("./dev-
|
|
61
|
+
const { dev } = await import("./dev-f0safhsr.js");
|
|
62
62
|
await dev(serverEntry, configPath, {
|
|
63
63
|
androidDevice,
|
|
64
64
|
eager: args.includes("--eager"),
|
|
@@ -71,7 +71,7 @@ if (command === "dev") {
|
|
|
71
71
|
const configPath = parseNamedArg("--config");
|
|
72
72
|
const positionalArgs = stripNamedArgs("--outdir", "--config").filter((arg) => arg !== "--prebuilt");
|
|
73
73
|
const serverEntry = positionalArgs[0] ?? DEFAULT_SERVER_ENTRY;
|
|
74
|
-
const { start } = await import("./start-
|
|
74
|
+
const { start } = await import("./start-8v6g2y31.js");
|
|
75
75
|
await start(serverEntry, outdir, configPath, {
|
|
76
76
|
prebuilt: args.includes("--prebuilt")
|
|
77
77
|
});
|
|
@@ -81,7 +81,7 @@ if (command === "dev") {
|
|
|
81
81
|
const configPath = parseNamedArg("--config");
|
|
82
82
|
const positionalArgs = stripNamedArgs("--outdir", "--config");
|
|
83
83
|
const serverEntry = positionalArgs[0] ?? DEFAULT_SERVER_ENTRY;
|
|
84
|
-
const { start } = await import("./start-
|
|
84
|
+
const { start } = await import("./start-8v6g2y31.js");
|
|
85
85
|
await start(serverEntry, outdir, configPath, { prepareOnly: true });
|
|
86
86
|
} else if (command === "build") {
|
|
87
87
|
sendTelemetryEvent("cli:command", { command });
|
|
@@ -197,13 +197,13 @@ if (command === "dev") {
|
|
|
197
197
|
const configPath = parseNamedArg("--config");
|
|
198
198
|
const positionalArgs = stripNamedArgs("--outdir", "--outfile", "--config");
|
|
199
199
|
const serverEntry = positionalArgs[0] ?? DEFAULT_SERVER_ENTRY;
|
|
200
|
-
const { compile } = await import("./compile-
|
|
200
|
+
const { compile } = await import("./compile-1d5arbqj.js");
|
|
201
201
|
await compile(serverEntry, outdir, outfile, configPath);
|
|
202
202
|
} else if (command === "mobile") {
|
|
203
203
|
sendTelemetryEvent("cli:command", {
|
|
204
204
|
command: `mobile:${workspaceCommand ?? "unknown"}`
|
|
205
205
|
});
|
|
206
|
-
const { runMobile } = await import("./mobile-
|
|
206
|
+
const { runMobile } = await import("./mobile-e4ygngfk.js");
|
|
207
207
|
try {
|
|
208
208
|
await runMobile(args);
|
|
209
209
|
} catch (error) {
|
|
@@ -7,12 +7,12 @@ import {
|
|
|
7
7
|
} from "./index-zh6hhrwy.js";
|
|
8
8
|
import {
|
|
9
9
|
start
|
|
10
|
-
} from "./index-
|
|
10
|
+
} from "./index-gps0zk0m.js";
|
|
11
11
|
import {
|
|
12
12
|
ABSOLUTE_MOBILE_CLIENT_MANIFEST_FORMAT,
|
|
13
13
|
ABSOLUTE_MOBILE_PAGE_PROTOCOL_VERSION,
|
|
14
14
|
resolveAbsoluteMobileRoute
|
|
15
|
-
} from "./index-
|
|
15
|
+
} from "./index-dfqzrznk.js";
|
|
16
16
|
import"./index-bzs19w3r.js";
|
|
17
17
|
import"./index-s2tazax7.js";
|
|
18
18
|
import {
|
|
@@ -56,7 +56,7 @@ import {
|
|
|
56
56
|
import"./index-w5vswatm.js";
|
|
57
57
|
import {
|
|
58
58
|
normalizeAbsoluteMobileConfig
|
|
59
|
-
} from "./index-
|
|
59
|
+
} from "./index-df2mjbdy.js";
|
|
60
60
|
import {
|
|
61
61
|
ABSOLUTE_MOBILE_UPDATE_FORMAT,
|
|
62
62
|
absoluteDeviceNativeRequirements,
|
|
@@ -22353,6 +22353,14 @@ var satisfiesRequirement = (strength, requirement) => {
|
|
|
22353
22353
|
return false;
|
|
22354
22354
|
return STRENGTH_RANK[strength] >= STRENGTH_RANK[requirement];
|
|
22355
22355
|
};
|
|
22356
|
+
var resolveAbsoluteMobileCertificationRequirement = (config, target) => {
|
|
22357
|
+
const channelRequirement = target.channel ? config.releaseCertification.channels[target.channel]?.[target.platform] : undefined;
|
|
22358
|
+
const playRequirement = target.googlePlayTrack ? config.releaseCertification.googlePlayTracks[target.googlePlayTrack] : undefined;
|
|
22359
|
+
const requirements = [channelRequirement, playRequirement].filter((value) => value !== undefined);
|
|
22360
|
+
if (requirements.length === 0)
|
|
22361
|
+
return;
|
|
22362
|
+
return requirements.reduce((strongest, candidate) => STRENGTH_RANK[candidate] > STRENGTH_RANK[strongest] ? candidate : strongest);
|
|
22363
|
+
};
|
|
22356
22364
|
var validateCertifiedEvidence = (platform, evidence) => {
|
|
22357
22365
|
if (platform === "android") {
|
|
22358
22366
|
if (evidence.strength !== "installed" || evidence.networkUnavailable !== "proven" || evidence.artifactExactness !== undefined || evidence.distribution !== undefined || evidence.remote)
|
|
@@ -22599,6 +22607,15 @@ var prepareAbsoluteAndroidRelease = async (publisher, options) => {
|
|
|
22599
22607
|
}
|
|
22600
22608
|
return versionCode;
|
|
22601
22609
|
};
|
|
22610
|
+
var requireCertificationReceipt = (publication, certification, requirement, releaseId) => {
|
|
22611
|
+
if (!certification && !requirement)
|
|
22612
|
+
return;
|
|
22613
|
+
if (!certification || !requirement)
|
|
22614
|
+
throw new TypeError("Native release publication certification contract is incomplete.");
|
|
22615
|
+
const receipt = publication.certification;
|
|
22616
|
+
if (!receipt || receipt.certificationId !== certification.certificationId || receipt.releaseId !== releaseId || receipt.requirement !== requirement || receipt.strength !== certification.strength)
|
|
22617
|
+
throw new TypeError("Native release registry did not retain the required release certification.");
|
|
22618
|
+
};
|
|
22602
22619
|
var isRecord7 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
22603
22620
|
var isPublisher = (value) => isRecord7(value) && typeof value.publish === "function";
|
|
22604
22621
|
var publisherModulePath = (projectRoot, requested) => {
|
|
@@ -22623,9 +22640,16 @@ var loadAbsoluteNativeReleasePublisher = async (projectRoot, requestedModulePath
|
|
|
22623
22640
|
return publisher;
|
|
22624
22641
|
};
|
|
22625
22642
|
var publishAbsoluteAndroidRelease = async (options) => {
|
|
22643
|
+
const certificationRequirement = options.certificationRequirement ?? options.certification?.requirement;
|
|
22644
|
+
if (options.certification)
|
|
22645
|
+
verifyAbsoluteMobileReleaseCertification(options.certification, options.release, certificationRequirement);
|
|
22646
|
+
else if (certificationRequirement)
|
|
22647
|
+
throw new TypeError(`Android release publication requires ${certificationRequirement} certification.`);
|
|
22626
22648
|
const publisher = await loadAbsoluteNativeReleasePublisher(options.projectRoot, options.modulePath);
|
|
22627
22649
|
const publication = await publisher.publish({
|
|
22628
22650
|
allowUnsigned: options.allowUnsigned,
|
|
22651
|
+
certification: options.certification,
|
|
22652
|
+
certificationRequirement,
|
|
22629
22653
|
channel: options.channel,
|
|
22630
22654
|
googlePlay: options.googlePlay,
|
|
22631
22655
|
releaseRoot: options.release.releaseRoot,
|
|
@@ -22636,6 +22660,7 @@ var publishAbsoluteAndroidRelease = async (options) => {
|
|
|
22636
22660
|
if (!actual || actual.appId !== expected.appId || actual.platform !== "android" || actual.releaseId !== expected.releaseId || actual.sha256 !== expected.sha256 || actual.signed !== expected.signed || actual.versionCode !== expected.versionCode || typeof publication.reused !== "boolean") {
|
|
22637
22661
|
throw new TypeError("Native release registry returned a different Android release identity.");
|
|
22638
22662
|
}
|
|
22663
|
+
requireCertificationReceipt(publication, options.certification, certificationRequirement, expected.releaseId);
|
|
22639
22664
|
if (options.channel !== undefined && (publication.channel?.channel !== options.channel || publication.channel.releaseId !== expected.releaseId)) {
|
|
22640
22665
|
throw new TypeError("Native release registry did not promote the requested channel.");
|
|
22641
22666
|
}
|
|
@@ -22648,10 +22673,17 @@ var publishAbsoluteAndroidRelease = async (options) => {
|
|
|
22648
22673
|
return publication;
|
|
22649
22674
|
};
|
|
22650
22675
|
var publishAbsoluteIosRelease = async (options) => {
|
|
22676
|
+
const certificationRequirement = options.certificationRequirement ?? options.certification?.requirement;
|
|
22677
|
+
if (options.certification)
|
|
22678
|
+
verifyAbsoluteMobileReleaseCertification(options.certification, options.release, certificationRequirement);
|
|
22679
|
+
else if (certificationRequirement)
|
|
22680
|
+
throw new TypeError(`iOS release publication requires ${certificationRequirement} certification.`);
|
|
22651
22681
|
const publisher = await loadAbsoluteNativeReleasePublisher(options.projectRoot, options.modulePath);
|
|
22652
22682
|
const publication = await publisher.publish({
|
|
22653
22683
|
allowUnsigned: options.allowUnsigned,
|
|
22654
22684
|
appStoreConnect: options.appStoreConnect,
|
|
22685
|
+
certification: options.certification,
|
|
22686
|
+
certificationRequirement,
|
|
22655
22687
|
channel: options.channel,
|
|
22656
22688
|
releaseRoot: options.release.releaseRoot,
|
|
22657
22689
|
signal: options.signal
|
|
@@ -22661,6 +22693,7 @@ var publishAbsoluteIosRelease = async (options) => {
|
|
|
22661
22693
|
if (!actual || actual.appId !== expected.appId || actual.platform !== "ios" || actual.releaseId !== expected.releaseId || actual.sha256 !== expected.sha256 || actual.signed !== expected.signed || actual.buildNumber !== expected.buildNumber || actual.marketingVersion !== expected.marketingVersion || typeof publication.reused !== "boolean") {
|
|
22662
22694
|
throw new TypeError("Native release registry returned a different iOS release identity.");
|
|
22663
22695
|
}
|
|
22696
|
+
requireCertificationReceipt(publication, options.certification, certificationRequirement, expected.releaseId);
|
|
22664
22697
|
if (options.channel !== undefined && (publication.channel?.channel !== options.channel || publication.channel.releaseId !== expected.releaseId)) {
|
|
22665
22698
|
throw new TypeError("Native release registry did not promote the requested channel.");
|
|
22666
22699
|
}
|
|
@@ -23023,12 +23056,9 @@ var androidJob = (options) => {
|
|
|
23023
23056
|
ABSOLUTE_GOOGLE_CREDENTIALS_BASE64: \${{ secrets.ABSOLUTE_GOOGLE_CREDENTIALS_BASE64 }}
|
|
23024
23057
|
GOOGLE_APPLICATION_CREDENTIALS: \${{ runner.temp }}/absolute-google-credentials.json` : "";
|
|
23025
23058
|
const publishCommand = options.includePublishing ? `if [[ "$ABSOLUTE_PUBLISH" == "true" ]]; then
|
|
23026
|
-
args=(bunx absolute mobile
|
|
23027
|
-
if [[ -n "$ABSOLUTE_RELEASE_CHANNEL" ]]; then
|
|
23028
|
-
args+=(--channel "$ABSOLUTE_RELEASE_CHANNEL")
|
|
23029
|
-
fi
|
|
23059
|
+
args=(bunx absolute mobile build android "$ABSOLUTE_SERVER_ENTRY")
|
|
23030
23060
|
if [[ "$ABSOLUTE_PLAY_TRACK" != "registry-only" ]]; then
|
|
23031
|
-
args+=(--play-track "$ABSOLUTE_PLAY_TRACK")
|
|
23061
|
+
args+=(--registry "$ABSOLUTE_REGISTRY_MODULE" --play-track "$ABSOLUTE_PLAY_TRACK")
|
|
23032
23062
|
fi
|
|
23033
23063
|
else
|
|
23034
23064
|
args=(bunx absolute mobile build android "$ABSOLUTE_SERVER_ENTRY")
|
|
@@ -23042,6 +23072,58 @@ var androidJob = (options) => {
|
|
|
23042
23072
|
printf '%s' "$ABSOLUTE_GOOGLE_CREDENTIALS_BASE64" | base64 --decode > "$GOOGLE_APPLICATION_CREDENTIALS"
|
|
23043
23073
|
chmod 600 "$GOOGLE_APPLICATION_CREDENTIALS"
|
|
23044
23074
|
fi` : "";
|
|
23075
|
+
const certificationSteps = options.includePublishing ? `
|
|
23076
|
+
- name: Install-test and certify exact Android release
|
|
23077
|
+
if: inputs.publish
|
|
23078
|
+
shell: bash
|
|
23079
|
+
run: |
|
|
23080
|
+
args=(bunx absolute mobile doctor android --fix --yes)
|
|
23081
|
+
${appendConfigArgument}
|
|
23082
|
+
"\${args[@]}"
|
|
23083
|
+
shopt -s nullglob
|
|
23084
|
+
releases=(.absolutejs/mobile/releases/android/*)
|
|
23085
|
+
if [[ "\${#releases[@]}" -ne 1 || ! -d "\${releases[0]}" ]]; then
|
|
23086
|
+
echo "Expected exactly one immutable Android release directory." >&2
|
|
23087
|
+
exit 1
|
|
23088
|
+
fi
|
|
23089
|
+
RELEASE_DIRECTORY="\${releases[0]}"
|
|
23090
|
+
args=(bunx absolute mobile test android --release "$RELEASE_DIRECTORY" --report .absolutejs/mobile-ci/acceptance/android --yes)
|
|
23091
|
+
${appendConfigArgument}
|
|
23092
|
+
"\${args[@]}"
|
|
23093
|
+
args=(bunx absolute mobile certify "$RELEASE_DIRECTORY" --evidence .absolutejs/mobile-ci/acceptance/android --require installed --outdir .absolutejs/mobile-ci/certifications/android --json)
|
|
23094
|
+
"\${args[@]}" > .absolutejs/mobile-ci/android-certification.json
|
|
23095
|
+
- name: Publish certified Android release
|
|
23096
|
+
if: inputs.publish
|
|
23097
|
+
shell: bash
|
|
23098
|
+
run: |
|
|
23099
|
+
shopt -s nullglob
|
|
23100
|
+
releases=(.absolutejs/mobile/releases/android/*)
|
|
23101
|
+
certifications=(.absolutejs/mobile-ci/certifications/android/*)
|
|
23102
|
+
if [[ "\${#releases[@]}" -ne 1 || "\${#certifications[@]}" -ne 1 || ! -d "\${releases[0]}" || ! -d "\${certifications[0]}" ]]; then
|
|
23103
|
+
echo "Expected exactly one Android release and certification." >&2
|
|
23104
|
+
exit 1
|
|
23105
|
+
fi
|
|
23106
|
+
args=(bunx absolute mobile publish android --release "\${releases[0]}" --certification "\${certifications[0]}" --registry "$ABSOLUTE_REGISTRY_MODULE")
|
|
23107
|
+
if [[ -n "$ABSOLUTE_RELEASE_CHANNEL" ]]; then
|
|
23108
|
+
args+=(--channel "$ABSOLUTE_RELEASE_CHANNEL")
|
|
23109
|
+
fi
|
|
23110
|
+
if [[ "$ABSOLUTE_PLAY_TRACK" != "registry-only" ]]; then
|
|
23111
|
+
args+=(--play-track "$ABSOLUTE_PLAY_TRACK")
|
|
23112
|
+
fi
|
|
23113
|
+
${appendConfigArgument}
|
|
23114
|
+
"\${args[@]}"
|
|
23115
|
+
- name: Upload Android acceptance and certification
|
|
23116
|
+
if: always() && inputs.publish
|
|
23117
|
+
uses: actions/upload-artifact@v7
|
|
23118
|
+
with:
|
|
23119
|
+
name: absolute-mobile-android-certification
|
|
23120
|
+
path: |
|
|
23121
|
+
.absolutejs/mobile-ci/acceptance/android/
|
|
23122
|
+
.absolutejs/mobile-ci/certifications/android/
|
|
23123
|
+
.absolutejs/mobile-ci/android-certification.json
|
|
23124
|
+
if-no-files-found: error
|
|
23125
|
+
retention-days: 30
|
|
23126
|
+
include-hidden-files: true` : "";
|
|
23045
23127
|
return `
|
|
23046
23128
|
android:
|
|
23047
23129
|
name: Signed Android release
|
|
@@ -23080,13 +23162,14 @@ ${installSteps}
|
|
|
23080
23162
|
done
|
|
23081
23163
|
printf '%s' "$ABSOLUTE_ANDROID_KEYSTORE_BASE64" | base64 --decode > "\${{ runner.temp }}/absolute-release.jks"
|
|
23082
23164
|
chmod 600 "\${{ runner.temp }}/absolute-release.jks"${googleSetup}
|
|
23083
|
-
- name: Build
|
|
23165
|
+
- name: Build Android
|
|
23084
23166
|
shell: bash
|
|
23085
23167
|
run: |
|
|
23086
23168
|
${publishCommand}
|
|
23087
23169
|
${appendConfigArgument}
|
|
23088
23170
|
"\${args[@]}"
|
|
23089
23171
|
${releaseAuditSteps("android")}
|
|
23172
|
+
${certificationSteps}
|
|
23090
23173
|
- name: Attest Android App Bundle
|
|
23091
23174
|
if: inputs.attest
|
|
23092
23175
|
uses: actions/attest@v4
|
|
@@ -23119,15 +23202,9 @@ var iosJob = (options) => {
|
|
|
23119
23202
|
APP_STORE_CONNECT_PRIVATE_KEY_BASE64: \${{ secrets.APP_STORE_CONNECT_PRIVATE_KEY_BASE64 }}
|
|
23120
23203
|
APP_STORE_CONNECT_PRIVATE_KEY_PATH: \${{ runner.temp }}/AuthKey_AbsoluteJS.p8` : "";
|
|
23121
23204
|
const publishCommand = options.includePublishing ? `if [[ "$ABSOLUTE_PUBLISH" == "true" ]]; then
|
|
23122
|
-
args=(bunx absolute mobile
|
|
23123
|
-
if [[ -n "$ABSOLUTE_RELEASE_CHANNEL" ]]; then
|
|
23124
|
-
args+=(--channel "$ABSOLUTE_RELEASE_CHANNEL")
|
|
23125
|
-
fi
|
|
23205
|
+
args=(bunx absolute mobile build ios "$ABSOLUTE_SERVER_ENTRY")
|
|
23126
23206
|
if [[ -n "$ABSOLUTE_TESTFLIGHT_GROUP" ]]; then
|
|
23127
|
-
args+=(--testflight-group "$ABSOLUTE_TESTFLIGHT_GROUP")
|
|
23128
|
-
fi
|
|
23129
|
-
if [[ "$ABSOLUTE_TESTFLIGHT_SUBMIT_REVIEW" == "true" ]]; then
|
|
23130
|
-
args+=(--testflight-submit-review)
|
|
23207
|
+
args+=(--registry "$ABSOLUTE_REGISTRY_MODULE" --testflight-group "$ABSOLUTE_TESTFLIGHT_GROUP")
|
|
23131
23208
|
fi
|
|
23132
23209
|
else
|
|
23133
23210
|
args=(bunx absolute mobile build ios "$ABSOLUTE_SERVER_ENTRY")
|
|
@@ -23141,6 +23218,58 @@ var iosJob = (options) => {
|
|
|
23141
23218
|
printf '%s' "$APP_STORE_CONNECT_PRIVATE_KEY_BASE64" | base64 --decode > "$APP_STORE_CONNECT_PRIVATE_KEY_PATH"
|
|
23142
23219
|
chmod 600 "$APP_STORE_CONNECT_PRIVATE_KEY_PATH"
|
|
23143
23220
|
fi` : "";
|
|
23221
|
+
const certificationSteps = options.includePublishing ? `
|
|
23222
|
+
- name: Simulator-test and certify exact iOS release
|
|
23223
|
+
if: inputs.publish
|
|
23224
|
+
shell: bash
|
|
23225
|
+
run: |
|
|
23226
|
+
shopt -s nullglob
|
|
23227
|
+
releases=(.absolutejs/mobile/releases/ios/*)
|
|
23228
|
+
if [[ "\${#releases[@]}" -ne 1 || ! -d "\${releases[0]}" ]]; then
|
|
23229
|
+
echo "Expected exactly one immutable iOS release directory." >&2
|
|
23230
|
+
exit 1
|
|
23231
|
+
fi
|
|
23232
|
+
RELEASE_DIRECTORY="\${releases[0]}"
|
|
23233
|
+
args=(bunx absolute mobile test ios --release "$RELEASE_DIRECTORY" --report .absolutejs/mobile-ci/acceptance/ios --yes)
|
|
23234
|
+
${appendConfigArgument}
|
|
23235
|
+
"\${args[@]}"
|
|
23236
|
+
args=(bunx absolute mobile certify "$RELEASE_DIRECTORY" --evidence .absolutejs/mobile-ci/acceptance/ios --require simulator --outdir .absolutejs/mobile-ci/certifications/ios --json)
|
|
23237
|
+
"\${args[@]}" > .absolutejs/mobile-ci/ios-certification.json
|
|
23238
|
+
- name: Publish certified iOS release
|
|
23239
|
+
if: inputs.publish
|
|
23240
|
+
shell: bash
|
|
23241
|
+
run: |
|
|
23242
|
+
shopt -s nullglob
|
|
23243
|
+
releases=(.absolutejs/mobile/releases/ios/*)
|
|
23244
|
+
certifications=(.absolutejs/mobile-ci/certifications/ios/*)
|
|
23245
|
+
if [[ "\${#releases[@]}" -ne 1 || "\${#certifications[@]}" -ne 1 || ! -d "\${releases[0]}" || ! -d "\${certifications[0]}" ]]; then
|
|
23246
|
+
echo "Expected exactly one iOS release and certification." >&2
|
|
23247
|
+
exit 1
|
|
23248
|
+
fi
|
|
23249
|
+
args=(bunx absolute mobile publish ios --release "\${releases[0]}" --certification "\${certifications[0]}" --registry "$ABSOLUTE_REGISTRY_MODULE")
|
|
23250
|
+
if [[ -n "$ABSOLUTE_RELEASE_CHANNEL" ]]; then
|
|
23251
|
+
args+=(--channel "$ABSOLUTE_RELEASE_CHANNEL")
|
|
23252
|
+
fi
|
|
23253
|
+
if [[ -n "$ABSOLUTE_TESTFLIGHT_GROUP" ]]; then
|
|
23254
|
+
args+=(--testflight-group "$ABSOLUTE_TESTFLIGHT_GROUP")
|
|
23255
|
+
fi
|
|
23256
|
+
if [[ "$ABSOLUTE_TESTFLIGHT_SUBMIT_REVIEW" == "true" ]]; then
|
|
23257
|
+
args+=(--testflight-submit-review)
|
|
23258
|
+
fi
|
|
23259
|
+
${appendConfigArgument}
|
|
23260
|
+
"\${args[@]}"
|
|
23261
|
+
- name: Upload iOS acceptance and certification
|
|
23262
|
+
if: always() && inputs.publish
|
|
23263
|
+
uses: actions/upload-artifact@v7
|
|
23264
|
+
with:
|
|
23265
|
+
name: absolute-mobile-ios-certification
|
|
23266
|
+
path: |
|
|
23267
|
+
.absolutejs/mobile-ci/acceptance/ios/
|
|
23268
|
+
.absolutejs/mobile-ci/certifications/ios/
|
|
23269
|
+
.absolutejs/mobile-ci/ios-certification.json
|
|
23270
|
+
if-no-files-found: error
|
|
23271
|
+
retention-days: 30
|
|
23272
|
+
include-hidden-files: true` : "";
|
|
23144
23273
|
return `
|
|
23145
23274
|
ios:
|
|
23146
23275
|
name: Signed iOS release
|
|
@@ -23192,13 +23321,14 @@ ${installSteps}
|
|
|
23192
23321
|
security list-keychain -d user -s "$KEYCHAIN_PATH"
|
|
23193
23322
|
mkdir -p "$(dirname "$PROFILE_DESTINATION")"
|
|
23194
23323
|
cp "$PROFILE_PATH" "$PROFILE_DESTINATION"${appStoreDecode}
|
|
23195
|
-
- name: Build
|
|
23324
|
+
- name: Build iOS
|
|
23196
23325
|
shell: bash
|
|
23197
23326
|
run: |
|
|
23198
23327
|
${publishCommand}
|
|
23199
23328
|
${appendConfigArgument}
|
|
23200
23329
|
"\${args[@]}"
|
|
23201
23330
|
${releaseAuditSteps("ios")}
|
|
23331
|
+
${certificationSteps}
|
|
23202
23332
|
- name: Attest iOS IPA
|
|
23203
23333
|
if: inputs.attest
|
|
23204
23334
|
uses: actions/attest@v4
|
|
@@ -24439,7 +24569,7 @@ var provisionMobileUpdate = async (args) => {
|
|
|
24439
24569
|
throw new TypeError("--storage must be local or s3.");
|
|
24440
24570
|
const modulePath = valueAfter(args, "--registry") ?? mobile.updateServer.registryModule;
|
|
24441
24571
|
const packages = [
|
|
24442
|
-
"@absolutejs/deploy@0.
|
|
24572
|
+
"@absolutejs/deploy@0.26.0",
|
|
24443
24573
|
"@absolutejs/blob@0.5.2",
|
|
24444
24574
|
...requestedStorage === "s3" ? [
|
|
24445
24575
|
"@aws-sdk/client-s3@3.1095.0",
|
|
@@ -24957,25 +25087,70 @@ var printAppStoreConnectPublication = (publication) => {
|
|
|
24957
25087
|
const { receipt } = publication;
|
|
24958
25088
|
console.log(`${publication.reused ? "Reused" : "Uploaded"} App Store Connect build ${receipt.marketingVersion} (${receipt.buildNumber}); ${receipt.stage}.`);
|
|
24959
25089
|
};
|
|
25090
|
+
var buildAndroidCommand = async (args) => {
|
|
25091
|
+
const googlePlay = googlePlayTarget(args);
|
|
25092
|
+
if (!googlePlay)
|
|
25093
|
+
return buildAndroid(args);
|
|
25094
|
+
const registryModule = args.includes("--registry") ? requireValueAfter(args, "--registry") : "mobile.release.ts";
|
|
25095
|
+
const { mobile, projectRoot } = await loadMobile(valueAfter(args, "--config"));
|
|
25096
|
+
const publisher = await loadAbsoluteNativeReleasePublisher(projectRoot, registryModule);
|
|
25097
|
+
return buildAndroid(args, (buildIdentity) => prepareAbsoluteAndroidRelease(publisher, {
|
|
25098
|
+
buildIdentity,
|
|
25099
|
+
googlePlay,
|
|
25100
|
+
packageName: mobile.appId
|
|
25101
|
+
}));
|
|
25102
|
+
};
|
|
25103
|
+
var requirePublicationReleaseIdentity = (mobile, release, platform2) => {
|
|
25104
|
+
if (release.metadata.platform !== platform2 || release.metadata.appId !== mobile.appId || release.metadata.engine !== mobile.engine)
|
|
25105
|
+
throw new TypeError(`The existing ${platform2} release does not match this application's platform, app ID, or engine.`);
|
|
25106
|
+
};
|
|
25107
|
+
var loadPublicationCertification = async (options) => {
|
|
25108
|
+
const requested = valueAfter(options.args, "--certification");
|
|
25109
|
+
if (options.args.includes("--certification") && (!requested || requested.startsWith("-")))
|
|
25110
|
+
throw new TypeError(`mobile publish ${options.platform} requires --certification <directory-or-json>.`);
|
|
25111
|
+
if (!requested) {
|
|
25112
|
+
if (options.requirement)
|
|
25113
|
+
throw new TypeError(`mobile publish ${options.platform} requires --certification with ${options.requirement} evidence for this release target.`);
|
|
25114
|
+
return;
|
|
25115
|
+
}
|
|
25116
|
+
const loaded = await readAbsoluteMobileReleaseCertification(options.projectRoot, requested);
|
|
25117
|
+
return verifyAbsoluteMobileReleaseCertification(loaded.certification, options.release, options.requirement);
|
|
25118
|
+
};
|
|
24960
25119
|
var publishAndroid = async (args) => {
|
|
24961
25120
|
const registryModule = args.includes("--registry") ? requireValueAfter(args, "--registry") : "mobile.release.ts";
|
|
24962
25121
|
const channel = args.includes("--channel") ? requireValueAfter(args, "--channel") : undefined;
|
|
24963
25122
|
const configPath = valueAfter(args, "--config");
|
|
24964
25123
|
const googlePlay = googlePlayTarget(args);
|
|
24965
25124
|
const { mobile, projectRoot } = await loadMobile(configPath);
|
|
25125
|
+
const certificationRequirement = resolveAbsoluteMobileCertificationRequirement(mobile, {
|
|
25126
|
+
channel,
|
|
25127
|
+
googlePlayTrack: googlePlay?.track,
|
|
25128
|
+
platform: "android"
|
|
25129
|
+
});
|
|
24966
25130
|
const startedAt = performance.now();
|
|
24967
25131
|
let reused = false;
|
|
24968
25132
|
let success = false;
|
|
24969
25133
|
try {
|
|
24970
25134
|
const publisher = await loadAbsoluteNativeReleasePublisher(projectRoot, registryModule);
|
|
24971
|
-
const
|
|
25135
|
+
const requestedRelease = args.includes("--release") ? requireValueAfter(args, "--release") : undefined;
|
|
25136
|
+
const release = requestedRelease ? await readAbsoluteAndroidRelease(projectRoot, requestedRelease) : await buildAndroid(args, googlePlay ? (buildIdentity) => prepareAbsoluteAndroidRelease(publisher, {
|
|
24972
25137
|
buildIdentity,
|
|
24973
25138
|
googlePlay,
|
|
24974
25139
|
packageName: mobile.appId
|
|
24975
25140
|
}) : undefined);
|
|
25141
|
+
requirePublicationReleaseIdentity(mobile, release, "android");
|
|
25142
|
+
const certification = await loadPublicationCertification({
|
|
25143
|
+
args,
|
|
25144
|
+
platform: "android",
|
|
25145
|
+
projectRoot,
|
|
25146
|
+
release,
|
|
25147
|
+
...certificationRequirement ? { requirement: certificationRequirement } : {}
|
|
25148
|
+
});
|
|
24976
25149
|
const publication = await publishAbsoluteAndroidRelease({
|
|
24977
25150
|
allowUnsigned: args.includes("--unsigned"),
|
|
24978
25151
|
channel,
|
|
25152
|
+
...certification ? { certification } : {},
|
|
25153
|
+
...certificationRequirement ? { certificationRequirement } : {},
|
|
24979
25154
|
googlePlay,
|
|
24980
25155
|
modulePath: registryModule,
|
|
24981
25156
|
projectRoot,
|
|
@@ -25111,18 +25286,39 @@ var buildIos = async (args, prepareBuildNumber) => {
|
|
|
25111
25286
|
});
|
|
25112
25287
|
}
|
|
25113
25288
|
};
|
|
25289
|
+
var buildIosCommand = async (args) => {
|
|
25290
|
+
const appStoreConnect = appStoreConnectTarget(args);
|
|
25291
|
+
if (!appStoreConnect)
|
|
25292
|
+
return buildIos(args);
|
|
25293
|
+
const registryModule = args.includes("--registry") ? requireIosValueAfter(args, "--registry") : "mobile.release.ts";
|
|
25294
|
+
const { mobile, projectRoot } = await loadMobile(valueAfter(args, "--config"));
|
|
25295
|
+
const marketingVersion = mobile.iosVersion;
|
|
25296
|
+
if (!marketingVersion)
|
|
25297
|
+
throw new TypeError("iOS App Store build allocation requires mobile.ios.version.");
|
|
25298
|
+
const publisher = await loadAbsoluteNativeReleasePublisher(projectRoot, registryModule);
|
|
25299
|
+
return buildIos(args, (buildIdentity) => prepareAbsoluteIosRelease(publisher, {
|
|
25300
|
+
buildIdentity,
|
|
25301
|
+
bundleId: mobile.appId,
|
|
25302
|
+
marketingVersion
|
|
25303
|
+
}));
|
|
25304
|
+
};
|
|
25114
25305
|
var publishIos = async (args) => {
|
|
25115
25306
|
const registryModule = args.includes("--registry") ? requireIosValueAfter(args, "--registry") : "mobile.release.ts";
|
|
25116
25307
|
const channel = args.includes("--channel") ? requireIosValueAfter(args, "--channel") : undefined;
|
|
25117
25308
|
const configPath = valueAfter(args, "--config");
|
|
25118
25309
|
const appStoreConnect = appStoreConnectTarget(args);
|
|
25119
25310
|
const { mobile, projectRoot } = await loadMobile(configPath);
|
|
25311
|
+
const certificationRequirement = resolveAbsoluteMobileCertificationRequirement(mobile, {
|
|
25312
|
+
channel,
|
|
25313
|
+
platform: "ios"
|
|
25314
|
+
});
|
|
25120
25315
|
const startedAt = performance.now();
|
|
25121
25316
|
let reused = false;
|
|
25122
25317
|
let success = false;
|
|
25123
25318
|
try {
|
|
25124
25319
|
const publisher = await loadAbsoluteNativeReleasePublisher(projectRoot, registryModule);
|
|
25125
|
-
const
|
|
25320
|
+
const requestedRelease = args.includes("--release") ? requireIosValueAfter(args, "--release") : undefined;
|
|
25321
|
+
const release = requestedRelease ? await readAbsoluteIosRelease(projectRoot, requestedRelease) : await buildIos(args, appStoreConnect ? (buildIdentity) => {
|
|
25126
25322
|
if (!mobile.iosVersion)
|
|
25127
25323
|
throw new TypeError("iOS publishing requires mobile.ios.version.");
|
|
25128
25324
|
return prepareAbsoluteIosRelease(publisher, {
|
|
@@ -25131,10 +25327,20 @@ var publishIos = async (args) => {
|
|
|
25131
25327
|
marketingVersion: mobile.iosVersion
|
|
25132
25328
|
});
|
|
25133
25329
|
} : undefined);
|
|
25330
|
+
requirePublicationReleaseIdentity(mobile, release, "ios");
|
|
25331
|
+
const certification = await loadPublicationCertification({
|
|
25332
|
+
args,
|
|
25333
|
+
platform: "ios",
|
|
25334
|
+
projectRoot,
|
|
25335
|
+
release,
|
|
25336
|
+
...certificationRequirement ? { requirement: certificationRequirement } : {}
|
|
25337
|
+
});
|
|
25134
25338
|
const publication = await publishAbsoluteIosRelease({
|
|
25135
25339
|
allowUnsigned: args.includes("--unsigned"),
|
|
25136
25340
|
appStoreConnect,
|
|
25137
25341
|
channel,
|
|
25342
|
+
...certification ? { certification } : {},
|
|
25343
|
+
...certificationRequirement ? { certificationRequirement } : {},
|
|
25138
25344
|
modulePath: registryModule,
|
|
25139
25345
|
projectRoot,
|
|
25140
25346
|
release
|
|
@@ -26621,11 +26827,11 @@ var runMobile = async (args) => {
|
|
|
26621
26827
|
return;
|
|
26622
26828
|
}
|
|
26623
26829
|
if (command === "build" && args[1] === "android") {
|
|
26624
|
-
await
|
|
26830
|
+
await buildAndroidCommand(args.slice(2));
|
|
26625
26831
|
return;
|
|
26626
26832
|
}
|
|
26627
26833
|
if (command === "build" && args[1] === "ios") {
|
|
26628
|
-
await
|
|
26834
|
+
await buildIosCommand(args.slice(2));
|
|
26629
26835
|
return;
|
|
26630
26836
|
}
|
|
26631
26837
|
if (command === "update" && args[1] === "build") {
|
|
@@ -26676,7 +26882,7 @@ var runMobile = async (args) => {
|
|
|
26676
26882
|
await publishIos(args.slice(2));
|
|
26677
26883
|
return;
|
|
26678
26884
|
}
|
|
26679
|
-
throw new TypeError("Usage: absolute mobile <pair mac <name> <user@host> [--port n] [--workspace path] | remotes [inspect [name] [--json] | clean [name] --yes | --json] | unpair mac <name> | init [--no-native] [--force] | sync [ios|android] | inspect [--json] [--require-bundle] | certify <release-dir> [--evidence report-dir]... [--require installed|simulator|device|store] [--outdir dir] [--json] | certify <release-dir> --verify certification-dir [--require installed|simulator|device|store] [--json] | associations [--outdir dir] [--verify] | ci github [server-entry] [--publish] [--registry module] [--secret-env NAME] [--output path] [--force] [--json] | doctor [ios|android|release [ios|android]] [--remote name] [--json|--fix [--yes]] | build <android|ios> [server-entry] [--remote name] [--registered-device-artifact] [--outdir dir] [--web-outdir dir] [--unsigned] | update provision [--storage local|s3] [--registry module] [--force] [--yes] | update signing generate --private-key path [--certificate path] [--public-key path] [--key-id id] [--common-name name] [--validity-years n] | update build [server-entry] --classification bug-fix|content|security --key-id id --signing-key path --within-submitted-purpose [--outdir dir] [--web-outdir dir] | update publish <release-directory> [--rollout fraction] [--registry module] | update promote --release id --rollout fraction [--registry module] | update rollback [--release id] [--registry module] | update status [--registry module] [--json] | update advance [--rollout fraction] [--registry module] [--json] | update pause|resume|cancel|reconcile [--registry module] [--json] | update storage [--retain count] [--min-age-days days] [--registry module] [--json] | update gc [--retain count] [--min-age-days days] [--grace-days days] [--apply] [--registry module] [--json] | publish android [server-entry] [--registry module] [--channel name] [--play-track track] [--play-status completed|draft|halted|in-progress] [--play-rollout fraction] [--play-name name] [--play-notes language=text] [--play-update-priority 0..5] [--play-hold-review] [--play-cancel-existing-review] [--outdir dir] [--web-outdir dir] [--unsigned] | publish ios [server-entry] [--remote name] [--registry module] [--channel name] [--testflight-group name-or-id] [--testflight-notes locale=text] [--testflight-submit-review] [--outdir dir] [--web-outdir dir] [--unsigned] | test android [--release release-dir [--yes] | --route path [--wait-for-hmr] [--port n]] [--report [dir]] [--serial id] [--artifacts dir] [--json] [--config path] | test ios [--release release-dir [--remote name] [--device id [--testflight] --yes] | --wait-for-hmr] [--report [dir]] [--udid id] [--artifacts dir] [--json] [--config path]");
|
|
26885
|
+
throw new TypeError("Usage: absolute mobile <pair mac <name> <user@host> [--port n] [--workspace path] | remotes [inspect [name] [--json] | clean [name] --yes | --json] | unpair mac <name> | init [--no-native] [--force] | sync [ios|android] | inspect [--json] [--require-bundle] | certify <release-dir> [--evidence report-dir]... [--require installed|simulator|device|store] [--outdir dir] [--json] | certify <release-dir> --verify certification-dir [--require installed|simulator|device|store] [--json] | associations [--outdir dir] [--verify] | ci github [server-entry] [--publish] [--registry module] [--secret-env NAME] [--output path] [--force] [--json] | doctor [ios|android|release [ios|android]] [--remote name] [--json|--fix [--yes]] | build <android|ios> [server-entry] [--remote name] [--registered-device-artifact] [--outdir dir] [--web-outdir dir] [--unsigned] | update provision [--storage local|s3] [--registry module] [--force] [--yes] | update signing generate --private-key path [--certificate path] [--public-key path] [--key-id id] [--common-name name] [--validity-years n] | update build [server-entry] --classification bug-fix|content|security --key-id id --signing-key path --within-submitted-purpose [--outdir dir] [--web-outdir dir] | update publish <release-directory> [--rollout fraction] [--registry module] | update promote --release id --rollout fraction [--registry module] | update rollback [--release id] [--registry module] | update status [--registry module] [--json] | update advance [--rollout fraction] [--registry module] [--json] | update pause|resume|cancel|reconcile [--registry module] [--json] | update storage [--retain count] [--min-age-days days] [--registry module] [--json] | update gc [--retain count] [--min-age-days days] [--grace-days days] [--apply] [--registry module] [--json] | publish android [server-entry] [--release release-dir] [--certification certification-dir] [--registry module] [--channel name] [--play-track track] [--play-status completed|draft|halted|in-progress] [--play-rollout fraction] [--play-name name] [--play-notes language=text] [--play-update-priority 0..5] [--play-hold-review] [--play-cancel-existing-review] [--outdir dir] [--web-outdir dir] [--unsigned] | publish ios [server-entry] [--release release-dir] [--certification certification-dir] [--remote name] [--registry module] [--channel name] [--testflight-group name-or-id] [--testflight-notes locale=text] [--testflight-submit-review] [--outdir dir] [--web-outdir dir] [--unsigned] | test android [--release release-dir [--yes] | --route path [--wait-for-hmr] [--port n]] [--report [dir]] [--serial id] [--artifacts dir] [--json] [--config path] | test ios [--release release-dir [--remote name] [--device id [--testflight] --yes] | --wait-for-hmr] [--report [dir]] [--udid id] [--artifacts dir] [--json] [--config path]");
|
|
26680
26886
|
};
|
|
26681
26887
|
export {
|
|
26682
26888
|
runMobile
|