shipkit / shipkit-changelog

Minimalistic Gradle plugin that generates changelog based on commit history and GitHub pull requests/issues
Apache License 2.0
68 stars 10 forks source link

"Execution optimizations have been disabled" Warning on Gradle >= 7 #103

Closed magneticflux- closed 8 months ago

magneticflux- commented 3 years ago

An example of the warnings:

Execution optimizations have been disabled for task ':jetpack-compose-optics:compileKotlin' to ensure correctness due to the following reasons:
  - Gradle detected a problem with the following location: '/home/runner/work/jetpack-compose-optics/jetpack-compose-optics/jetpack-compose-optics/build/classes/kotlin/main'. Reason: Task ':jetpack-compose-optics:generateChangelog' uses this output of task ':jetpack-compose-optics:compileKotlin' without declaring an explicit or implicit dependency. This can lead to incorrect results being produced, depending on what order the tasks are executed. Please refer to https://docs.gradle.org/7.0.2/userguide/validation_problems.html#implicit_dependency for more details about this problem.
  - Gradle detected a problem with the following location: '/home/runner/work/jetpack-compose-optics/jetpack-compose-optics/jetpack-compose-optics/build/kotlin/compileKotlin'. Reason: Task ':jetpack-compose-optics:generateChangelog' uses this output of task ':jetpack-compose-optics:compileKotlin' without declaring an explicit or implicit dependency. This can lead to incorrect results being produced, depending on what order the tasks are executed. Please refer to https://docs.gradle.org/7.0.2/userguide/validation_problems.html#implicit_dependency for more details about this problem.

And the full log: https://github.com/magneticflux-/jetpack-compose-optics/runs/2769627239#step:5:38

Maybe only the .git folder should be provided as input?

LunNova commented 2 years ago
    @Internal
    public File getWorkingDir() {
        return workingDir;
    }

    public void setWorkingDir(File workingDir) {
        this.workingDir = workingDir;
    }

    @InputDirectory
    @Optional
    public File getInputGitDirectory() {
        if (workingDir != null) {
            File dotGitDirectory = new File(workingDir, ".git");
            if (dotGitDirectory.isDirectory()) {
                return dotGitDirectory;
            }
        }

        return null;
    }

Works as a workaround which allows not changing the existing API, but I don't like it.

It's probably best if it doesn't take the root project directory as an input property at all?

In my custom changelog task I take just the relevant git refs folder:

https://github.com/MinimallyCorrect/DefaultsPlugin/blob/0f782d85c8ec7a3d9fb4f1185c14fd3aa820f9eb/src/main/java/dev/minco/gradle/changelog/ChangelogTask.java#L47-L49

    @InputDirectory
    @PathSensitive(PathSensitivity.RELATIVE)
    public abstract DirectoryProperty getGitRefs();

        ... { getGitRefs().convention(objectFactory.directoryProperty().fileValue(new File(".git/refs/"))); }
LunNova commented 2 years ago

Task.doNotTrackState in Gradle 7.3 might also be relevant.

magneticflux- commented 1 year ago

I needed to add this to my build for it to work on Gradle 8:

tasks.generateChangelog {
    // ...
    doNotTrackState("GenerateChangelogTask incorrectly depends on entire working dir, see https://github.com/shipkit/shipkit-changelog/issues/103")
    dependsOn(tasks.assemble) // Same as above
}

Otherwise, the build fails with one of two exceptions:

org.gradle.internal.execution.WorkValidationException: Some problems were found with the configuration of task ':generateChangelog' (type 'GenerateChangelogTask').
  - Gradle detected a problem with the following location: 'C:\Users\Mitchell\IdeaProjects\my-project'.

    Reason: Task ':generateChangelog' uses this output of task ':compileKotlin' without declaring an explicit or implicit dependency. This can lead to incorrect results being produced, depending on what order the tasks are executed.

    Possible solutions:
      1. Declare task ':compileKotlin' as an input of ':generateChangelog'.
      2. Declare an explicit dependency on ':compileKotlin' from ':generateChangelog' using Task#dependsOn.
      3. Declare an explicit dependency on ':compileKotlin' from ':generateChangelog' using Task#mustRunAfter.

    Please refer to https://docs.gradle.org/8.0.2/userguide/validation_problems.html#implicit_dependency for more details about this problem.
