Versioning of artifacts - CI/CD - jenkins

Build process of java code is currently generating artifacts with name having no version number.
For ex: serial-framework-SNAPSHOT.jar
We are currently in build phase of CI/CD pipeline
All the artifacts generated through maven build has no version number for back-end services, in build phase of CI/CD pipeline
Dependent artifacts that are required to build a specific jar are only stored in JFrog artifactory
1)
Does it require versioning of artifacts for Build/QA/prod phase of CI/CD pipeline?
2)
Does it require to store every artifact in JFrog artifactory? Because only dependent artifacts that are required by pom.xml during maven build are stored in JFrog

The versioning was well explained in the first answer by snukone.Note the below points which might be helpful regarding versioning
For development always follow the version as “versionNumber-SNAPSHOT “(capital letters)
Eg:- 1.0 -SNAPSHOT
2) For test/prod branch follow the version as “versionNumber-RELEASE”
Eg:- 1.0 – RELEASE
a) Snapshots are mutable, so they are used for development purpose.
b) Releases are immutable. Once committed we cannot override the artifact in the
artifactory. So releases are used for higher environments.
c) Snapshots capture a work in progress and are used during development. A Snapshot artifact has both a version number such as “1.3.0” or “1.3” and a timestamp. For example, a snapshot artifact for commons-lang 1.3.0 might have the name commons-lang-1.3.0-20090314.182342-1.jar
So in your case if you are using "serial-framework-SNAPSHOT" it will store as "serial-framework-version-timestamp.jar" in your artifactory.
Similarly if you are using "serial-framework-RELEASE" it will store as "serial-framework-version.jar" in your artifactory.

