Skip to content

Commit

Permalink
Merge pull request #302 from gradle/fix-config-cache
Browse files Browse the repository at this point in the history
Fix save/restore of configuration-cache
  • Loading branch information
bigdaz committed Jun 4, 2022
2 parents 8aaf080 + 4da2997 commit 8b56c4a
Show file tree
Hide file tree
Showing 9 changed files with 70 additions and 19 deletions.
2 changes: 1 addition & 1 deletion README.md
Expand Up @@ -195,7 +195,7 @@ By default, this action aims to cache any and all reusable state that may be spe
The state that is cached includes:
- Any distributions downloaded to satisfy a `gradle-version` parameter ;
- A subset of the Gradle User Home directory, including downloaded dependencies, wrapper distributions, and the local build cache ;
- Any [configuration-cache](https://docs.gradle.org/nightly/userguide/configuration_cache.html) data stored in the project `.gradle` directory.
- Any [configuration-cache](https://docs.gradle.org/nightly/userguide/configuration_cache.html) data stored in the project `.gradle` directory. (Only supported for Gradle 7 or higher.)

To reduce the space required for caching, this action makes a best effort to reduce duplication in cache entries.

Expand Down
6 changes: 5 additions & 1 deletion dist/main/index.js
Expand Up @@ -64965,7 +64965,11 @@ class GradleStateCache {
initializeGradleUserHome(gradleUserHome, initScriptsDir) {
const propertiesFile = path_1.default.resolve(gradleUserHome, 'gradle.properties');
fs_1.default.appendFileSync(propertiesFile, 'org.gradle.daemon=false');
const initScriptFilenames = ['build-result-capture.init.gradle', 'project-root-capture.init.gradle'];
const initScriptFilenames = [
'build-result-capture.init.gradle',
'project-root-capture.init.gradle',
'project-root-capture.plugin.groovy'
];
for (const initScriptFilename of initScriptFilenames) {
const initScriptContent = this.readResourceAsString(initScriptFilename);
const initScriptPath = path_1.default.resolve(initScriptsDir, initScriptFilename);
Expand Down
2 changes: 1 addition & 1 deletion dist/main/index.js.map

Large diffs are not rendered by default.

6 changes: 5 additions & 1 deletion dist/post/index.js
Expand Up @@ -64016,7 +64016,11 @@ class GradleStateCache {
initializeGradleUserHome(gradleUserHome, initScriptsDir) {
const propertiesFile = path_1.default.resolve(gradleUserHome, 'gradle.properties');
fs_1.default.appendFileSync(propertiesFile, 'org.gradle.daemon=false');
const initScriptFilenames = ['build-result-capture.init.gradle', 'project-root-capture.init.gradle'];
const initScriptFilenames = [
'build-result-capture.init.gradle',
'project-root-capture.init.gradle',
'project-root-capture.plugin.groovy'
];
for (const initScriptFilename of initScriptFilenames) {
const initScriptContent = this.readResourceAsString(initScriptFilename);
const initScriptPath = path_1.default.resolve(initScriptsDir, initScriptFilename);
Expand Down
2 changes: 1 addition & 1 deletion dist/post/index.js.map

Large diffs are not rendered by default.

8 changes: 6 additions & 2 deletions src/cache-base.ts
Expand Up @@ -170,7 +170,11 @@ export class GradleStateCache {
const propertiesFile = path.resolve(gradleUserHome, 'gradle.properties')
fs.appendFileSync(propertiesFile, 'org.gradle.daemon=false')

const initScriptFilenames = ['build-result-capture.init.gradle', 'project-root-capture.init.gradle']
const initScriptFilenames = [
'build-result-capture.init.gradle',
'project-root-capture.init.gradle',
'project-root-capture.plugin.groovy'
]
for (const initScriptFilename of initScriptFilenames) {
const initScriptContent = this.readResourceAsString(initScriptFilename)
const initScriptPath = path.resolve(initScriptsDir, initScriptFilename)
Expand All @@ -179,7 +183,7 @@ export class GradleStateCache {
}

private readResourceAsString(resource: string): string {
// Resolving relative to __dirname will force the compiler to inline the content in the distribution
// Resolving relative to __dirname will allow node to find the resource at runtime
const absolutePath = path.resolve(__dirname, '..', '..', 'src', 'resources', resource)
return fs.readFileSync(absolutePath, 'utf8')
}
Expand Down
5 changes: 3 additions & 2 deletions src/resources/build-result-capture.init.gradle
Expand Up @@ -27,7 +27,10 @@ if (isTopLevelBuild) {

def registerCallbacks(buildScanExtension, rootProjectName) {
buildScanExtension.with {
def requestedTasks = gradle.startParameter.taskNames.join(" ")
def gradleVersion = GradleVersion.current().version
def buildFailed = false

buildFinished { result ->
buildFailed = (result.failure != null)
}
Expand All @@ -38,8 +41,6 @@ def registerCallbacks(buildScanExtension, rootProjectName) {

def buildResultsFile = new File(buildResultsDir, System.getenv("GITHUB_ACTION") + System.currentTimeMillis() + ".json")

def requestedTasks = gradle.startParameter.taskNames.join(" ")
def gradleVersion = GradleVersion.current().version
def buildScanUri = buildScan.buildScanUri.toASCIIString()
def buildResults = [
rootProject: rootProjectName,
Expand Down
18 changes: 8 additions & 10 deletions src/resources/project-root-capture.init.gradle
@@ -1,12 +1,10 @@
// Capture the build root directory for each executed Gradle build.
import org.gradle.util.GradleVersion

// Only run against root build. Do not run against included builds.
def isTopLevelBuild = gradle.getParent() == null
if (isTopLevelBuild) {
settingsEvaluated { settings ->
def projectRootEntry = settings.rootDir.absolutePath + '\n'
def projectRootList = new File(settings.gradle.gradleUserHomeDir, "project-roots.txt")
if (!projectRootList.exists() || !projectRootList.text.contains(projectRootEntry)) {
projectRootList << projectRootEntry
}
}
}
// Only record configuration-cache entries for Gradle 7+
def isAtLeastGradle7 = GradleVersion.current() >= GradleVersion.version('7.0')

if (isTopLevelBuild && isAtLeastGradle7) {
apply from: 'project-root-capture.plugin.groovy'
}
40 changes: 40 additions & 0 deletions src/resources/project-root-capture.plugin.groovy
@@ -0,0 +1,40 @@

/*
* Capture the build root directory for each executed Gradle build.
* This is used to save/restore configuration-cache files, so:
* - The implementation only makes sense if it's config-cache compatible
* - We only need to support Gradle 7+
*/

import org.gradle.tooling.events.*

settingsEvaluated { settings ->
def rootDir = settings.rootDir.absolutePath
def rootListLocation = new File(settings.gradle.gradleUserHomeDir, "project-roots.txt").absolutePath

def projectTracker = gradle.sharedServices.registerIfAbsent("gradle-build-action-projectRootTracker", ProjectTracker, { spec ->
spec.getParameters().getRootDir().set(rootDir);
spec.getParameters().getRootListLocation().set(rootListLocation);
})

gradle.services.get(BuildEventsListenerRegistry).onTaskCompletion(projectTracker)
}

abstract class ProjectTracker implements BuildService<ProjectTracker.Params>, OperationCompletionListener, AutoCloseable {
interface Params extends BuildServiceParameters {
Property<String> getRootDir();
Property<String> getRootListLocation();
}

public void onFinish(FinishEvent finishEvent) {}

@Override
public void close() {
def rootDir = getParameters().getRootDir().get()
def rootDirEntry = rootDir + '\n'
def rootListFile = new File(getParameters().getRootListLocation().get())
if (!rootListFile.exists() || !rootListFile.text.contains(rootDirEntry)) {
rootListFile << rootDirEntry
}
}
}

0 comments on commit 8b56c4a

Please sign in to comment.