* Exception is:
org.gradle.api.tasks.TaskExecutionException: Execution failed for task ':generateChangelog'.
    at org.gradle.api.internal.tasks.execution.CatchExceptionTaskExecuter.execute(CatchExceptionTaskExecuter.java:38)
    at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.executeTask(EventFiringTaskExecuter.java:77)
    at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.call(EventFiringTaskExecuter.java:55)
    at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.call(EventFiringTaskExecuter.java:52)
    at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:204)
    at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:199)
    at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:66)
    at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:59)
    at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:157)
    at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:59)
    at org.gradle.internal.operations.DefaultBuildOperationRunner.call(DefaultBuildOperationRunner.java:53)
    at org.gradle.internal.operations.DefaultBuildOperationExecutor.call(DefaultBuildOperationExecutor.java:73)
    at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter.execute(EventFiringTaskExecuter.java:52)
    at org.gradle.execution.plan.LocalTaskNodeExecutor.execute(LocalTaskNodeExecutor.java:42)
    at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$InvokeNodeExecutorsAction.execute(DefaultTaskExecutionGraph.java:338)
    at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$InvokeNodeExecutorsAction.execute(DefaultTaskExecutionGraph.java:325)
    at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$BuildOperationAwareExecutionAction.execute(DefaultTaskExecutionGraph.java:318)
    at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$BuildOperationAwareExecutionAction.execute(DefaultTaskExecutionGraph.java:304)
    at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.execute(DefaultPlanExecutor.java:463)
    at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.run(DefaultPlanExecutor.java:380)
    at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64)
    at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:49)
