Delete and/or Replace Artifacts in Nexus using Gradle - gradle

I am still new to Gradle and Nexus.
I want to be able to remove artifact from a hosted nexus repository with Gradle. Using the nexus GUI in order to do this is not an option, because I don't wanna.
Part of the reason for wanting this is to be able to automatically correct upload errors such as incorrectly labeled artifacts, or artifacts uploaded with he wrong version. I may also just want to wipe out an entire project and all versions of it (maybe because it was uploaded to the wrong repo, or I'm just doing some house cleaning. OR perhaps I want to overwrite the currently up-loaded version of an artifact. Anyways, I don't have a real use case right now, but I still want to know how to do it.
Edit: Also, I'm curious about ways to "gracefully" handle times when a certain artifact version is already uploaded, such as catching a specific exception and outputting a user friendly message to advise the developer to update the build version before uploading.
Here's my current uploadArtifact task.
uploadArchives {
repositories {
flatDir {
dirs 'repos'
}
mavenDeployer {
credentials {
username "user"
password "password"
}
url "http://localhost:8081/nexus/content/repositories/releases/"
}
}
}

There isn't anything built into Gradle to manage a Nexus repository. Unless you find a third-party Gradle plugin for this, you'll have to develop your own solution. For example, you could write one or more Gradle tasks that use Nexus' REST APIs to accomplish what you want.
PS: Maven repositories are designed to be immutable, and changing any data or metadata after it has been published is generally frowned upon. (Instead a new version should be published that fixes the problem.) For such a change to take affect, every developer and CI machine will have to run all affected builds with --refresh-dependencies in order to invalidate the local cache (or wipe out the whole cache). This will likely cause lots of pain.

Related

Can I keep Maven local repository on another machine and use it in my project?

Where are Maven and pom.xml file kept in a real-time project if the code is at GitHub. I mean can I keep my local repository somewhere in another machine and use it in my project. If yes, how?
Local repositories are not meant for sharing. They are also not "thread-safe" in any way, so accessing them simultaneously from two different builds might break things.
They are populated by the artifacts Maven downloads from MavenCentral and other repositories, and also the stuff you build yourself. As they are more or less a form of cache, there is no need to share them.
If you need a repository that is used from different machines or by different users, set up a Nexus/Artifactory server.

What is the best practice for archiving Jenkins pipeline artifacts

I see that you can add a goal to a maven Pom to archive artifacts to a repo manager such as nexus
https://www.baeldung.com/maven-deploy-nexus
distributionManagement>
   <snapshotRepository>
      <id>nexus-snapshots</id>
      <url>http://localhost:8081/nexus/content/repositories/snapshots</url>
   </snapshotRepository>
</distributionManagement>
But Jenkins also allows you to do this from the pipeline itself
https://wiki.jenkins.io/plugins/servlet/mobile?contentId=96076078#content/view/96076078
freeStyleJob('NexusArtifactUploaderJob') {
steps {
nexusArtifactUploader {
nexusVersion('nexus2')
protocol('http')
nexusUrl('localhost:8080/nexus')
groupId('sp.sd')
version('2.4')
repository('NexusArtifactUploader')
credentialsId('44620c50-1589-4617-a677-7563985e46e1')
artifact {
artifactId('nexus-artifact-uploader')
type('jar')
classifier('debug')
file('nexus-artifact-uploader.jar')
}
artifact {
artifactId('nexus-artifact-uploader')
type('hpi')
classifier('debug')
file('nexus-artifact-uploader.hpi')
}
}
}
}
What is the difference between the two approaches, is one more commonly used?
The main difference is that if you use maven, you can manually add artifacts to Nexus from your local computer, using mvn deploy. So it really comes down to how you want to create the artifacts that end up being used in production. In my experience, the preferred way of doing this is through using Jenkins. The advantage of using Jenkins is that you link your new version builds to other activities, as well as the possibility to trigger a release when certain conditions have been met, rather than starting the build manually. Also, you end up with all versions being built on the same platform, and you avoid differences between computers if every developer builds such versions from their own computer.
But you might still need the maven configuration. Jenkins might use this information to find the URL to upload the artifact to (your example says nothing about how Jenkins finds Nexus), and sometimes it is useful to upload a SNAPSHOT-version, or some other temporary version not meant for production. In your example you only define Nexus for upload SNAPSHOT-versions, I guess this is done on purpose to enforce a rule that uploading final version from local computers is disallowed.
By the way, having a repository defined in your pom.xml does not automatically mean that anything will be uploaded. It is only if you do mvn deploy with a repository defined in your pom that something will be uploaded.

Custom build tagging with Jenkins, Artifactory, Maven

I'm working on a strategy to tag builds in my continuous integration and delivery pipeline. When a fresh build is produced it then goes through multiple stages of testing; after each stage I would like to tag the build. My idea was to expand on the standard Maven system, so an example would be:
my-artifact-1.0-SNAPSHOT.jar
my-artifact-1.0-PASSED_TESTS_1.jar
my-artifact-1.0-PASSED_TESTS_2.jar
...
my-artifact-1.0-RELEASE.jar
As a build passes each stage its tag, which is part of its name/version, gets updated. Eventually, after all testing stages the build is tagged as releasable with RELEASE.
I'm using a Jenkins server and storing artifacts on Artifactory (non-Pro) in Maven repositories. My plan is to use separate Maven repositories for each tag type above, and to move an artifact from one to the other as its tag is updated.
My pseudo-code for the promotion looks like:
(1) Download artifacts that passed in Jenkins
(2) Text-replace the tag (maybe pom.xml as well?)
(3) Upload to new repository
(4) Update the associated Git commit with tag also
I'm not sure how to actually implement this cleanly - is this a common way of doing things? Am I missing something important? Can a Jenkins + Artifactory (non-Pro) + Maven (repos only, Gradle for builds) system accomplish this?
Thanks!
I can see where the idea of adding more metadata to the file names come. Usually, we don't have any other place to add this kind of information, except of the name. But with a proper artifact repository manager (as Artifactory), you don't need it anymore. You can attach any metadata to the artifacts in the repository manager, and then manipulate (e.g. promote) the artifacts based on those properties.
Here's a screencast showing what it takes to add this kind of metadata to the artifacts, and how to promote artifacts based on it.

How do I block redeployments to Sonatype Nexus OSSRH

We're deploying our open source libraries to the OSS instance of Sonatype Nexus (https://oss.sonatype.org/) using the nexus-staging-plugin. This works all fine and well. However, since we're using a build server I want to block an accidential re-deployment of an existing artifact id - as this is normally not suppoted by maven. However, the OSSRH happily accepts and updates an existing release. Is there any way to block this and make the build fail?
I know that Nexus can be configured to do that - it is just, that I don't have any permissions to reconfigure the OSSRH instance..
Is there any maven plugin which could check the repo first and fail in first place in case nexus/sonatype does not support this? I looked into the enforcer plugin but there isn't a rule available.
It is true that there is a staging rule in Nexus which prevents duplicate GAV's being staged, but it is not enabled on https://oss.sonatype.org. The reason for this is that some users stage artifacts repeatedly (creating multiple staging repositories) and then choose one of them for release based on testing results.
But the server at https://oss.sonatype.org is configured so that you cannot release the same artifacts twice. So if you have two staging repositories that contain the same artifacts you will only be able to release one of them.

Can Nexus/Artifactory store copies from a public repository?

The requirements are as follows. We need copies from binaries we need in our projects on our repository server. We can't just proxy the public repository because we had several cases in the past where the binaries on the public repository were changed without changing the release number and we want to avoid problems imposed by that, thus we want to manually specify when to download it from the public repository and when to update. No changes are ever to be made to the binary stored on our repository server without manual interaction.
Is there a way achieve this? I.e. to say "I want artefacts X, Y, Z" copied to my repository server(preferably including their dependencies). Is this possible with either Nexus or Artifactory?
Yes. In Nexus define your own local repository, manually download the versions you want and add them to your repository. You may have to set up "manual routing" for dependency resolution to ensure that Nexus consults the repos in the correct order.
Then make sure your pom files refer to the specific versions you have downloaded.
One thing that will make this a little easier is that you can place the downloaded artifacts directly into the local storage directory of a Nexus repository (you don't need to upload them into Nexus).
See here for details: https://support.sonatype.com/entries/38605563

Resources