c4193e27db
移动壳新增 EAS Android 和 iOS 构建 profile 移动壳增加原生包构建配置 smoke 门禁 原生壳总验收接入移动 EAS 配置检查 宿主壳文档同步移动原生包构建口径
105 lines
3.5 KiB
JavaScript
105 lines
3.5 KiB
JavaScript
import fs from 'node:fs';
|
|
|
|
const shellRoot = new URL('../', import.meta.url);
|
|
const easConfigPath = new URL('eas.json', shellRoot);
|
|
const packagePath = new URL('package.json', shellRoot);
|
|
|
|
const easConfig = JSON.parse(fs.readFileSync(easConfigPath, 'utf8'));
|
|
const packageConfig = JSON.parse(fs.readFileSync(packagePath, 'utf8'));
|
|
|
|
function assertObject(value, label) {
|
|
if (!value || typeof value !== 'object' || Array.isArray(value)) {
|
|
throw new Error(`${label} must be an object`);
|
|
}
|
|
}
|
|
|
|
function assertNoKeys(value, blockedKeys, label) {
|
|
for (const key of blockedKeys) {
|
|
if (key in value) {
|
|
throw new Error(`${label} must not configure ${key}`);
|
|
}
|
|
}
|
|
}
|
|
|
|
assertObject(easConfig.cli, 'EAS cli config');
|
|
assertObject(easConfig.build, 'EAS build config');
|
|
|
|
if (easConfig.cli.version !== '>= 20.3.0') {
|
|
throw new Error('mobile shell EAS CLI version gate must stay pinned to the checked devDependency floor');
|
|
}
|
|
|
|
if (easConfig.cli.appVersionSource !== 'local') {
|
|
throw new Error('mobile shell EAS builds must use local app.json version fields');
|
|
}
|
|
|
|
for (const scriptName of ['build:android', 'build:ios', 'build-config:smoke']) {
|
|
if (typeof packageConfig.scripts?.[scriptName] !== 'string') {
|
|
throw new Error(`mobile shell package missing ${scriptName} script`);
|
|
}
|
|
}
|
|
|
|
if (
|
|
packageConfig.scripts['build:android'] !==
|
|
'eas build --local --profile production --platform android'
|
|
) {
|
|
throw new Error('mobile shell Android package build script drifted');
|
|
}
|
|
|
|
if (
|
|
packageConfig.scripts['build:ios'] !==
|
|
'eas build --local --profile production-simulator --platform ios'
|
|
) {
|
|
throw new Error('mobile shell iOS package build script drifted');
|
|
}
|
|
|
|
if (packageConfig.scripts['build-config:smoke'] !== 'node scripts/check-eas-build-config.mjs') {
|
|
throw new Error('mobile shell EAS config smoke script drifted');
|
|
}
|
|
|
|
const production = easConfig.build.production;
|
|
const productionSimulator = easConfig.build['production-simulator'];
|
|
assertObject(production, 'EAS Android production profile');
|
|
assertObject(productionSimulator, 'EAS iOS simulator production profile');
|
|
|
|
if (production.distribution !== 'internal' || production.channel !== 'production') {
|
|
throw new Error('mobile shell Android production profile must build an internal production package');
|
|
}
|
|
|
|
if (production.android?.buildType !== 'apk') {
|
|
throw new Error('mobile shell Android production profile must produce an installable APK');
|
|
}
|
|
|
|
if (production.env?.EXPO_NO_DOTENV !== '1') {
|
|
throw new Error('mobile shell Android production profile must ignore local dotenv files');
|
|
}
|
|
|
|
if (
|
|
productionSimulator.distribution !== 'internal' ||
|
|
productionSimulator.channel !== 'production'
|
|
) {
|
|
throw new Error('mobile shell iOS simulator production profile must stay internal production');
|
|
}
|
|
|
|
if (productionSimulator.ios?.simulator !== true) {
|
|
throw new Error('mobile shell iOS production smoke profile must target simulator builds until signing is configured');
|
|
}
|
|
|
|
if (productionSimulator.env?.EXPO_NO_DOTENV !== '1') {
|
|
throw new Error('mobile shell iOS simulator production profile must ignore local dotenv files');
|
|
}
|
|
|
|
for (const [profileName, profile] of Object.entries(easConfig.build)) {
|
|
assertObject(profile, `EAS ${profileName} profile`);
|
|
assertNoKeys(
|
|
profile,
|
|
['credentialsSource', 'autoIncrement', 'submit', 'releaseChannel'],
|
|
`EAS ${profileName} profile`,
|
|
);
|
|
}
|
|
|
|
if ('submit' in easConfig) {
|
|
throw new Error('mobile shell EAS config must not include store submit profiles yet');
|
|
}
|
|
|
|
console.log('[mobile-shell:eas-build-config] OK');
|