@absolutejs/deploy 0.22.0 → 0.23.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -48,6 +48,37 @@ both publication and promotion for intentionally non-publishable local-testing
48
48
  artifacts. The registry uses the structural BlobStore shape, so Deploy does not
49
49
  take a runtime dependency on `@absolutejs/blob` or a cloud SDK.
50
50
 
51
+ ### Google Play distribution (0.23.0)
52
+
53
+ `@absolutejs/deploy/google-play` composes the native registry with Google Play.
54
+ The same BlobStore persists stage receipts before external effects, allowing a
55
+ retry to reuse an unexpired edit or resumable upload and to reconcile a commit
56
+ whose successful response was lost.
57
+
58
+ ```ts
59
+ import { createGooglePlayReleasePublisher } from '@absolutejs/deploy/google-play';
60
+
61
+ export default createGooglePlayReleasePublisher({
62
+ receiptStore: store,
63
+ registry: releases
64
+ });
65
+ ```
66
+
67
+ AbsoluteJS supplies the requested track and rollout intent when the developer
68
+ runs `absolute mobile publish android --play-track internal`. Google
69
+ Application Default Credentials must have Android Publisher access to the app.
70
+ Before Gradle runs, the publisher inspects Play's existing bundles and returns
71
+ the next version code. It persists that allocation by application and complete
72
+ build identity, so retries and promotion to another track reuse the same code.
73
+ AbsoluteJS injects it into the AAB and the publisher verifies the upload response
74
+ returned that exact code. Serialize publication jobs for one application because
75
+ Google Play provides monotonic version codes but no reservation operation.
76
+ The default commit behavior is `ERROR_IF_IN_REVIEW`; opting into cancellation
77
+ of an existing review must therefore be explicit. Production staged rollouts
78
+ use `status: 'inProgress'` with `0 < userFraction < 1`; subsequent calls for the
79
+ same release can increase the fraction, halt or resume it, or mark it completed
80
+ without uploading the AAB again.
81
+
51
82
  ## Infrastructure providers (0.14.0)
52
83
 
53
84
  Control planes use the normalized `InfrastructureProvider` contract from
