The code we develop ends up being packaged into artifacts that are consumed as dependencies during the development of other software components. We rely on an artifact repository manager, like JFrog Artifactory, to resolve the complex challenges that come with consuming and developing all of these artifacts.
Artifactory serves as the foundation for managing binaries in so many organizations, both large and small, as part of an effective CI/CD pipeline.
This blog post will specifically discuss the administration challenges behind managing the consumption of binaries across development teams, focusing on security best practices for managing your connection details. As an example, we’ll focus on Java projects built using Maven. However, the same approach applies for any programming language and package type.
A little bit about JFrog CLI
Before we start with the specific challenge and solution, let’s recap. JFrog CLI is a smart client that provides a simple interface to automate access to the JFrog products. It includes a lot of functionality when it comes to the JFrog Platform, such as smart uploads and downloads with checksum optimizations, full support for File Specs, build integration features and a lot more. It also integrates with some of the most popular package managers, such as Maven, and enhances their functionality when used with the JFrog Platform.
The Challenge: Securely managing your repository connection details
Let’s take the following scenario. Your application is written in Java and it is built and packaged using Maven. Maven resolves the project dependencies from Artifactory and creates your application’s jars. Your developers are probably unaware that their dependencies are being resolved from the Maven repository in Artifactory, since this is configured in their local settings xml file. They are building their project locally and running their tests, with everything working perfectly.
Now, let’s take a look at your CI/CD pipeline. The CI server you’re using, such as Jenkins, CircleCI or JFrog Pipelines, continuously (or periodically) polls the source control repository and invokes Maven to build and test the code accordingly. When all goes well, a new snapshot version is deployed to the binary repository.
But, how does Maven know where to deploy the new snapshot version?
If you’re using Maven’s default deploy plugin, then the POM and settings.xml files should include the connection details to the deployment repository. In most cases, your developers do not directly deploy the artifacts they build and do not have access to the deployment repository. This means that we also need to maintain a dedicated settings xml file for the CI server. It also means that the server ID configured in the POM should match the ID in the settings.xml.
[...] <distributionManagement> <repository> <id>internal.repo</id> <name>MyCo Internal Repository</name> <url>Host to Company Repository</url> </repository> </distributionManagement> [...]
[...] <server> <id>internal.repo</id> <username>maven</username> <password>foobar</password> </server> [...]
Managing the deployment targets this way is inconvenient, to say the least. It becomes even worse when you have multiple projects, managed by different development teams, with different deployment repositories.
The Solution: Use JFrog CLI
I’d like to show you an easy and convenient way to solve this problem. If you’re using JFrog Artifactory to host your Maven repositories. This solution does not require your developers to change anything in the way they are working. The change is only in the CI server side. Instead of the CI pipeline invoking Maven directly, it will invoke Maven through JFrog CLI.
1. How to build and deploy your Maven artifacts using JFrog CLI
Run the following commands locally and then implement them as part of your CI pipeline:
- Install JFrog CLI.
- Configure your Artifactory server details:
> jfrog c add
- Clone the Maven project from the source control and CD into the root directory of the project:
> git clone https://github.com/jfrog/project-examples.git && cd project-examples/maven-example
- Configure the resolution and deployment details for the project:
> jfrog rt mvnc
Notice: You’ll now have a new .jfrog directory at the root of the project. This directory includes the resolution and deployment details. If you want, you can actually push the .jfrog directory to the source control. By doing so, the CI pipeline won’t need to run jfrog rt mvnc every time. You also have the option of not pushing this directory to the source control, and have your CI run the mvnc command every time, in a non interactive mode as follows:
> jfrog rt mvnc --server-id-resolve my-s-id --server-id-deploy my-s-id --repo-resolve-releases libs-release --repo-resolve-snapshots libs-snapshot --repo-deploy-releases libs-snapshot-local --repo-deploy-snapshots libs-release-local
2. Building and deploying your code
Building the code with JFrog CLI is very similar to building it with Maven directly, with one difference. Since we’re no longer using Maven’s deploy plugin, the deployment happens when running “install” and not “deploy”.
Run the following JFrog CLI command to build the code and deploy the artifacts with JFrog CLI:
> jfrog rt mvn clean install
Notice: You can add any Maven flag to the above command.
That’s it! You’re now ready to easily and securely manage your Maven repositories.
There are many more advantages to using JFrog CLI and Artifactory for Maven builds, like parallel deployments. We’ll discover more of them in the following blog posts.
Install JFrog CLI and start embedding it into your CI/CD pipelines.