The article will be updated when anything valuable is discovered.

How to deploy directory tree flat

Here is the catch: Copy, Sync, Zip etc preserve directory structure when doing their job. If you needed to copy files from subdirectories into a single directory, you would need to specify collection of files manually modify file paths via eachFile:

task deploy(type: Sync) {
    from 'src'
    into 'dst'
    eachFile { desc ->
        desc.path = desc.path.replaceAll('regex', 'subst')
    }
}

// This may be suitable for static files, but not for generated ones.
// Because fileTree() is evaluated before the task
task deploy_flat(type: Sync) {
    from(fileTree(dir: 'src').files)
    into 'dst_flat'
}