The Zip task is a specialization of a Copy task. The archive will only contain the items copied using the CopySpec configuration on the task (i.e. from, into, etc). The doFirst doesn’t interact with the task configuration at all. You basically need to create the empty folder somewhere (like a temp folder) in order to copy it into the archive. For example, adding the following should create userdir/userdir in the temporary directory for the task and then include the contents of that temporary directory in the archive:
from({ new File(temporaryDir, 'userdir/userdir').mkdirs(); temporaryDir })