@expo/eas-json 0.26.0 → 0.29.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/build/EasJson.types.d.ts +5 -4
- package/build/EasJson.types.js +1 -0
- package/build/EasJsonReader.d.ts +1 -0
- package/build/EasJsonReader.js +42 -13
- package/build/EasSubmit.types.d.ts +2 -0
- package/build/EasSubmit.types.js +5 -1
- package/build/migrate.js +16 -6
- package/package.json +5 -3
- package/src/DeprecatedEasJsonSchema.ts +1 -1
- package/src/EasJson.types.ts +6 -4
- package/src/EasJsonReader.ts +50 -16
- package/src/EasJsonSchema.ts +1 -1
- package/src/EasSubmit.types.ts +6 -0
- package/src/__tests__/EasJsonReader-build-test.ts +2 -2
- package/src/__tests__/EasJsonReader-submit-test.ts +30 -23
- package/src/migrate.ts +16 -6
package/build/EasJson.types.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { Platform } from '@expo/eas-build-job';
|
|
1
2
|
import { AndroidBuildProfile, CommonBuildProfile, IosBuildProfile } from './EasBuild.types';
|
|
2
3
|
import { AndroidSubmitProfile, IosSubmitProfile } from './EasSubmit.types';
|
|
3
4
|
export declare enum CredentialsSource {
|
|
@@ -6,12 +7,12 @@ export declare enum CredentialsSource {
|
|
|
6
7
|
}
|
|
7
8
|
export interface RawBuildProfile extends Partial<CommonBuildProfile> {
|
|
8
9
|
extends?: string;
|
|
9
|
-
|
|
10
|
-
|
|
10
|
+
[Platform.ANDROID]?: Partial<AndroidBuildProfile>;
|
|
11
|
+
[Platform.IOS]?: Partial<IosBuildProfile>;
|
|
11
12
|
}
|
|
12
13
|
export interface EasSubmitConfiguration {
|
|
13
|
-
|
|
14
|
-
|
|
14
|
+
[Platform.ANDROID]?: AndroidSubmitProfile;
|
|
15
|
+
[Platform.IOS]?: IosSubmitProfile;
|
|
15
16
|
}
|
|
16
17
|
export interface EasJson {
|
|
17
18
|
build: {
|
package/build/EasJson.types.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.CredentialsSource = void 0;
|
|
4
|
+
const eas_build_job_1 = require("@expo/eas-build-job");
|
|
4
5
|
var CredentialsSource;
|
|
5
6
|
(function (CredentialsSource) {
|
|
6
7
|
CredentialsSource["LOCAL"] = "local";
|
package/build/EasJsonReader.d.ts
CHANGED
|
@@ -24,6 +24,7 @@ export declare class EasJsonReader {
|
|
|
24
24
|
readRawAsync(): Promise<EasJsonPreValidation>;
|
|
25
25
|
private resolveBuildProfile;
|
|
26
26
|
private ensureBuildProfileExists;
|
|
27
|
+
private evaluateFields;
|
|
27
28
|
}
|
|
28
29
|
export declare function profileMerge(base: RawBuildProfile, update: RawBuildProfile): RawBuildProfile;
|
|
29
30
|
export {};
|
package/build/EasJsonReader.js
CHANGED
|
@@ -3,10 +3,12 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.profileMerge = exports.EasJsonReader = void 0;
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
5
|
const eas_build_job_1 = require("@expo/eas-build-job");
|
|
6
|
-
const
|
|
6
|
+
const json_file_1 = (0, tslib_1.__importDefault)(require("@expo/json-file"));
|
|
7
|
+
const env_string_1 = (0, tslib_1.__importDefault)(require("env-string"));
|
|
7
8
|
const path_1 = (0, tslib_1.__importDefault)(require("path"));
|
|
8
9
|
const EasJson_types_1 = require("./EasJson.types");
|
|
9
10
|
const EasJsonSchema_1 = require("./EasJsonSchema");
|
|
11
|
+
const EasSubmit_types_1 = require("./EasSubmit.types");
|
|
10
12
|
const defaults = {
|
|
11
13
|
distribution: 'store',
|
|
12
14
|
credentialsSource: EasJson_types_1.CredentialsSource.REMOTE,
|
|
@@ -55,7 +57,7 @@ class EasJsonReader {
|
|
|
55
57
|
}
|
|
56
58
|
}
|
|
57
59
|
async readSubmitProfileAsync(platform, profileName) {
|
|
58
|
-
var _a
|
|
60
|
+
var _a;
|
|
59
61
|
if (!profileName) {
|
|
60
62
|
const profileNames = await this.getSubmitProfileNamesAsync({
|
|
61
63
|
throwIfEasJsonDoesNotExist: false,
|
|
@@ -68,11 +70,17 @@ class EasJsonReader {
|
|
|
68
70
|
}
|
|
69
71
|
}
|
|
70
72
|
const easJson = await this.readAndValidateAsync();
|
|
71
|
-
const profile = (
|
|
73
|
+
const profile = (_a = easJson === null || easJson === void 0 ? void 0 : easJson.submit) === null || _a === void 0 ? void 0 : _a[profileName];
|
|
72
74
|
if (!profile) {
|
|
73
|
-
throw new Error(`There is no profile named ${profileName} in eas.json
|
|
75
|
+
throw new Error(`There is no profile named ${profileName} in eas.json`);
|
|
76
|
+
}
|
|
77
|
+
const platformProfile = profile[platform];
|
|
78
|
+
if (platformProfile) {
|
|
79
|
+
return this.evaluateFields(platform, platformProfile);
|
|
80
|
+
}
|
|
81
|
+
else {
|
|
82
|
+
return getDefaultSubmitProfile(platform);
|
|
74
83
|
}
|
|
75
|
-
return profile;
|
|
76
84
|
}
|
|
77
85
|
async readAndValidateAsync() {
|
|
78
86
|
const easJson = await this.readRawAsync();
|
|
@@ -87,13 +95,21 @@ class EasJsonReader {
|
|
|
87
95
|
return value;
|
|
88
96
|
}
|
|
89
97
|
async readRawAsync() {
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
98
|
+
try {
|
|
99
|
+
const easJsonPath = EasJsonReader.formatEasJsonPath(this.projectDir);
|
|
100
|
+
const rawEasJson = json_file_1.default.read(easJsonPath);
|
|
101
|
+
const { value, error } = EasJsonSchema_1.MinimalEasJsonSchema.validate(rawEasJson, { abortEarly: false });
|
|
102
|
+
if (error) {
|
|
103
|
+
throw new Error(`eas.json is not valid [${error.toString()}]`);
|
|
104
|
+
}
|
|
105
|
+
return value;
|
|
106
|
+
}
|
|
107
|
+
catch (err) {
|
|
108
|
+
if (err.code === 'EJSONPARSE') {
|
|
109
|
+
err.message = `Found invalid JSON in eas.json. ${err.message}`;
|
|
110
|
+
}
|
|
111
|
+
throw err;
|
|
95
112
|
}
|
|
96
|
-
return value;
|
|
97
113
|
}
|
|
98
114
|
resolveBuildProfile(easJson, profileName, depth = 0) {
|
|
99
115
|
if (depth >= 2) {
|
|
@@ -101,7 +117,7 @@ class EasJsonReader {
|
|
|
101
117
|
}
|
|
102
118
|
const buildProfile = easJson.build[profileName];
|
|
103
119
|
if (!buildProfile) {
|
|
104
|
-
throw new Error(`There is no profile named ${profileName}`);
|
|
120
|
+
throw new Error(`There is no profile named ${profileName} in eas.json`);
|
|
105
121
|
}
|
|
106
122
|
const { extends: baseProfileName, ...buildProfileRest } = buildProfile;
|
|
107
123
|
if (baseProfileName) {
|
|
@@ -113,8 +129,21 @@ class EasJsonReader {
|
|
|
113
129
|
}
|
|
114
130
|
ensureBuildProfileExists(easJson, profileName) {
|
|
115
131
|
if (!easJson.build || !easJson.build[profileName]) {
|
|
116
|
-
throw new Error(`There is no profile named ${profileName} in eas.json
|
|
132
|
+
throw new Error(`There is no profile named ${profileName} in eas.json`);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
evaluateFields(platform, profile) {
|
|
136
|
+
const fields = platform === eas_build_job_1.Platform.ANDROID
|
|
137
|
+
? EasSubmit_types_1.AndroidSubmitProfileFieldsToEvaluate
|
|
138
|
+
: EasSubmit_types_1.IosSubmitProfileFieldsToEvaluate;
|
|
139
|
+
const evaluatedProfile = { ...profile };
|
|
140
|
+
for (const field of fields) {
|
|
141
|
+
if (field in evaluatedProfile) {
|
|
142
|
+
// @ts-ignore
|
|
143
|
+
evaluatedProfile[field] = (0, env_string_1.default)(evaluatedProfile[field], process.env);
|
|
144
|
+
}
|
|
117
145
|
}
|
|
146
|
+
return evaluatedProfile;
|
|
118
147
|
}
|
|
119
148
|
}
|
|
120
149
|
exports.EasJsonReader = EasJsonReader;
|
|
@@ -17,6 +17,7 @@ export interface AndroidSubmitProfile {
|
|
|
17
17
|
releaseStatus: AndroidReleaseStatus;
|
|
18
18
|
changesNotSentForReview: boolean;
|
|
19
19
|
}
|
|
20
|
+
export declare const AndroidSubmitProfileFieldsToEvaluate: (keyof AndroidSubmitProfile)[];
|
|
20
21
|
export interface IosSubmitProfile {
|
|
21
22
|
appleId?: string;
|
|
22
23
|
ascAppId?: string;
|
|
@@ -26,4 +27,5 @@ export interface IosSubmitProfile {
|
|
|
26
27
|
companyName?: string;
|
|
27
28
|
appName?: string;
|
|
28
29
|
}
|
|
30
|
+
export declare const IosSubmitProfileFieldsToEvaluate: (keyof IosSubmitProfile)[];
|
|
29
31
|
export declare type SubmitProfile<TPlatform extends Platform = Platform> = TPlatform extends Platform.ANDROID ? AndroidSubmitProfile : TPlatform extends Platform.IOS ? IosSubmitProfile : TPlatform extends Platform ? AndroidSubmitProfile | IosSubmitProfile : never;
|
package/build/EasSubmit.types.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.AndroidReleaseTrack = exports.AndroidReleaseStatus = void 0;
|
|
3
|
+
exports.IosSubmitProfileFieldsToEvaluate = exports.AndroidSubmitProfileFieldsToEvaluate = exports.AndroidReleaseTrack = exports.AndroidReleaseStatus = void 0;
|
|
4
4
|
var AndroidReleaseStatus;
|
|
5
5
|
(function (AndroidReleaseStatus) {
|
|
6
6
|
AndroidReleaseStatus["completed"] = "completed";
|
|
@@ -15,3 +15,7 @@ var AndroidReleaseTrack;
|
|
|
15
15
|
AndroidReleaseTrack["alpha"] = "alpha";
|
|
16
16
|
AndroidReleaseTrack["internal"] = "internal";
|
|
17
17
|
})(AndroidReleaseTrack = exports.AndroidReleaseTrack || (exports.AndroidReleaseTrack = {}));
|
|
18
|
+
exports.AndroidSubmitProfileFieldsToEvaluate = [
|
|
19
|
+
'serviceAccountKeyPath',
|
|
20
|
+
];
|
|
21
|
+
exports.IosSubmitProfileFieldsToEvaluate = [];
|
package/build/migrate.js
CHANGED
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.migrateProfile = exports.migrateAsync = exports.hasMismatchedExtendsAsync = exports.isUsingDeprecatedFormatAsync = void 0;
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
5
|
const eas_build_job_1 = require("@expo/eas-build-job");
|
|
6
|
+
const json_file_1 = (0, tslib_1.__importDefault)(require("@expo/json-file"));
|
|
6
7
|
const fs_extra_1 = (0, tslib_1.__importDefault)(require("fs-extra"));
|
|
7
8
|
const path_1 = (0, tslib_1.__importDefault)(require("path"));
|
|
8
9
|
const DeprecatedEasJsonReader_1 = require("./DeprecatedEasJsonReader");
|
|
@@ -11,15 +12,13 @@ async function isUsingDeprecatedFormatAsync(projectDir) {
|
|
|
11
12
|
if (!(await fs_extra_1.default.pathExists(easJsonPath))) {
|
|
12
13
|
return false;
|
|
13
14
|
}
|
|
14
|
-
const
|
|
15
|
-
const json = JSON.parse(rawFile);
|
|
15
|
+
const json = await readEasJsonAsync(projectDir);
|
|
16
16
|
return !!(json === null || json === void 0 ? void 0 : json.builds);
|
|
17
17
|
}
|
|
18
18
|
exports.isUsingDeprecatedFormatAsync = isUsingDeprecatedFormatAsync;
|
|
19
19
|
async function hasMismatchedExtendsAsync(projectDir) {
|
|
20
20
|
var _a, _b;
|
|
21
|
-
const
|
|
22
|
-
const rawEasJson = JSON.parse(rawFile);
|
|
21
|
+
const rawEasJson = (await readEasJsonAsync(projectDir));
|
|
23
22
|
const profiles = new Set();
|
|
24
23
|
Object.keys((_a = rawEasJson.builds.android) !== null && _a !== void 0 ? _a : {}).forEach(profile => profiles.add(profile));
|
|
25
24
|
Object.keys((_b = rawEasJson.builds.ios) !== null && _b !== void 0 ? _b : {}).forEach(profile => profiles.add(profile));
|
|
@@ -43,8 +42,7 @@ async function migrateAsync(projectDir) {
|
|
|
43
42
|
catch (err) {
|
|
44
43
|
throw new Error(`Valid eas.json is required to migrate to the new format\n${err.message}`);
|
|
45
44
|
}
|
|
46
|
-
const
|
|
47
|
-
const rawEasJson = JSON.parse(rawFile);
|
|
45
|
+
const rawEasJson = (await readEasJsonAsync(projectDir));
|
|
48
46
|
const profiles = new Set();
|
|
49
47
|
Object.keys((_a = rawEasJson.builds.android) !== null && _a !== void 0 ? _a : {}).forEach(profile => profiles.add(profile));
|
|
50
48
|
Object.keys((_b = rawEasJson.builds.ios) !== null && _b !== void 0 ? _b : {}).forEach(profile => profiles.add(profile));
|
|
@@ -57,6 +55,18 @@ async function migrateAsync(projectDir) {
|
|
|
57
55
|
await fs_extra_1.default.writeFile(path_1.default.join(projectDir, 'eas.json'), `${JSON.stringify(result, null, 2)}\n`);
|
|
58
56
|
}
|
|
59
57
|
exports.migrateAsync = migrateAsync;
|
|
58
|
+
async function readEasJsonAsync(projectDir) {
|
|
59
|
+
try {
|
|
60
|
+
const easJsonPath = path_1.default.join(projectDir, 'eas.json');
|
|
61
|
+
return json_file_1.default.read(easJsonPath);
|
|
62
|
+
}
|
|
63
|
+
catch (err) {
|
|
64
|
+
if (err.code === 'EJSONPARSE') {
|
|
65
|
+
err.message = `Found invalid JSON in eas.json. ${err.message}`;
|
|
66
|
+
}
|
|
67
|
+
throw err;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
60
70
|
function migrateProfile(rawEasJson, profileName) {
|
|
61
71
|
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
62
72
|
const androidProfile = ((_c = (_b = (_a = rawEasJson === null || rawEasJson === void 0 ? void 0 : rawEasJson.builds) === null || _a === void 0 ? void 0 : _a.android) === null || _b === void 0 ? void 0 : _b[profileName]) !== null && _c !== void 0 ? _c : {});
|
package/package.json
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@expo/eas-json",
|
|
3
3
|
"description": "A library for interacting with the eas.json",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.29.0",
|
|
5
5
|
"author": "Expo <support@expo.dev>",
|
|
6
6
|
"bugs": "https://github.com/expo/eas-cli/issues",
|
|
7
7
|
"dependencies": {
|
|
8
|
-
"@expo/eas-build-job": "0.2.
|
|
8
|
+
"@expo/eas-build-job": "0.2.48",
|
|
9
|
+
"@expo/json-file": "8.2.33",
|
|
10
|
+
"env-string": "1.0.1",
|
|
9
11
|
"fs-extra": "10.0.0",
|
|
10
12
|
"joi": "17.4.2",
|
|
11
13
|
"tslib": "2.3.1"
|
|
@@ -31,5 +33,5 @@
|
|
|
31
33
|
"publishConfig": {
|
|
32
34
|
"access": "public"
|
|
33
35
|
},
|
|
34
|
-
"gitHead": "
|
|
36
|
+
"gitHead": "6e1c7dd91e4d6ba45dca2744bd9c95fc32bed62d"
|
|
35
37
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Android, Ios } from '@expo/eas-build-job';
|
|
2
2
|
import Joi, { CustomHelpers } from 'joi';
|
|
3
3
|
|
|
4
|
-
const semverSchemaCheck = (value: any, helpers: CustomHelpers) => {
|
|
4
|
+
const semverSchemaCheck = (value: any, helpers: CustomHelpers): any => {
|
|
5
5
|
if (/^[0-9]+\.[0-9]+\.[0-9]+$/.test(value)) {
|
|
6
6
|
return value;
|
|
7
7
|
} else {
|
package/src/EasJson.types.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { Platform } from '@expo/eas-build-job';
|
|
2
|
+
|
|
1
3
|
import { AndroidBuildProfile, CommonBuildProfile, IosBuildProfile } from './EasBuild.types';
|
|
2
4
|
import { AndroidSubmitProfile, IosSubmitProfile } from './EasSubmit.types';
|
|
3
5
|
|
|
@@ -8,13 +10,13 @@ export enum CredentialsSource {
|
|
|
8
10
|
|
|
9
11
|
export interface RawBuildProfile extends Partial<CommonBuildProfile> {
|
|
10
12
|
extends?: string;
|
|
11
|
-
|
|
12
|
-
|
|
13
|
+
[Platform.ANDROID]?: Partial<AndroidBuildProfile>;
|
|
14
|
+
[Platform.IOS]?: Partial<IosBuildProfile>;
|
|
13
15
|
}
|
|
14
16
|
|
|
15
17
|
export interface EasSubmitConfiguration {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
+
[Platform.ANDROID]?: AndroidSubmitProfile;
|
|
19
|
+
[Platform.IOS]?: IosSubmitProfile;
|
|
18
20
|
}
|
|
19
21
|
|
|
20
22
|
export interface EasJson {
|
package/src/EasJsonReader.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Platform } from '@expo/eas-build-job';
|
|
2
|
-
import
|
|
2
|
+
import JsonFile from '@expo/json-file';
|
|
3
|
+
import envString from 'env-string';
|
|
3
4
|
import path from 'path';
|
|
4
5
|
|
|
5
6
|
import { BuildProfile } from './EasBuild.types';
|
|
@@ -10,7 +11,11 @@ import {
|
|
|
10
11
|
IosSubmitProfileSchema,
|
|
11
12
|
MinimalEasJsonSchema,
|
|
12
13
|
} from './EasJsonSchema';
|
|
13
|
-
import {
|
|
14
|
+
import {
|
|
15
|
+
AndroidSubmitProfileFieldsToEvaluate,
|
|
16
|
+
IosSubmitProfileFieldsToEvaluate,
|
|
17
|
+
SubmitProfile,
|
|
18
|
+
} from './EasSubmit.types';
|
|
14
19
|
|
|
15
20
|
interface EasJsonPreValidation {
|
|
16
21
|
build: { [profile: string]: object };
|
|
@@ -23,7 +28,7 @@ const defaults = {
|
|
|
23
28
|
} as const;
|
|
24
29
|
|
|
25
30
|
export class EasJsonReader {
|
|
26
|
-
public static formatEasJsonPath(projectDir: string) {
|
|
31
|
+
public static formatEasJsonPath(projectDir: string): string {
|
|
27
32
|
return path.join(projectDir, 'eas.json');
|
|
28
33
|
}
|
|
29
34
|
|
|
@@ -89,11 +94,16 @@ export class EasJsonReader {
|
|
|
89
94
|
}
|
|
90
95
|
}
|
|
91
96
|
const easJson = await this.readAndValidateAsync();
|
|
92
|
-
const profile = easJson?.submit?.[profileName]
|
|
97
|
+
const profile = easJson?.submit?.[profileName];
|
|
93
98
|
if (!profile) {
|
|
94
|
-
throw new Error(`There is no profile named ${profileName} in eas.json
|
|
99
|
+
throw new Error(`There is no profile named ${profileName} in eas.json`);
|
|
100
|
+
}
|
|
101
|
+
const platformProfile = profile[platform];
|
|
102
|
+
if (platformProfile) {
|
|
103
|
+
return this.evaluateFields(platform, platformProfile as SubmitProfile<T>);
|
|
104
|
+
} else {
|
|
105
|
+
return getDefaultSubmitProfile(platform);
|
|
95
106
|
}
|
|
96
|
-
return profile as SubmitProfile<T>;
|
|
97
107
|
}
|
|
98
108
|
|
|
99
109
|
public async readAndValidateAsync(): Promise<EasJson> {
|
|
@@ -111,14 +121,20 @@ export class EasJsonReader {
|
|
|
111
121
|
}
|
|
112
122
|
|
|
113
123
|
public async readRawAsync(): Promise<EasJsonPreValidation> {
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
124
|
+
try {
|
|
125
|
+
const easJsonPath = EasJsonReader.formatEasJsonPath(this.projectDir);
|
|
126
|
+
const rawEasJson = JsonFile.read(easJsonPath);
|
|
127
|
+
const { value, error } = MinimalEasJsonSchema.validate(rawEasJson, { abortEarly: false });
|
|
128
|
+
if (error) {
|
|
129
|
+
throw new Error(`eas.json is not valid [${error.toString()}]`);
|
|
130
|
+
}
|
|
131
|
+
return value;
|
|
132
|
+
} catch (err: any) {
|
|
133
|
+
if (err.code === 'EJSONPARSE') {
|
|
134
|
+
err.message = `Found invalid JSON in eas.json. ${err.message}`;
|
|
135
|
+
}
|
|
136
|
+
throw err;
|
|
120
137
|
}
|
|
121
|
-
return value;
|
|
122
138
|
}
|
|
123
139
|
|
|
124
140
|
private resolveBuildProfile(
|
|
@@ -133,7 +149,7 @@ export class EasJsonReader {
|
|
|
133
149
|
}
|
|
134
150
|
const buildProfile = easJson.build[profileName];
|
|
135
151
|
if (!buildProfile) {
|
|
136
|
-
throw new Error(`There is no profile named ${profileName}`);
|
|
152
|
+
throw new Error(`There is no profile named ${profileName} in eas.json`);
|
|
137
153
|
}
|
|
138
154
|
const { extends: baseProfileName, ...buildProfileRest } = buildProfile;
|
|
139
155
|
if (baseProfileName) {
|
|
@@ -146,10 +162,28 @@ export class EasJsonReader {
|
|
|
146
162
|
}
|
|
147
163
|
}
|
|
148
164
|
|
|
149
|
-
private ensureBuildProfileExists(easJson: EasJson, profileName: string) {
|
|
165
|
+
private ensureBuildProfileExists(easJson: EasJson, profileName: string): void {
|
|
150
166
|
if (!easJson.build || !easJson.build[profileName]) {
|
|
151
|
-
throw new Error(`There is no profile named ${profileName} in eas.json
|
|
167
|
+
throw new Error(`There is no profile named ${profileName} in eas.json`);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
private evaluateFields<T extends Platform>(
|
|
172
|
+
platform: T,
|
|
173
|
+
profile: SubmitProfile<T>
|
|
174
|
+
): SubmitProfile<T> {
|
|
175
|
+
const fields =
|
|
176
|
+
platform === Platform.ANDROID
|
|
177
|
+
? AndroidSubmitProfileFieldsToEvaluate
|
|
178
|
+
: IosSubmitProfileFieldsToEvaluate;
|
|
179
|
+
const evaluatedProfile = { ...profile };
|
|
180
|
+
for (const field of fields) {
|
|
181
|
+
if (field in evaluatedProfile) {
|
|
182
|
+
// @ts-ignore
|
|
183
|
+
evaluatedProfile[field] = envString(evaluatedProfile[field], process.env);
|
|
184
|
+
}
|
|
152
185
|
}
|
|
186
|
+
return evaluatedProfile;
|
|
153
187
|
}
|
|
154
188
|
}
|
|
155
189
|
|
package/src/EasJsonSchema.ts
CHANGED
|
@@ -3,7 +3,7 @@ import Joi from 'joi';
|
|
|
3
3
|
|
|
4
4
|
import { AndroidReleaseStatus, AndroidReleaseTrack } from './EasSubmit.types';
|
|
5
5
|
|
|
6
|
-
const semverSchemaCheck = (value: any) => {
|
|
6
|
+
const semverSchemaCheck = (value: any): any => {
|
|
7
7
|
if (/^[0-9]+\.[0-9]+\.[0-9]+$/.test(value)) {
|
|
8
8
|
return value;
|
|
9
9
|
} else {
|
package/src/EasSubmit.types.ts
CHANGED
|
@@ -21,6 +21,10 @@ export interface AndroidSubmitProfile {
|
|
|
21
21
|
changesNotSentForReview: boolean;
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
+
export const AndroidSubmitProfileFieldsToEvaluate: (keyof AndroidSubmitProfile)[] = [
|
|
25
|
+
'serviceAccountKeyPath',
|
|
26
|
+
];
|
|
27
|
+
|
|
24
28
|
export interface IosSubmitProfile {
|
|
25
29
|
appleId?: string;
|
|
26
30
|
ascAppId?: string;
|
|
@@ -31,6 +35,8 @@ export interface IosSubmitProfile {
|
|
|
31
35
|
appName?: string;
|
|
32
36
|
}
|
|
33
37
|
|
|
38
|
+
export const IosSubmitProfileFieldsToEvaluate: (keyof IosSubmitProfile)[] = [];
|
|
39
|
+
|
|
34
40
|
export type SubmitProfile<TPlatform extends Platform = Platform> =
|
|
35
41
|
TPlatform extends Platform.ANDROID
|
|
36
42
|
? AndroidSubmitProfile
|
|
@@ -225,7 +225,7 @@ test('valid eas.json with missing profile', async () => {
|
|
|
225
225
|
|
|
226
226
|
const reader = new EasJsonReader('/project');
|
|
227
227
|
const promise = reader.readBuildProfileAsync(Platform.ANDROID, 'debug');
|
|
228
|
-
await expect(promise).rejects.toThrowError('There is no profile named debug in eas.json
|
|
228
|
+
await expect(promise).rejects.toThrowError('There is no profile named debug in eas.json');
|
|
229
229
|
});
|
|
230
230
|
|
|
231
231
|
test('invalid eas.json when using wrong buildType', async () => {
|
|
@@ -247,7 +247,7 @@ test('empty json', async () => {
|
|
|
247
247
|
|
|
248
248
|
const reader = new EasJsonReader('/project');
|
|
249
249
|
const promise = reader.readBuildProfileAsync(Platform.ANDROID, 'release');
|
|
250
|
-
await expect(promise).rejects.toThrowError('There is no profile named release in eas.json
|
|
250
|
+
await expect(promise).rejects.toThrowError('There is no profile named release in eas.json');
|
|
251
251
|
});
|
|
252
252
|
|
|
253
253
|
test('invalid semver value', async () => {
|
|
@@ -14,10 +14,7 @@ beforeEach(async () => {
|
|
|
14
14
|
test('minimal allowed eas.json for both platforms', async () => {
|
|
15
15
|
await fs.writeJson('/project/eas.json', {
|
|
16
16
|
submit: {
|
|
17
|
-
release: {
|
|
18
|
-
android: {},
|
|
19
|
-
ios: {},
|
|
20
|
-
},
|
|
17
|
+
release: {},
|
|
21
18
|
},
|
|
22
19
|
});
|
|
23
20
|
|
|
@@ -59,6 +56,35 @@ test('android config with all required values', async () => {
|
|
|
59
56
|
});
|
|
60
57
|
});
|
|
61
58
|
|
|
59
|
+
test('android config with serviceAccountKeyPath set to env var', async () => {
|
|
60
|
+
await fs.writeJson('/project/eas.json', {
|
|
61
|
+
submit: {
|
|
62
|
+
release: {
|
|
63
|
+
android: {
|
|
64
|
+
serviceAccountKeyPath: '$GOOGLE_SERVICE_ACCOUNT',
|
|
65
|
+
track: 'beta',
|
|
66
|
+
releaseStatus: 'completed',
|
|
67
|
+
},
|
|
68
|
+
},
|
|
69
|
+
},
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
try {
|
|
73
|
+
process.env.GOOGLE_SERVICE_ACCOUNT = './path.json';
|
|
74
|
+
const reader = new EasJsonReader('/project');
|
|
75
|
+
const androidProfile = await reader.readSubmitProfileAsync(Platform.ANDROID, 'release');
|
|
76
|
+
|
|
77
|
+
expect(androidProfile).toEqual({
|
|
78
|
+
serviceAccountKeyPath: './path.json',
|
|
79
|
+
track: 'beta',
|
|
80
|
+
releaseStatus: 'completed',
|
|
81
|
+
changesNotSentForReview: false,
|
|
82
|
+
});
|
|
83
|
+
} finally {
|
|
84
|
+
process.env.GOOGLE_SERVICE_ACCOUNT = undefined;
|
|
85
|
+
}
|
|
86
|
+
});
|
|
87
|
+
|
|
62
88
|
test('ios config with all required values', async () => {
|
|
63
89
|
await fs.writeJson('/project/eas.json', {
|
|
64
90
|
submit: {
|
|
@@ -82,22 +108,3 @@ test('ios config with all required values', async () => {
|
|
|
82
108
|
language: 'en-US',
|
|
83
109
|
});
|
|
84
110
|
});
|
|
85
|
-
|
|
86
|
-
test('missing ios profile', async () => {
|
|
87
|
-
await fs.writeJson('/project/eas.json', {
|
|
88
|
-
submit: {
|
|
89
|
-
release: {
|
|
90
|
-
android: {
|
|
91
|
-
serviceAccountKeyPath: './path.json',
|
|
92
|
-
track: 'beta',
|
|
93
|
-
releaseStatus: 'completed',
|
|
94
|
-
},
|
|
95
|
-
},
|
|
96
|
-
},
|
|
97
|
-
});
|
|
98
|
-
|
|
99
|
-
const reader = new EasJsonReader('/project');
|
|
100
|
-
const promise = reader.readSubmitProfileAsync(Platform.IOS, 'release');
|
|
101
|
-
|
|
102
|
-
expect(promise).rejects.toThrow('There is no profile named release in eas.json for ios.');
|
|
103
|
-
});
|
package/src/migrate.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Android, Ios } from '@expo/eas-build-job';
|
|
2
|
+
import JsonFile, { JSONObject } from '@expo/json-file';
|
|
2
3
|
import fs from 'fs-extra';
|
|
3
4
|
import path from 'path';
|
|
4
5
|
|
|
@@ -11,14 +12,12 @@ export async function isUsingDeprecatedFormatAsync(projectDir: string): Promise<
|
|
|
11
12
|
if (!(await fs.pathExists(easJsonPath))) {
|
|
12
13
|
return false;
|
|
13
14
|
}
|
|
14
|
-
const
|
|
15
|
-
const json = JSON.parse(rawFile);
|
|
15
|
+
const json = await readEasJsonAsync(projectDir);
|
|
16
16
|
return !!json?.builds;
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
export async function hasMismatchedExtendsAsync(projectDir: string): Promise<boolean> {
|
|
20
|
-
const
|
|
21
|
-
const rawEasJson = JSON.parse(rawFile) as DeprecatedEasJson;
|
|
20
|
+
const rawEasJson = (await readEasJsonAsync(projectDir)) as unknown as DeprecatedEasJson;
|
|
22
21
|
const profiles = new Set<string>();
|
|
23
22
|
Object.keys(rawEasJson.builds.android ?? {}).forEach(profile => profiles.add(profile));
|
|
24
23
|
Object.keys(rawEasJson.builds.ios ?? {}).forEach(profile => profiles.add(profile));
|
|
@@ -42,8 +41,7 @@ export async function migrateAsync(projectDir: string): Promise<void> {
|
|
|
42
41
|
} catch (err: any) {
|
|
43
42
|
throw new Error(`Valid eas.json is required to migrate to the new format\n${err.message}`);
|
|
44
43
|
}
|
|
45
|
-
const
|
|
46
|
-
const rawEasJson = JSON.parse(rawFile) as DeprecatedEasJson;
|
|
44
|
+
const rawEasJson = (await readEasJsonAsync(projectDir)) as unknown as DeprecatedEasJson;
|
|
47
45
|
const profiles = new Set<string>();
|
|
48
46
|
Object.keys(rawEasJson.builds.android ?? {}).forEach(profile => profiles.add(profile));
|
|
49
47
|
Object.keys(rawEasJson.builds.ios ?? {}).forEach(profile => profiles.add(profile));
|
|
@@ -57,6 +55,18 @@ export async function migrateAsync(projectDir: string): Promise<void> {
|
|
|
57
55
|
await fs.writeFile(path.join(projectDir, 'eas.json'), `${JSON.stringify(result, null, 2)}\n`);
|
|
58
56
|
}
|
|
59
57
|
|
|
58
|
+
async function readEasJsonAsync(projectDir: string): Promise<JSONObject> {
|
|
59
|
+
try {
|
|
60
|
+
const easJsonPath = path.join(projectDir, 'eas.json');
|
|
61
|
+
return JsonFile.read(easJsonPath);
|
|
62
|
+
} catch (err: any) {
|
|
63
|
+
if (err.code === 'EJSONPARSE') {
|
|
64
|
+
err.message = `Found invalid JSON in eas.json. ${err.message}`;
|
|
65
|
+
}
|
|
66
|
+
throw err;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
60
70
|
interface MigrateContext {
|
|
61
71
|
androidProfile?: Partial<AndroidBuildProfile>;
|
|
62
72
|
iosProfile?: Partial<IosBuildProfile>;
|