Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions packages/build-tools/src/builders/__tests__/android.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ import {
injectConfigureVersionGradleConfig,
injectCredentialsGradleConfig,
} from '../../steps/utils/android/gradleConfig';
import {
logGradleCacheEnv,
restoreGradleCacheAsync,
} from '../../steps/functions/restoreBuildCache';

jest.mock('../common', () => ({
runBuilderWithHooksAsync: jest.fn(async (ctx, buildFn) => {
Expand Down Expand Up @@ -41,10 +45,13 @@ jest.mock('../../common/setup', () => ({
}));
jest.mock('../../steps/functions/restoreBuildCache', () => ({
cacheStatsAsync: jest.fn(),
logGradleCacheEnv: jest.fn(),
restoreCcacheAsync: jest.fn(),
restoreGradleCacheAsync: jest.fn(async () => ({ env: {} })),
}));
jest.mock('../../steps/functions/saveBuildCache', () => ({
saveCcacheAsync: jest.fn(),
saveGradleCacheAsync: jest.fn(),
}));
jest.mock('../../steps/utils/android/gradleConfig', () => ({
...jest.requireActual('../../steps/utils/android/gradleConfig'),
Expand Down Expand Up @@ -145,6 +152,30 @@ describe(androidBuilder, () => {
expect(injectConfigureVersionGradleConfig).not.toHaveBeenCalled();
});

it('logs Gradle cache environment variables returned by restoreGradleCacheAsync', async () => {
jest.mocked(restoreGradleCacheAsync).mockResolvedValueOnce({
env: {
'ORG_GRADLE_PROJECT_org.gradle.caching': 'true',
},
});
const ctx = new BuildContext(createTestAndroidJob(), {
workingdir: '/workingdir',
logBuffer: { getLogs: () => [], getPhaseLogs: () => [] },
logger: createMockLogger(),
env: {
EAS_BUILD_RUNNER: 'eas-build',
__API_SERVER_URL: 'http://api.expo.test',
},
uploadArtifact: jest.fn(),
});

await androidBuilder(ctx);

expect(logGradleCacheEnv).toHaveBeenCalledWith(expect.anything(), {
'ORG_GRADLE_PROJECT_org.gradle.caching': 'true',
});
});

it('marks the configure Android version phase as warning for legacy eas-build.gradle', async () => {
const job: Android.Job = {
...createTestAndroidJob(),
Expand Down
7 changes: 6 additions & 1 deletion packages/build-tools/src/builders/android.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import { setupAsync } from '../common/setup';
import { Artifacts, BuildContext, SkipNativeBuildError } from '../context';
import {
cacheStatsAsync,
logGradleCacheEnv,
restoreCcacheAsync,
restoreGradleCacheAsync,
} from '../steps/functions/restoreBuildCache';
Expand Down Expand Up @@ -88,12 +89,16 @@ async function buildAsync(ctx: BuildContext<Android.Job>): Promise<void> {
env: ctx.env,
secrets: ctx.job.secrets,
});
await restoreGradleCacheAsync({
const { env } = await restoreGradleCacheAsync({
logger: ctx.logger,
workingDirectory,
env: ctx.env,
secrets: ctx.job.secrets,
});
if (Object.keys(env).length > 0) {
Object.assign(ctx.env, env);
logGradleCacheEnv(ctx.logger, env);
}
});

await ctx.runBuildPhase(BuildPhase.POST_INSTALL_HOOK, async () => {
Expand Down
36 changes: 26 additions & 10 deletions packages/build-tools/src/steps/functions/restoreBuildCache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,12 +57,19 @@ export function createRestoreBuildCacheFunction(): BuildFunction {
});

if (platform === Platform.ANDROID) {
await restoreGradleCacheAsync({
const { env: gradleCacheEnv } = await restoreGradleCacheAsync({
logger,
workingDirectory,
env,
secrets: stepCtx.global.staticContext.job.secrets,
});
if (Object.keys(gradleCacheEnv).length > 0) {
stepCtx.global.updateEnv({
...stepCtx.global.env,
...gradleCacheEnv,
});
logGradleCacheEnv(logger, gradleCacheEnv);
}
}
},
});
Expand Down Expand Up @@ -200,19 +207,16 @@ export async function restoreGradleCacheAsync({
workingDirectory: string;
env: Record<string, string | undefined>;
secrets?: { robotAccessToken?: string };
}): Promise<void> {
}): Promise<{ env: Record<string, string> }> {
if (env.EAS_GRADLE_CACHE !== '1') {
return;
return { env: {} };
}

try {
const gradlePropertiesPath = path.join(workingDirectory, 'android', 'gradle.properties');
const gradlePropertiesContent = await fs.promises.readFile(gradlePropertiesPath, 'utf-8');
await fs.promises.writeFile(
gradlePropertiesPath,
`${gradlePropertiesContent}\n\norg.gradle.caching=true\n`
);
const gradleCacheEnv = {
'ORG_GRADLE_PROJECT_org.gradle.caching': 'true',

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not entirely certain this will truly enable the property still. ref gradle/gradle#18087

I will validate your branch locally to see

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I ran this locally and validated it does not enable gradle caching. In restore

Restoring Gradle cache key: android-gradle-cache-f0ece61fb139c94a5b03cfd08ced7227a2d238dc293484d692233893e90d8752
Matched cache key: android-gradle-cache-f0ece61fb139c94a5b03cfd08ced7227a2d238dc293484d692233893e90d8752. Downloading...
Gradle cache restored to /Users/mustafa/.gradle/caches (direct hit)
Enabling Gradle cache. Running Gradle with additional environment variables.
ORG_GRADLE_PROJECT_org.gradle.caching=true

in run gradle

[EAS] Gradle build cache entries before cleanup: 464
[EAS] Configured Gradle cache cleanup via init script
...

[EAS] Gradle build cache entries after build: 464 (was 464)

what I expected to see and what I saw with current setup

[EAS] Gradle build cache entries after build: 476 (was 464)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah but we can modify ~/.gradle/gradle.properties and leave the project untouched

};

try {
// Configure cache cleanup via init script (works with both Gradle 8 and 9,
// org.gradle.cache.cleanup property was removed in Gradle 9)
const initScriptDir = path.join(os.homedir(), '.gradle', 'init.d');
Expand Down Expand Up @@ -294,6 +298,18 @@ export async function restoreGradleCacheAsync({
logger.warn('Failed to restore Gradle cache: ', err);
}
}

return { env: gradleCacheEnv };
}

export function logGradleCacheEnv(logger: bunyan, env: Record<string, string>): void {
logger.info(
`Enabling Gradle cache. Running Gradle with additional environment variables.\n${Object.entries(
env
)
.map(([key, value]) => `${key}=${value}`)
.join('\n')}`
);
}

export async function cacheStatsAsync({
Expand Down
Loading