How can I set the archiveName so that it can be changed by another task?

I want to do something like:

task myZip(type: Zip) {
    from 'somedir'
    archiveName = "$modowner~$modname~$version.zip"
}

But it seems the archiveName gets evaluated at the start of the script, so when the $version is changed by our release plugin, the change is not picked up, and the archive is created with the wrong name.

That’s correct. The archiveName is set during the configuration phase. You can still change the value of the property though. Here’s an example that emulates a release task:

task myZip(type: Zip) {
    from 'somedir'
    archiveName = "$modowner~$modname~${project.version}.zip"
}
  task release {
      finalizedBy myZip
        doLast {
       project.version = '4.0'
        myZip.archiveName = "$modowner~$modname~${project.version}.zip"
   }
}