How to uniquely upload a release artifact on a repository

Hello Gradle people,

Once a “release” artifact has been uploaded to a repository on a given version, it should not be possible to upload it again to avoid damaging the traceability. Is there a way to do that using the MavenDeployer ?

My impression is that this is generally (with Maven as well, not just with Gradle) handled via settings on the repository.

For Nexus, you’d set the deployment policy to “disable redeploy”. Reference: [Nexus FAQ](https://docs.sonatype.com/display/SPRTNXOSS/Nexus+FAQ#NexusFAQ-Q.HowdoIdisableartifactredeployment.

For Artifactory, you’d disable the Delete permission. Reference: Managing Permissions on JFrog Wiki; see “Preventing Overwriting Deployments” topic

I see, thanks !

David’s solution is by far the best and safest approach.

If you want to just have Gradle skip trying to publish if it’s already been uploaded (in addition), you can do something like…

uploadArchives {
  onlyIf {
    try {
       new URL("http://myrepo.com/${calculatedPathToWhereItWouldBePublished}").bytes
      false
    } catch (FileNotFoundException e) {
      true
    }
  }
}

That’s rather unsophisticated, but hopefully gives anyone interested the start of an idea.

Hi Luke,

Yes I was thinking of that kind of solution too, that’s why I posted the question on the Gradle forum. I was able to do it with Artifactory using two profiles, one for “snapshot” with “delete” rights, and one for “release” with only “deploy” rights. However, the error message is not really easy to understand for users, see traces below.

For SNAPSHOT I am using a dedicated user named “snapshot”, same for release:

uploadArchives.doFirst() {
  logger.lifecycle path + " Project Version: " + project.version
  repositories.mavenDeployer {
   name = 'artifactory'
   def repositoryRootUpload = 'http://vvv.zzz.yyy.xxx:8081/artifactory/'
            if (version.endsWith('SNAPSHOT')) {
                repository(url: repositoryRootUpload + 'libs-snapshot-local') {
                    authentication(userName: "snapshot", password: "vvv.zzz.yyy.xxx")
                }
            } else {
                repository(url: repositoryRootUpload + 'libs-release-local') {
                    authentication(userName: "release", password: "vvv.zzz.yyy.xxx")
                }
            }
  }
 }

As in your solution, the error message could be dedicated like: “A release artifact already exists for that version”.

If I have complains from my users, I will use your proposition.

Thanks,

Jean-Pierre

[13:47:24][Step 1/3] :asn-nem-client:uploadArchives
[13:47:24][:asn-nem-client:uploadArchives] :asn-nem-client:uploadArchives Project Version: 1.1.3.4.5
[13:47:25][:asn-nem-client:uploadArchives] Uploading: com/alcatel/asn/asn-nem-client/1.1.3.4.5/asn-nem-client-1.1.3.4.5.jar to repository remote at http://vvv.zzz.yyy.xxx:8081/artifactory/libs-release-local
[13:47:25][:asn-nem-client:uploadArchives] Transferring 1545K from remote
[13:47:25][Step 1/3]
 [13:47:25][Step 1/3] FAILURE: Build failed with an exception.
[13:47:25][Step 1/3]
 [13:47:25][Step 1/3]
 [13:47:25][Step 1/3] BUILD FAILED
[13:47:25][Step 1/3] * What went wrong:
[13:47:25][Step 1/3]
 [13:47:25][Step 1/3] Execution failed for task ':asn-nem-client:uploadArchives'.
[13:47:25][Step 1/3] Total time: 38.951 secs
[13:47:25][Step 1/3] > Could not publish configuration ':asn-nem-client:archives'.
[13:47:25][Step 1/3]
  > Error deploying artifact 'com.alcatel.asn:asn-nem-client:jar': Error deploying artifact: Authorization failed: Access denied to: http://vvv.zzz.yyy.xxx:8081/artifactory/libs-release-local/com/alcatel/asn/asn-nem-client/1.1.3.4.5/asn-nem-client-1.1.3.4.5.jar