fix metaspace oom for ci

This commit is contained in:
Boof2015
2026-08-13 14:34:08 -04:00
parent be1a1b8498
commit a037be8d26
3 changed files with 125 additions and 0 deletions
+2
View File
@@ -96,6 +96,7 @@ jobs:
grep -Fq "ASTRA VENDORED KOTLIN AUDIO" android/settings.gradle
grep -Fq "ASTRA KOTLIN AUDIO SUBSTITUTION" android/build.gradle
grep -Fq "ASTRA RELEASE SIGNING" android/app/build.gradle
grep -Fq 'org.gradle.jvmargs=-Xmx2048m -XX:MaxMetaspaceSize=1024m' android/gradle.properties
grep -Fq 'android:shell="true"' android/app/src/main/AndroidManifest.xml
- name: Decode app-signing keystore
@@ -218,6 +219,7 @@ jobs:
grep -Fq "ASTRA VENDORED KOTLIN AUDIO" android/settings.gradle
grep -Fq "ASTRA KOTLIN AUDIO SUBSTITUTION" android/build.gradle
grep -Fq "ASTRA RELEASE SIGNING" android/app/build.gradle
grep -Fq 'org.gradle.jvmargs=-Xmx2048m -XX:MaxMetaspaceSize=1024m' android/gradle.properties
grep -Fq 'android:shell="true"' android/app/src/main/AndroidManifest.xml
- name: Run Astra native unit tests
+43
View File
@@ -3,6 +3,7 @@ const path = require('path');
const {
AndroidConfig,
withDangerousMod,
withGradleProperties,
withAndroidManifest,
withAppBuildGradle,
withProjectBuildGradle,
@@ -15,6 +16,8 @@ const SIGNING_MARKER = '// ASTRA RELEASE SIGNING';
const CAMERA_FEATURE = 'android.hardware.camera';
const NOTIFICATION_ICON_FILE = 'astra_notification_icon.xml';
const NOTIFICATION_OVERRIDE_FILE = 'astra_notification_icon_overrides.xml';
const GRADLE_JVM_ARGS_PROPERTY = 'org.gradle.jvmargs';
const GRADLE_JVM_ARGS_VALUE = '-Xmx2048m -XX:MaxMetaspaceSize=1024m';
// A notification small icon is an alpha mask: Android supplies the color for
// the status bar, lock screen and media controls. Keep only the main Astra mark
@@ -108,6 +111,31 @@ function appendBlock(contents, marker, block) {
return contents.includes(marker) ? contents : `${contents.trimEnd()}${block}`;
}
function upsertGradleProperty(properties, key, value) {
let propertyFound = false;
const updatedProperties = [];
for (const property of properties) {
if (property.type === 'property' && property.key === key) {
if (!propertyFound) {
updatedProperties.push({ ...property, value });
propertyFound = true;
}
continue;
}
updatedProperties.push(property);
}
if (!propertyFound) {
if (updatedProperties.length > 0 && updatedProperties.at(-1)?.type !== 'empty') {
updatedProperties.push({ type: 'empty' });
}
updatedProperties.push({ type: 'property', key, value });
}
return updatedProperties;
}
function addReleaseSigning(contents) {
if (contents.includes(SIGNING_MARKER)) return contents;
@@ -159,6 +187,17 @@ function withReleaseSigning(config) {
});
}
function withGradleBuildMemory(config) {
return withGradleProperties(config, (mod) => {
mod.modResults = upsertGradleProperty(
mod.modResults,
GRADLE_JVM_ARGS_PROPERTY,
GRADLE_JVM_ARGS_VALUE
);
return mod;
});
}
function withProfileableRelease(config) {
return withAndroidManifest(config, (mod) => {
AndroidConfig.Manifest.ensureToolsAvailable(mod.modResults);
@@ -224,6 +263,7 @@ function withAstraNotificationIcon(config) {
function withAstraAndroidRelease(config) {
config = withVendoredKotlinAudio(config);
config = withReleaseSigning(config);
config = withGradleBuildMemory(config);
config = withAstraNotificationIcon(config);
return withProfileableRelease(config);
}
@@ -233,12 +273,15 @@ module.exports._internal = {
PROJECT_BUILD_MARKER,
SETTINGS_MARKER,
SIGNING_MARKER,
GRADLE_JVM_ARGS_PROPERTY,
GRADLE_JVM_ARGS_VALUE,
NOTIFICATION_ICON_FILE,
NOTIFICATION_ICON_VECTOR,
NOTIFICATION_OVERRIDE_FILE,
NOTIFICATION_ICON_OVERRIDE,
addReleaseSigning,
appendBlock,
upsertGradleProperty,
ensureOptionalCameraFeature,
writeNotificationIconResources,
};
+80
View File
@@ -53,6 +53,86 @@ test('appendBlock adds a native block exactly once', () => {
assert.equal(once.split(_internal.SETTINGS_MARKER).length - 1, 1);
});
test('raises the generated Gradle Metaspace cap while preserving unrelated properties', () => {
const properties = [
{ type: 'comment', value: 'Project-wide Gradle settings.' },
{
type: 'property',
key: _internal.GRADLE_JVM_ARGS_PROPERTY,
value: '-Xmx2048m -XX:MaxMetaspaceSize=512m',
},
{ type: 'property', key: 'org.gradle.parallel', value: 'true' },
];
assert.deepEqual(
_internal.upsertGradleProperty(
properties,
_internal.GRADLE_JVM_ARGS_PROPERTY,
_internal.GRADLE_JVM_ARGS_VALUE
),
[
properties[0],
{
type: 'property',
key: _internal.GRADLE_JVM_ARGS_PROPERTY,
value: '-Xmx2048m -XX:MaxMetaspaceSize=1024m',
},
properties[2],
]
);
});
test('adds the Gradle JVM arguments when the generated property is absent', () => {
const transformed = _internal.upsertGradleProperty(
[{ type: 'property', key: 'org.gradle.parallel', value: 'true' }],
_internal.GRADLE_JVM_ARGS_PROPERTY,
_internal.GRADLE_JVM_ARGS_VALUE
);
assert.deepEqual(transformed.slice(-2), [
{ type: 'empty' },
{
type: 'property',
key: _internal.GRADLE_JVM_ARGS_PROPERTY,
value: _internal.GRADLE_JVM_ARGS_VALUE,
},
]);
});
test('Gradle JVM argument transform is idempotent and removes duplicate properties', () => {
const properties = [
{
type: 'property',
key: _internal.GRADLE_JVM_ARGS_PROPERTY,
value: '-Xmx2048m -XX:MaxMetaspaceSize=512m',
},
{
type: 'property',
key: _internal.GRADLE_JVM_ARGS_PROPERTY,
value: '-Xmx1024m -XX:MaxMetaspaceSize=256m',
},
];
const once = _internal.upsertGradleProperty(
properties,
_internal.GRADLE_JVM_ARGS_PROPERTY,
_internal.GRADLE_JVM_ARGS_VALUE
);
const twice = _internal.upsertGradleProperty(
once,
_internal.GRADLE_JVM_ARGS_PROPERTY,
_internal.GRADLE_JVM_ARGS_VALUE
);
assert.deepEqual(twice, once);
assert.equal(
once.filter(
(property) =>
property.type === 'property' && property.key === _internal.GRADLE_JVM_ARGS_PROPERTY
).length,
1
);
});
test('marks QR scanning camera hardware as optional without duplicating it', () => {
const manifest = { manifest: {} };