Caused by: org.gradle.internal.deprecation.DocumentedFailure$DocumentedExceptionWithCause: Cannot access input property 'workingDir' of task ':generateChangelog'. Accessing unreadable inputs or outputs is not supported. Declare the task as untracked by using Task.doNotTrackState(). See https://docs.gradle.org/8.0.2/userguide/incremental_build.html#disable-state-tracking for more details.
    at org.gradle.internal.deprecation.DocumentedFailure$Builder.build(DocumentedFailure.java:70)
    at org.gradle.api.internal.tasks.execution.TaskExecution.decorateSnapshottingException(TaskExecution.java:380)
    at org.gradle.api.internal.tasks.execution.TaskExecution.visitRegularInputs(TaskExecution.java:332)
    at org.gradle.internal.execution.impl.DefaultInputFingerprinter.fingerprintInputProperties(DefaultInputFingerprinter.java:63)
    at org.gradle.internal.execution.steps.CaptureStateBeforeExecutionStep.captureExecutionStateWithOutputs(CaptureStateBeforeExecutionStep.java:123)
    at org.gradle.internal.execution.steps.CaptureStateBeforeExecutionStep.lambda$captureExecutionState$1(CaptureStateBeforeExecutionStep.java:82)
    at org.gradle.internal.execution.steps.BuildOperationStep$1.call(BuildOperationStep.java:37)
    at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:204)
    at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:199)
    at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:66)
    at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:59)
    at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:157)
    at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:59)
    at org.gradle.internal.operations.DefaultBuildOperationRunner.call(DefaultBuildOperationRunner.java:53)
    at org.gradle.internal.operations.DefaultBuildOperationExecutor.call(DefaultBuildOperationExecutor.java:73)
    at org.gradle.internal.execution.steps.BuildOperationStep.operation(BuildOperationStep.java:34)
    at org.gradle.internal.execution.steps.CaptureStateBeforeExecutionStep.captureExecutionState(CaptureStateBeforeExecutionStep.java:76)
    at org.gradle.internal.execution.steps.CaptureStateBeforeExecutionStep.lambda$execute$0(CaptureStateBeforeExecutionStep.java:70)
    at org.gradle.internal.execution.steps.CaptureStateBeforeExecutionStep.execute(CaptureStateBeforeExecutionStep.java:70)
    at org.gradle.internal.execution.steps.CaptureStateBeforeExecutionStep.execute(CaptureStateBeforeExecutionStep.java:45)
    at org.gradle.internal.execution.steps.SkipEmptyWorkStep.executeWithNonEmptySources(SkipEmptyWorkStep.java:177)
    at org.gradle.internal.execution.steps.SkipEmptyWorkStep.execute(SkipEmptyWorkStep.java:81)
    at org.gradle.internal.execution.steps.SkipEmptyWorkStep.execute(SkipEmptyWorkStep.java:53)
    at org.gradle.internal.execution.steps.RemoveUntrackedExecutionStateStep.execute(RemoveUntrackedExecutionStateStep.java:32)
    at org.gradle.internal.execution.steps.RemoveUntrackedExecutionStateStep.execute(RemoveUntrackedExecutionStateStep.java:21)
    at org.gradle.internal.execution.steps.legacy.MarkSnapshottingInputsStartedStep.execute(MarkSnapshottingInputsStartedStep.java:38)
    at org.gradle.internal.execution.steps.LoadPreviousExecutionStateStep.execute(LoadPreviousExecutionStateStep.java:36)
    at org.gradle.internal.execution.steps.LoadPreviousExecutionStateStep.execute(LoadPreviousExecutionStateStep.java:23)
    at org.gradle.internal.execution.steps.CleanupStaleOutputsStep.execute(CleanupStaleOutputsStep.java:75)
    at org.gradle.internal.execution.steps.CleanupStaleOutputsStep.execute(CleanupStaleOutputsStep.java:41)
    at org.gradle.internal.execution.steps.AssignWorkspaceStep.lambda$execute$0(AssignWorkspaceStep.java:32)
    at org.gradle.api.internal.tasks.execution.TaskExecution$4.withWorkspace(TaskExecution.java:287)
    at org.gradle.internal.execution.steps.AssignWorkspaceStep.execute(AssignWorkspaceStep.java:30)
    at org.gradle.internal.execution.steps.AssignWorkspaceStep.execute(AssignWorkspaceStep.java:21)
    at org.gradle.internal.execution.steps.IdentityCacheStep.execute(IdentityCacheStep.java:37)
    at org.gradle.internal.execution.steps.IdentityCacheStep.execute(IdentityCacheStep.java:27)
    at org.gradle.internal.execution.steps.IdentifyStep.execute(IdentifyStep.java:42)
    at org.gradle.internal.execution.steps.IdentifyStep.execute(IdentifyStep.java:31)
    at org.gradle.internal.execution.impl.DefaultExecutionEngine$1.execute(DefaultExecutionEngine.java:64)
    at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeIfValid(ExecuteActionsTaskExecuter.java:146)
    at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.execute(ExecuteActionsTaskExecuter.java:135)
    at org.gradle.api.internal.tasks.execution.FinalizePropertiesTaskExecuter.execute(FinalizePropertiesTaskExecuter.java:46)
    at org.gradle.api.internal.tasks.execution.ResolveTaskExecutionModeExecuter.execute(ResolveTaskExecutionModeExecuter.java:51)
    at org.gradle.api.internal.tasks.execution.SkipTaskWithNoActionsExecuter.execute(SkipTaskWithNoActionsExecuter.java:57)
    at org.gradle.api.internal.tasks.execution.SkipOnlyIfTaskExecuter.execute(SkipOnlyIfTaskExecuter.java:74)
    at org.gradle.api.internal.tasks.execution.CatchExceptionTaskExecuter.execute(CatchExceptionTaskExecuter.java:36)
    at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.executeTask(EventFiringTaskExecuter.java:77)
    at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.call(EventFiringTaskExecuter.java:55)
    at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.call(EventFiringTaskExecuter.java:52)
    at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:204)
    at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:199)
    at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:66)
    at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:59)
    at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:157)
    at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:59)
    at org.gradle.internal.operations.DefaultBuildOperationRunner.call(DefaultBuildOperationRunner.java:53)
    at org.gradle.internal.operations.DefaultBuildOperationExecutor.call(DefaultBuildOperationExecutor.java:73)
    at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter.execute(EventFiringTaskExecuter.java:52)
    at org.gradle.execution.plan.LocalTaskNodeExecutor.execute(LocalTaskNodeExecutor.java:42)
    at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$InvokeNodeExecutorsAction.execute(DefaultTaskExecutionGraph.java:338)
    at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$InvokeNodeExecutorsAction.execute(DefaultTaskExecutionGraph.java:325)
    at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$BuildOperationAwareExecutionAction.execute(DefaultTaskExecutionGraph.java:318)
    at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$BuildOperationAwareExecutionAction.execute(DefaultTaskExecutionGraph.java:304)
    at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.execute(DefaultPlanExecutor.java:463)
    at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.run(DefaultPlanExecutor.java:380)
    at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64)
    at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:49)
