How can I prevent an artifact from being re-released to a repository?

A year ago there was a discussion regarding how to prevent an artifact from being re-released over and over again.

http://gradle.1045684.n5.nabble.com/Using-an-IvyResolver-directly-to-query-existing-versions-causes-NullPointerException-td4552897.html

Now, I get the feeling things have moved on here and I am wondering what would the best way be to deal with this as things currently stand?

Is there an elegant way to use the artifact repositories that Gradle have been configured to use and via Gradle (rather than going via Ivy APIs) query whether the artifact (group:name:version) has already been released/uploaded to the repository?

Have you considered implementing this on repository-level instead? If using Nexus, there is a repository configuration to disable re-deploy:

It should be possible with Artifactory as well, if not supported out of the box, surely can be implemented with a custom Artifactory plugin.

I think that this cannot be implemented properly on the client-side since you will need to use some kind of a transaction-like “check-upload” mechanism to ensure that nobody else can upload the same module after you checked for its existence but before you managed to upload it.

Regards,

Detelin

Certainly the support for preventing this would be implemented at multiple levels.

However, the issue here is that, despite having a fully competent tool in front of me that knows about the repositories I have configured, there does not appear to be any way to programmatically access and use that information on the fly.

For example, I don’t seem to have any way to check whether certain constraints are met before I put through my software through eg. pre-release quality gate testing. Perhaps I don’t want to waste that effort if I already knew that someone had gone in before me, thus indicating there might be further actions required before testing could commence, eg. merging in latest code changes.

What can I say, I agree - I would really like to see more Ivy features exposed to Gradle users, but it seems that the future is the opposite. When I started using Gradle I thought that since it uses Ivy under the hood, everything possible with Ivy should be possible with Gradle. But it seems that Gradle developers would not like to expose Ivy to the users, since using Ivy directly could interfere with Gradle’s Ivy-specific operations and lead to subtle problems that are hard to detect - and this could potentially disappoint Gradle users. But I think that while Gradle developers try to find the lowest common denominator between Ivy and Maven and expose this as pure Gradle API, all the power users of those tools are suffering since they have no way to configure their favorite tool the way they like. IMHO the least that could be done is to create a list of supported Ivy/Maven features so that any new Gradle users that come from either Ivy or Maven land will be aware of the restrictions, rather than figure them out much later when they want to do something specific.

Regards,

Detelin

Now, I get the feeling things have moved on here and I am wondering what would the best way be to deal

with this as things currently stand?

Right now, it’s best to implement this at the repository layer. Regardless, it’s also the safest as it protects anyone from re-publishing… not just the Gradle build.

Is there an elegant way to use the artifact repositories that Gradle have been configured to use and via Gradle (rather than going via Ivy APIs) query whether the artifact (group:name:version) has already been released/uploaded to the repository?

Not at the moment I’m afraid.

But it seems that Gradle developers would not like to expose Ivy to the users.

We don’t want to tie it to the core. As we extract it from the core we are pushing it out so we can expose it via a plugin. Why we are doing this below…

But I think that while Gradle developers try to find the lowest common denominator between Ivy and Maven and expose this as pure Gradle API

It’s probably fair to say that this was the strategy when Gradle was started, however it’s not our strategy now. Rather than abstracting over the two protocols/formats, we are working towards adapting to them. So, at the core there is a general engine that specific protocols can be plugged into in a sense. In the publication space, you can see this starting to happen already with the new Ivy publish stuff we delivered in 1.3.

However, we still have a long way to go. It’s challenging to make such a fundamental change in a backwards compatible way, which is what we have to do.

In short, our strategy going forward is to “adapt” and not to “abstract” WRT dependency management protocols.

That’s great info Luke, thanks for sharing. I would expect it to be really challenging, especially on the resolve side. About backward compatibility - I think that if you can manage to do it in small steps while keeping the old functionality supported, it will not cause that much pain. I was a bit concerned about all the stuff you are deprecating with the new publication support, but at the end we need to live with it if we want Gradle to evolve. I think that the people that are quite familiar with Gradle will not have a hard time to adopt the changes, but probably it would be much harder for those that just want to get something to build (e.g. doing copy-paste of already available build scripts) without caring much about how it works. Hopefully the Gradle community will be willing to adopt the changes and provide feedback, at least I will do my best. Thanks and have a nice weekend.