Declaring an explicit or implicit dependency

Gradle 8
We have a custom task that copies an uber-jar and puts it in libs directory

tasks.register('override', Copy) {
    outputs.upToDateWhen { false }
    from "${project.layout.buildDirectory.get().asFile}/$project.name-$version-runner.jar"
    into "${project.layout.buildDirectory.get().asFile}/libs/"
    rename { String fileName ->
        fileName.replace("-runner", '')
    }
    doLast {
        println "Finished copy jar at: " + getDate()
    }
}

We are using a release task from researchgate.release plugin to build the project and manage versions.
In the release task we specify afterReleaseBuild.dependsOn override so the ‘override’ would be called after the build is over.
However we are getting errors about a few tasks (distZip, distTar, startScripts) that the task uses this output of task ‘override’ without declaring an explicit or implicit dependency. And build fails. These tasks are not called explicitly, they are called by the plugin.
How this could be fixed (except declaring for each of the tasks that it is depend on ‘override’)
Thank you.

The problem is, that you define tasks with overlapping outputs.
The output of your Copy task is the whole libs directory.
Also other tasks write into this directory, so you have overlapping outputs which is a bad idea.
Instead do not use a Copy task but use a copy { ... } closure in doFirst { ... } or doLast { ... } and declare the one input file as input file and the one output file as output file.

Thank you so much for your swift reply and explanation!
Could you please provide a link to documentation or an example how to configure the copy closure using input and output files.

The closure you configure exactly like the task regarding from / into / …
The inputs and outputs are on the task like for each and every task.
Just with inputs.file(...) and outputs.file(...).

Thank you, but still can’t figure it out
Trying something like

    outputs.dir( "${project.layout.buildDirectory.get().asFile}/libs")
    inputs.file( "${project.layout.buildDirectory.get().asFile}/$project.name-$version-runner.jar" )
    doFirst {
        copy {
            from ??
            into ??
            rename { String fileName ->
                fileName.replace("-runner", '')
            }
        }
    }

But what do i use for ‘from’ and ‘into’

If you use outputs.dir, you end up with the same problem you have now. That’s why I said outputs.file.
And As I said, you use the same for from and into that you used for the task before.

Besides that even with the Copy task using a hard-coded path as from is a very bad idea, as you then for example miss the necessary task dependency. Better use from(theTaskThatGeneratesTheJar) as well as for the inputs.file(...).

Thank you for the tip! Seems that now its exactly what going on wrong as now i am getting an error

‘:override’ uses this output of task ‘:quarkusBuild’ without declaring an explicit or implicit dependency.

Quarkus build is called by a release task (we are using a researchgate.release plugin for it, its not a custom task)
I tried in copy closure to do
from(quarkusBuild)
but it didn’t work. the build still fails.

I have no idea about Quarkus.
Are you sure the quarkusBuild task is the one actually generating the jar?
And did you also use it for the inputs.file(...) as I said?

I made copy work (not with using task as input though).
Thank you for your fast and very useful replies!