Caused by: java.io.UncheckedIOException: Failed to create MD5 hash for file content.
    at org.gradle.internal.hash.DefaultStreamHasher.hash(DefaultStreamHasher.java:37)
    at org.gradle.internal.hash.DefaultFileHasher.hash(DefaultFileHasher.java:41)
    at org.gradle.api.internal.changedetection.state.CachingFileHasher.snapshot(CachingFileHasher.java:94)
    at org.gradle.api.internal.changedetection.state.CachingFileHasher.hash(CachingFileHasher.java:76)
    at org.gradle.api.internal.changedetection.state.SplitFileHasher.hash(SplitFileHasher.java:54)
    at org.gradle.internal.snapshot.impl.DirectorySnapshotter$PathVisitor.snapshotFile(DirectorySnapshotter.java:425)
    at org.gradle.internal.snapshot.impl.DirectorySnapshotter$PathVisitor.visitResolvedFile(DirectorySnapshotter.java:393)
    at org.gradle.internal.snapshot.impl.DirectorySnapshotter$PathVisitor.doVisitFile(DirectorySnapshotter.java:353)
    at org.gradle.internal.snapshot.impl.DirectorySnapshotterStatistics$CollectingFileVisitor.visitFile(DirectorySnapshotterStatistics.java:125)
    at org.gradle.internal.snapshot.impl.DirectorySnapshotterStatistics$CollectingFileVisitor.visitFile(DirectorySnapshotterStatistics.java:106)
    at org.gradle.internal.snapshot.impl.DirectorySnapshotter.snapshot(DirectorySnapshotter.java:119)
    at org.gradle.internal.vfs.impl.DefaultFileSystemAccess.lambda$snapshot$7(DefaultFileSystemAccess.java:153)
    at org.gradle.internal.vfs.impl.AbstractVirtualFileSystem.store(AbstractVirtualFileSystem.java:84)
    at org.gradle.internal.vfs.impl.DefaultFileSystemAccess.snapshot(DefaultFileSystemAccess.java:143)
    at org.gradle.internal.vfs.impl.DefaultFileSystemAccess.lambda$readLocation$8(DefaultFileSystemAccess.java:164)
    at org.gradle.internal.vfs.impl.DefaultFileSystemAccess.lambda$readSnapshotFromLocation$9(DefaultFileSystemAccess.java:189)
    at org.gradle.internal.vfs.impl.DefaultFileSystemAccess$StripedProducerGuard.guardByKey(DefaultFileSystemAccess.java:212)
    at org.gradle.internal.vfs.impl.DefaultFileSystemAccess.lambda$readSnapshotFromLocation$10(DefaultFileSystemAccess.java:186)
    at org.gradle.internal.vfs.impl.DefaultFileSystemAccess.readSnapshotFromLocation(DefaultFileSystemAccess.java:186)
    at org.gradle.internal.vfs.impl.DefaultFileSystemAccess.readSnapshotFromLocation(DefaultFileSystemAccess.java:171)
    at org.gradle.internal.vfs.impl.DefaultFileSystemAccess.readLocation(DefaultFileSystemAccess.java:164)
    at org.gradle.internal.vfs.impl.DefaultFileSystemAccess.read(DefaultFileSystemAccess.java:80)
    at org.gradle.internal.vfs.impl.DefaultFileSystemAccess.read(DefaultFileSystemAccess.java:122)
    at org.gradle.internal.fingerprint.impl.DefaultFileCollectionSnapshotter$SnapshottingVisitor.visitFileTree(DefaultFileCollectionSnapshotter.java:76)
    at org.gradle.api.internal.file.collections.FileTreeAdapter$1.visitFileTree(FileTreeAdapter.java:112)
    at org.gradle.api.internal.file.collections.DirectoryFileTree.visitStructure(DirectoryFileTree.java:106)
    at org.gradle.api.internal.file.collections.FileTreeAdapter.visitContents(FileTreeAdapter.java:108)
    at org.gradle.api.internal.file.AbstractFileCollection.visitStructure(AbstractFileCollection.java:366)
    at org.gradle.api.internal.file.FileCollectionBackedFileTree$2.visitCollection(FileCollectionBackedFileTree.java:104)
    at org.gradle.api.internal.file.AbstractOpaqueFileCollection.visitContents(AbstractOpaqueFileCollection.java:60)
    at org.gradle.api.internal.file.AbstractFileCollection.visitStructure(AbstractFileCollection.java:366)
    at org.gradle.api.internal.file.CompositeFileCollection.lambda$visitContents$0(CompositeFileCollection.java:124)
    at org.gradle.api.internal.file.collections.UnpackingVisitor.visitSingleFile(UnpackingVisitor.java:114)
    at org.gradle.api.internal.file.collections.UnpackingVisitor.add(UnpackingVisitor.java:109)
    at org.gradle.api.internal.file.collections.UnpackingVisitor.add(UnpackingVisitor.java:92)
    at org.gradle.api.internal.file.DefaultFileCollectionFactory$ResolvingFileCollection.visitChildren(DefaultFileCollectionFactory.java:254)
    at org.gradle.api.internal.file.CompositeFileCollection.visitContents(CompositeFileCollection.java:124)
    at org.gradle.api.internal.file.AbstractFileCollection.visitStructure(AbstractFileCollection.java:366)
    at org.gradle.api.internal.file.FileCollectionBackedFileTree.visitContents(FileCollectionBackedFileTree.java:96)
    at org.gradle.api.internal.file.AbstractFileCollection.visitStructure(AbstractFileCollection.java:366)
    at org.gradle.api.internal.file.CompositeFileCollection.lambda$visitContents$0(CompositeFileCollection.java:124)
    at org.gradle.api.internal.tasks.PropertyFileCollection.visitChildren(PropertyFileCollection.java:48)
    at org.gradle.api.internal.file.CompositeFileCollection.visitContents(CompositeFileCollection.java:124)
    at org.gradle.api.internal.file.AbstractFileCollection.visitStructure(AbstractFileCollection.java:366)
    at org.gradle.internal.fingerprint.impl.DefaultFileCollectionSnapshotter.snapshot(DefaultFileCollectionSnapshotter.java:47)
    at org.gradle.internal.execution.impl.DefaultInputFingerprinter$InputCollectingVisitor.visitInputFileProperty(DefaultInputFingerprinter.java:133)
    at org.gradle.api.internal.tasks.execution.TaskExecution.visitRegularInputs(TaskExecution.java:322)
    ... 64 more
