I mentioned in my previous post that I changed your code from an "execution
closure" to a "configuration closure". That is what the "<<" does. With <<
the closure is an action closure, without it's a configuration closure.
What does this mean? Well, configuration closures are executed during the
configuration phase for all tasks, even those that will not execute. Their
purpose is to set up tasks that have predefined action logic (such as the
Upload type task). Execution closures are run if and only if the task needs
to execute (based on several things, including the command line options
specifying the tasks to run). To understand, try this:
task A {
println 'configuring A'
}
task B << {
println 'executing B'
}
Now run
gradle A
and the output should be 'configuring A'. The "execution closure" for B was
not run because B was not executed. Then run
gradle B
and the output should be 'configuring A' and then 'executing B'. The
configuration closure for A was run even though A was not executed.
Finally, to fully understand the error you are seeing, you need one more
piece of information. The "<<" is just shorthand for doLast. So, task B
above could equivalently be written
task B.doLast {
println 'executing B'
}
There is also a doFirst method, FYI. So, what's happening to you is when
you write "task uploadReleases(...) << { ... }" you are adding a new action
AFTER the built in action for task type Upload. So, when the task executes,
your closure has not run when the Upload task goes to use it's
configuration. You could fix this by writing "task
uploadReleases(...).doFirst { ... }", because that would cause your closure
to be run BEFORE the built in action, and then the configuration parameter
would get set. This kind of thing is sometimes necessary, but where
possible it is better form to use a configuration closure to configure the
task.
As to why uploadArchives doesn't need the configuration to be set, this is
part of what the Java plugin does for you. I don't remember for sure, but I
think it just finds all configurations and makes an upload<config name> task
for each one, associating the task with the configuration automatically.
The archives configuration is a default configuration to which the result of
all "Jar" and "Zip" and "Tar" type tasks are automatically added. Those two
automatic actions are fairly mundane, but the combination result is a bit
"magical."
I hope this helps to put the pieces together. As for the user guide, we
have discussed the need for an improved "beginners guide" before, but it's
one thing to say it's needed, and another altogether to write it. Hopefully
we (the Gradle community) will make some progress on that eventually.
--
John Murph
Automated Logic Research Team