@@ -0,0 +1,172 @@
1
+ import type { NativeReleaseBlobStore, NativeReleasePublication, NativeReleaseRegistry } from "./nativeRelease";
2
+ declare const RECEIPT_FORMAT: 1;
3
+ export type GooglePlayReleaseStatus = "completed" | "draft" | "halted" | "inProgress";
4
+ export type GooglePlayReviewBehavior = "CANCEL_IN_REVIEW_AND_SUBMIT" | "ERROR_IF_IN_REVIEW";
5
+ export type GooglePlayReleaseTarget = {
6
+ changesNotSentForReview?: boolean;
7
+ inAppUpdatePriority?: number;
8
+ name?: string;
9
+ releaseNotes?: readonly {
10
+ language: string;
11
+ text: string;
12
+ }[];
13
+ reviewBehavior?: GooglePlayReviewBehavior;
14
+ status?: GooglePlayReleaseStatus;
15
+ track: string;
16
+ userFraction?: number;
17
+ };
18
+ export type GooglePlayReleaseIntent = {
19
+ changesNotSentForReview: boolean;
20
+ inAppUpdatePriority: number;
21
+ name?: string;
22
+ releaseNotes: Array<{
23
+ language: string;
24
+ text: string;
25
+ }>;
26
+ reviewBehavior: GooglePlayReviewBehavior;
27
+ status: GooglePlayReleaseStatus;
28
+ track: string;
29
+ userFraction?: number;
30
+ };
31
+ export type GooglePlayReleaseReceipt = {
32
+ editExpiresAt?: string;
33
+ editId?: string;
34
+ format: typeof RECEIPT_FORMAT;
35
+ intent: GooglePlayReleaseIntent;
36
+ packageName: string;
37
+ provider: "google-play";
38
+ releaseId: string;
39
+ sha256: string;
40
+ stage: "committed" | "editing" | "uploading" | "commit-pending";
41
+ updatedAt: string;
42
+ uploadSession?: string;
43
+ versionCode?: string;
44
+ };
45
+ export type GooglePlayBundle = {
46
+ sha1?: string;
47
+ sha256?: string;
48
+ versionCode: number;
49
+ };
50
+ export type GooglePlayTrackRelease = {
51
+ inAppUpdatePriority?: number;
52
+ name?: string;
53
+ releaseNotes?: Array<{
54
+ language: string;
55
+ text: string;
56
+ }>;
57
+ status?: GooglePlayReleaseStatus;
58
+ userFraction?: number;
59
+ versionCodes?: string[];
60
+ };
61
+ export type GooglePlayTrack = {
62
+ releases?: GooglePlayTrackRelease[];
63
+ track?: string;
64
+ };
65
+ export type GooglePlayEdit = {
66
+ expiryTimeSeconds?: string;
67
+ id: string;
68
+ };
69
+ export type GooglePlayClient = {
70
+ commitEdit: (options: {
71
+ changesNotSentForReview: boolean;
72
+ editId: string;
73
+ packageName: string;
74
+ reviewBehavior: GooglePlayReviewBehavior;
75
+ signal?: AbortSignal;
76
+ }) => Promise<void>;
77
+ deleteEdit: (options: {
78
+ editId: string;
79
+ packageName: string;
80
+ signal?: AbortSignal;
81
+ }) => Promise<void>;
82
+ getEdit: (options: {
83
+ editId: string;
84
+ packageName: string;
85
+ signal?: AbortSignal;
86
+ }) => Promise<GooglePlayEdit | null>;
87
+ getTrack: (options: {
88
+ editId: string;
89
+ packageName: string;
90
+ signal?: AbortSignal;
91
+ track: string;
92
+ }) => Promise<GooglePlayTrack>;
93
+ insertEdit: (options: {
94
+ packageName: string;
95
+ signal?: AbortSignal;
96
+ }) => Promise<GooglePlayEdit>;
97
+ listBundles: (options: {
98
+ editId: string;
99
+ packageName: string;
100
+ signal?: AbortSignal;
101
+ }) => Promise<GooglePlayBundle[]>;
102
+ startBundleUpload: (options: {
103
+ bytes: number;
104
+ editId: string;
105
+ packageName: string;
106
+ signal?: AbortSignal;
107
+ }) => Promise<string>;
108
+ updateTrack: (options: {
109
+ editId: string;
110
+ packageName: string;
111
+ signal?: AbortSignal;
112
+ track: GooglePlayTrack;
113
+ trackName: string;
114
+ }) => Promise<GooglePlayTrack>;
115
+ uploadBundle: (options: {
116
+ artifactPath: string;
117
+ bytes: number;
118
+ sessionUrl: string;
119
+ signal?: AbortSignal;
120
+ }) => Promise<GooglePlayBundle>;
121
+ validateEdit: (options: {
122
+ editId: string;
123
+ packageName: string;
124
+ signal?: AbortSignal;
125
+ }) => Promise<void>;
126
+ };
127
+ export type GooglePlayReleasePublisherOptions = {
128
+ client?: GooglePlayClient;
129
+ clock?: () => Date;
130
+ receiptPrefix?: string;
131
+ receiptStore: NativeReleaseBlobStore;
132
+ registry: NativeReleaseRegistry;
133
+ target?: GooglePlayReleaseTarget;
134
+ };
135
+ export type GooglePlayNativeReleasePublication = NativeReleasePublication & {
136
+ googlePlay?: {
137
+ receipt: GooglePlayReleaseReceipt;
138
+ reused: boolean;
139
+ };
140
+ };
141
+ export type GooglePlayNativeReleasePublisher = {
142
+ prepareAndroidRelease: (options: {
143
+ buildIdentity: string;
144
+ googlePlay?: GooglePlayReleaseTarget;
145
+ packageName: string;
146
+ signal?: AbortSignal;
147
+ }) => Promise<{
148
+ versionCode?: number;
149
+ }>;
150
+ publish: (options: {
151
+ allowUnsigned?: boolean;
152
+ channel?: string;
153
+ googlePlay?: GooglePlayReleaseTarget;
154
+ releaseRoot: string;
155
+ signal?: AbortSignal;
156
+ }) => Promise<GooglePlayNativeReleasePublication>;
157
+ };
158
+ export declare class GooglePlayReleaseError extends Error {
159
+ readonly status?: number;
160
+ constructor(message: string, status?: number);
161
+ }
162
+ export type GooglePlayAuth = {
163
+ getClient: () => Promise<{
164
+ getRequestHeaders: (url?: string | URL) => Promise<Headers | Record<string, string>>;
165
+ }>;
166
+ };
167
+ export declare const createGooglePlayClient: (dependencies?: {
168
+ auth?: GooglePlayAuth;
169
+ fetch?: typeof fetch;
170
+ }) => GooglePlayClient;
171
+ export declare const createGooglePlayReleasePublisher: (options: GooglePlayReleasePublisherOptions) => GooglePlayNativeReleasePublisher;
172
+ export {};