Caused by: java.io.IOException: The process cannot access the file because another process has locked a portion of the file
    at org.gradle.internal.hash.DefaultStreamHasher.doHash(DefaultStreamHasher.java:52)
    at org.gradle.internal.hash.DefaultStreamHasher.hash(DefaultStreamHasher.java:35)
    ... 110 more
TWiStErRob commented 1 year ago

Mockito master is now broken because of this too... cc @TimvdLippe

https://github.com/mockito/mockito/actions/runs/5457593285/jobs/9931914322

I'll try the workaround mentioned above to keep releasing now that the build is on Gradle 8.x.

@shipkit please merge the PR associated here.

TimvdLippe commented 1 year ago

@mockitoguy can you please take a look?

TWiStErRob commented 1 year ago

It's not enough to just depend on assemble, in a multi-module project we need to depend on everything (https://github.com/mockito/mockito/pull/3053):

// GenerateChangelogTask uses the entire repo as input, which means it needs to "depend on" all other tasks' outputs.
mustRunAfter(allprojects.collectMany { it.tasks }.grep { it.path != ":generateChangelog" && it.path != ":githubRelease" })

This also has a very sad side effect of realizing every task, luckily the mockito repo is not migrated to be lazy configured yet.

mockitoguy commented 8 months ago

Looking. Thanks everyone!