Gradle Copy task stopped working at some point with NO-SOURCE

Hey,

We have a gradle task since ages in our build.gradle of a sub-project, which should copy some ZIP file into a different folder and rename it. It worked up until some point and stopped working without ever being touched, and I struggle to find out why. It seems like a gradle problem, but I want to make sure I’m not just dumb :slight_smile:

I modified the original copy task to add some debug information and it looks like this currently:

task release(type: Copy) {
    from("${webappDir}/cypress/fixtures/instance-export.zip") {
        rename { version + ".zip" }
    }
    into new File(project(':test-data').projectDir, "bin-test-data")

    println "-------------------------------"
    release.source.each { println it; println it.exists() }
    println release.destinationDir
    println "-------------------------------"

    doLast {
        println "Release seems to do well with UI tests"
    }
}

The output I get when I run this is:

...
> Configure project :ui
...
-------------------------------
E:\other\workspaces\deployment\deployment\ui\webapp\cypress\fixtures\instance-export.zip
true
E:\other\workspaces\deployment\deployment\test-data\bin-test-data
-------------------------------
...
> Task :ui:release NO-SOURCE
Skipping task ':ui:release' as it has no source files and no previous output files.
...

I manually made sure that both input file and output directory exist, also as you can see also the gradle task makes sure that input exists, yet i get “NO-SOURCE” and i’m 100% puzzled about this.

This is with latest gradle as of the time of testing:

------------------------------------------------------------
Gradle 7.4
------------------------------------------------------------

Build time:   2022-02-08 09:58:38 UTC
Revision:     f0d9291c04b90b59445041eaa75b2ee744162586

Kotlin:       1.5.31
Groovy:       3.0.9
Ant:          Apache Ant(TM) version 1.10.11 compiled on July 10 2021
JVM:          17-beta (Eclipse Adoptium 17-beta+35-202109150246)
OS:           Windows 10 10.0 amd64

Any hints/help are greatly appreciated!

I also tried eliminating possible causes by removing all depensOn, removing the ‘rename’ clause, etc.

I have found a solution by doing this:

task release() {
    doLast {
        copy {
            from("${webappDir}/cypress/fixtures/instance-export.zip") {
                rename { version + ".zip" }
            }
            into new File(project(':test-data').projectDir, "bin-test-data")
        }

        println "Release seems to do well with UI tests"
    }
}

…which does make sense if either in- or output does not exist at configuration time (thus shift configuration of the copy-thingy to execution time of the task, OK). Which actually can be the case, so I’ll leave it like that.

However: in my naive test scenario described above, all input and output do exist prior to executing gradle, and I would really want to understand why this does not work as expected.

Hi Markus,

that is very strange. Did this start happening with Gradle 7.4 or does it also fail with Gradle 7.3?

Cheers,
Stefan

Hey,

Not that easy to check, but judging from our GIT history, I’m 90% sure that it stopped working when we went from 7.3.3 to 7.4… We have files from few days earlier, but not a single one from afterwards.

Thanks for looking into it :slight_smile:

If you want to check some code: Releases · bdeployteam/bdeploy · GitHub - it is no longer working for all the 4.1.x releases, so it worked up to (including) 4.0.5 - 4.1.0 was the release where we switched to gradle 7.4…

I tried this out with a very simple build.gradle and a manually created file:

version = "1.5"

task release(type: Copy) {
    from("webapp/cypress/fixtures/instance-export.zip") {
        rename { version + ".zip" }
    }
    into new File("build", "bin-test-data")

    println "-------------------------------"
    release.source.each { println it; println it.exists() }
    println release.destinationDir
    println "-------------------------------"

    doLast {
        println "Release seems to do well with UI tests"
    }
}

That doesn’t expose the NO-SOURCE behaviour: Build Scan™ | Gradle Enterprise

Hi again,

I also tried your project. I don’t know how the file ui/webapp/cypress/fixtures/instance-export.zip is supposed to be created, though it didn’t exist for me. I created it manually and then ran:

gradle ui:release -x :ui:runCypressHeadless

The release task then did actually run and showed that the source is there. Do you have maybe another task which is supposed to create instance-export.zip?
See Build Scan™ | Gradle Enterprise

Another option is that the task did run before even though the file was not there in Gradle 7.3. With Gradle 7.4 it now detects correctly that if the file isn’t there the task doesn’t have any sources.

Cheers,
Stefan

Well that is strange (that it does not happen) - maybe this is also related to the OS (Windows)? The instance-export.zip is indeed created as a side-effect of runCypressHeadless - during UI Tests. It is not declared in the gradle files anywhere. That is why I said the “workaround” is actually a fitting solution as the file may be not there in the configure phase. However I still don’t get why this happened in the first place, and really would like to understand to avoid. Here a scan of when it happened: Build Scan™ | Gradle Cloud Services

I also tried to init a dummy gradle project and put that minimal code in there and it does not happen - I used the exact gradle version where it does… This is quite strange.

Hi Markus,

So I think the problem is that Gradle doesn’t know that the runCypressHeadless creates the output file. So Gradle would assume that the source tree doesn’t change and that there won’t be a new file. Can you declare the output file in runCypressHeadless? That should fix the issue.

Cheers,
Stefan

But it should work if the ZIP is a static file just lying there, right? That is the situation that puzzles me. Sure - declaring the output would also make it work without doLast if I understand that correctly. However if we just pretend that the ZIP file always exists (as it did in my tests!), then the original should work, right?

Hi Markus,

yes, it should work if the zip just is a static file which is there. I tried that and I couldn’t reproduce the problem. Can you check if the problem goes away when you use a new daemon and the zip exists already?

Cheers,
Stefan

I am unable to reproduce the issue. I have no idea why, since the issue happened on every build on multiple machines for a while, but now: nope. Even the original code behaves exactly as expected. Well. Lets just let it be as mysterious phenomenon xD Thanks for all the help!