How versioning helps:
Versioning helps in case you want to restore an older version of your application (due to bugs that are heavily decreasing performance in production)
If you are running integrationtests on api or ui level, you can specify which versions are fitting together (ie via contract testing: https://github.com/pact-foundation/pact_broker)
Default cleaning processes helps you to prevent your artifactory from huge storage usage
Storing every artifact or not?
My personal experience: Just store the artifacts which are dependencies to other artifacts. Like Libs for example. If you are working with Docker Container you should think about to version the Docker images which you are producing on every build.

Related

How to versionate artifacts on Artifactory without overwriting

I'm trying to extend our Jenkins job (which builds the entire project) to deploy the built artifacts to our Artifactory but then I faced some problems related to the versioning of the artifacts. If I try to redeploy an artifact whose version didn't change (not a snapshot), I get an error 403 (user 'foo' needs DELETE permission) which is understandable, I should not replace an already released artifact. If the artifact version contains -SNAPSHOT then there are no problems, it's always uploaded. My question is: how we should approach the scenario of having locked overwriting in Artifactory?
Shouldn't the artifactory plugin from Jenkins just ignore the deploy of the artifact in case is already deployed instead of failing the job?
Or should we use always -SNAPSHOT (during development) even the artifact has not changed?
Do we increase the version on every release even the artifact has not changed?
Shouldn't the artifactory plugin from Jenkins just ignore the deploy
of the artifact in case is already deployed instead of failing the
job?
The job should fail if the artifact is already deployed with a fixed version (non -SNAPSHOT). For instance on a manual job trigger, I would like to know if I tried to build and deploy using a version name that is already published (maybe by someone else in the team)
Or should we use always -SNAPSHOT (during development) even the
artifact has not changed?
-SNAPSHOT is made for development. Yes we usually push the artifact at the end of the build, even if it did not change because you updated for instance a README and the job was triggered.
Usually SNAPSHOT have a lifetime depending on how you binary repository (here Artifactory) is configured. SNAPSHOT can be cleaned every 2 weeks for instance.
The link shared by Manuel has other interesting definitions like
Usually, only the most recently deployed SNAPSHOT,
for a particular version of an artifact is kept in the artifact repository.
Although the repository can be configured to maintain a rolling archive
with a number of the most recent deployments of a given artifact
https://docs.oracle.com/middleware/1212/core/MAVEN/maven_version.htm#MAVEN401
Do we increase the version on every release
even the artifact has not changed?
yup we increase the version number at every release. I call release what the customer will get. Except an exceptional occasion, you wont go through the process of release if the artifact didn't change. A release usually involves a lot of people in an organization, even people that are not from Development. A popular standard is to use semantic versioning https://semver.org/ Sometime people prefer to version with the date. My advice is to use semver and have a file in the artifact with the date of the build. This file could be used by the artifact itself to tell its version at runtime.
You could work with build numbers, and you wouldn't overwrite existing versions. Instead a buildNumber could include some bugfixes/security fixes.
https://docs.oracle.com/middleware/1212/core/MAVEN/maven_version.htm#A1000661
If you're using the depenfency, you can handle the versions with expressions. Exact version or expression which covers the buildNumber.

Staging of Repository within profile ID='X' is not yet started

Trying to deploy on a staging repository leads on the maven side to
400 , ReasonPhrase:Bad Request
and the server log contains
Staging of Repository within profile ID='X' is not yet started!
It makes no difference using maven-deploy-plugin or maven-release-plugin. All three leads to the error from above.
My deployment user has (admin) rights to deploy to every staging profile.
maven-release-plugin:
mvn release:stage -DstagingRepository=nexus::default::http://localhost:8081/nexus/service/local/staging/deploy/maven2
If you doesn't use versions with the maven-release-plugin like SNAPSHOT qualifier and similar, nexus-staging-plugin works fine.
What did I miss?
Staging of snapshot versions is not allowed, you need to use release versions.
At first glance you might think that this could be done by having Nexus rewrite the pom files and rename the artifacts. But it's not that simple, the version number is often embedded in the artifacts themselves. This is particularly true of assembled artifacts such as war/ear files, you'll find the version numbers inside contained artifacts, and inside configuration files within the artifact. Even if these could be rewritten by Nexus changing the version numbers potentially changes the behavior of the artifacts. In any case, Nexus will not change staged artifacts, any changes made could potentially lead to regressions. Staged artifacts (like all artifacts deployed to Nexus) are immutable.
Consequentially, you need to use a release version when staging.

How do I do release versioning with Gradle and Jenkins?

We're building a continuous integration pipeline for the project I'm working on. We have a number of build artifacts (both JAR and WAR files) which we have versioned and deployed to an Artifactory server.
All our JARs start at version 0.0.1-SNAPSHOT. As we develop, we'd like to mark milestones by setting a particular point in the codebase as 0.0.1, and starting development on 0.0.2-SNAPSHOT. Eventually, a particular version will get accepted by QA, and promoted to 0.1.0, and we will start working on 0.1.1-SNAPSHOT. The same process will happen with a release to Production, when we reach 1.0.0.
I can't seem to find a plugin for Jenkins that supports this kind of versioning. Ideally, it would track the current version of each WAR and JAR, and once it hit a particular point (after running acceptance tests) it would automatically increment the version. Does such a thing exist?
You can make use of the gradle-release plugin. Please find different approaches that are documented here

Publishing/copying artifacts from one Ivy repository to another one

We are using ant with ivy through Jenkins to do our daily builds. Initially we want to publish our artifacts to our test Ivy repository and once testing is done, we want to copy the same artifacts to our released Ivy repository without rebuilding them. Does the Ivy or Jenkins has any tasks that help with this? Also, when we publish them to test repository we are planning on using integration status, is there a way we can change the status to release when we copy to released Ivy repository? We have multiple modules that we do builds for but only selected of them need to be moved to released Ivy repository. Any help is greatly appreciated.
You can use the install task to copy artifacts between repositories.
A better solution to consider is using the staging suite a feature of Nexus professional. It works by creating a temporary repository for each release candidate, which can be promoted until deemed worthy of release. Other repository managers have similar features, worth considering rather than building your own.

allow redeploy of the same pom file

We have a project where I upload the artifacts to a nexus repository using ant and ivy. Things have gone smooth for a long time, but now we must deploy the same artifact twice (because we are generating the same product for windows and mac). The code of the application is the same, it just changes the packaging. I have configured the deploy process to use a maven classifier. The problem is that the uploads are done from 2 different machines because each one has the appropiate build environment for the destination platform.
So, the first deploy is done right and it uploads:
myproduct-1.0.pom
myproduct-1.0-mac.zip
When I try to deploy the windows artifact, that will deploy
myproduct-1.0.pom
myproduct-1.0-win32.msi
It fails because the repository policy does not allow redeploying (and it should stay that way), so trying to deploy a new pom file for the same artifact and version fails, even if the pom contents are the same.
Also it is possible that in the future we have a similar problem, deploying various artifacts of the same product and version but different classifier from the different machine but in different build processes.
Is it possible to tell nexus to not fail if when deploying a classified artifact with a pom, does not fail if the same pom file already exists in the repository? If it is not possible, I understand that the only way to deploy various artifacts with different classifiers is to deploy them all at the same time. Is it true?
In the end, I created a task that deployed just the pom without any classifier, and modified the deploy of the windows & mac artifacts to just deploy the packages but not the pom:
deploy pom without classifier
deploy mac artifact with classifier (mac)
deploy win artficat with classifier (win32)
Nexus doesn't complain when deploying the artifact without deploying a pom file at the same time when I thought I would complain.
I feel it's a dirty trick, but it works :)

Resources