How to run Jenkins pipeline for multi module projects - jenkins

In my project, I have multiple modules(consist of multiple directories and each directory having it's own dockerfile and pom.xml files). I have created a Jenkins pipeline for it. But every time I run the jenkins pipeline each module gets build and deployed, which wastes lot of time. Is there any way, to deploy only a particular module that time through my jenkins pipeline. So that it saves my time.
As of now I am commenting manually the module which I don't want to run in my jenkins pipeline, is there any way, I don't have to comment the module, but can run only the module, I requires through jenkins pipeline. I don't want to create separate jenkins pipeline for each modules, because there are lots of modules.
I don't want to use multi-branch pipeline since, all the module codes are present in one single branch only, and placing modules in different branches will change my code structure.
Is there any plugin or mechanism through which I can do build for only particular module that I want.

Take a look at when and change set on this page https://www.jenkins.io/doc/book/pipeline/syntax/
You could then run certain module build stages depending on if changes to that modules code have been committed.

Related

Pipeline to use artifacts from 2 projects associated by the same git branch name

the company where I work for is evaluating jenkins 2.71, in particular the pipeline and blue ocean plugins. We already tested also GoCD and we need, as in GoCD, a way for a pipeline to automatically fetch the artifacts from 2 other pipelines (taking the last successful result of each one of them), here our case.
We have these initial pipelines (build & run tests), which reflect 2 projects:
frontend, ~ 15 minutes
backend, ~10 minutes
I created a pipeline called configure (~1 minute), with e.g. a parameter called customer-name, which takes backend and frontend files and puts them together, then applies specific customer specific configurations and customizations and produces deployable artifacts. Instead of "customer-name" I could also parallelize this job to create all the artifacts for each customer at once, separated in different directories.
The next pipeline would be to deploy them on different test servers separated for each customer. This could be also part of the same configure pipeline, we still have to see how to put things together in jenkins...
Ideally, I need configure pipeline to be triggered automatically (or also on demand) after each frontend or backend success and take as input the last successful artifacts from these 2 pipelines, but not just having the last successful build, we need as dependency the git branch name.
E.g. we have:
backend branches:
master
release/2017.2
frontend braches:
master
release/2017.2
In the pipeline editor, I found a Build Triggers option and set it as follows: Build after other projects are built > Projects to watch: frontend, backend > Check Trigger only if build is stable or better in my test environment full of failures Trigger even if the build is unstable.
Searching further, I found Copy Artifact Plugin
But now the big question, how to fetch the last successful artifacts from these pipelines with the same git branch name?
Because we don't want to mix e.g. a backend build of "release/2017.2" with frontend "master", it has to find as the last successful build having the same relationship or parameter or whatever you wanna call it, in our case the association is the git branch name.
Is it possible to achieve this? If yes, how?
The copy artifact plugin seems to work in a freestyle project. Would it work in a pipeline? That's also a concern...
Thanks
Yes, the Copy Artifact plugin does work in both freestyle and pipeline projects; pipeline uses the copyArtifact function that I referenced in my comment. Note that if you go to the Pipeline Syntax link, it's kind of hidden: you have to first select "step: General Build Step" from the drop-down, then it will give you the Copy Artifact pipeline command builder.
I'm going to assume that your frontend and backend projects are built as multi-branch pipelines, as that would probably be easiest to maintain so that you don't have to keep creating new projects for every release. You can reference these projects from other projects by referencing <project name>/<branch name> (sometimes I've had to replace the / with %2f instead, I think mostly on freestyle projects). You could then set up your configure project as a parameterized build (either pipeline or freestyle), say with a string parameter of PROJECT_BRANCH_NAME. Then put in the following in your frontend/backend project pipeline scripts to trigger a build of your configure project
build job: 'configure', parameters: [[$class: 'StringParameterValue', name: 'PROJECT_BRANCH_NAME', value: ${env.BRANCH_NAME}]]
Then you should just be able to make your configure project reference the frontend/%PROJECT_BRANCH_NAME% and backend/%PROJECT_BRANCH_NAME% (or ${env.PROJECT_BRANCH_NAME} in a pipeline script) when copying the artifacts.
Also, is there a particular reason why you're evaluating specifically Jenkins 2.7? 2.7 is a year old now, and there have been a few new LTS releases since then. I'd recommend staying reasonably up-to-date unless you know there's a specific reason you want 2.7.

Jenkins with Shared jobs

I am working with Jenkins, and we have quite a few projects that all use the same tasks, i.e. we set a few variables, change the version, restore packages, start sonarqube, build the solution, run unit/integration tests, stop sonarqube etc. The only difference would be like {Solution_Name}, everything else is exactly the same.
What my question is, is there a way to create 1 'Shared' job, that does all that work, while the job for building the project passes the variables down to that shared worker job. What i'm looking for is the ability to not have to create all the tasks for all of our services/components. It be really nice if each of our services/components could have only 2 tasks, one to set the variables, another to run the shared job.
Is this possible?
Thanks in advance.
You could potentially benefit from looking into the new pipelines as code feature.
https://jenkins.io/doc/book/pipeline/
Using this pattern, you define your build pipeline in a groovy script rather than the jenkins' UI. This script is then kept in the codebase of the project it builds in a file called Jenkinsfile.
By checking this pipeline into a git repository, you can create a minimal configuration on the jenkins' side and simply tell it to look towards a specific repo and do the things that pipeline says to do.
There's a few benefits to this approach if it works for your setup. The big one being that your build pipeline will be fully versioned just like the project it builds. And the repository becomes portable, easily able to be built on any jenkins' installation across as many jobs as long as the pipeline plugins are installed.

Adding Jenkins Pipelines on Build

does anyone know if its possible to add a Jenkins pipeline build into a Jenkins docker image? For example, I may have a Jenkinsfile that defines my pipeline in groovie, and would like to ADD that into my image when building from the Jenkins image.
something like:
FROM jenkins:latest
ADD ./jobs/Jenkinsfile-pipeline-example $JENKINS_HOME/${someplace}
And have that pipeline ready to go when i run it.
Thanks.
It's a lot cleaner to use Jenkinsfile for this instead. This way, as your repositories develop you can change the build process without needing to recompile and redeploy your Jenkins instance everytime. (less work, and less CI downtime) Also, having the Jenkinsfile in source code allows a simpler decoupling.
If you have any questions about extending Jenkins on Docker further to handle building NodeJS, Ruby or something else I go into how to do all that in an article.
You can create any job in Jenkins by passing in an XML file that describes the job. See https://support.cloudbees.com/hc/en-us/articles/220857567-How-to-create-a-job-using-the-REST-API-and-cURL
The way I've done this is to manually create the job I want in Jenkins, then append config.xml to the URL and it shows you the XML content needed to generate the pipeline job. Save that XML and you can deliver it to your newly deployed Jenkins instance.
I use a system similar to this to generate several hundred jobs based on our external build specifications.

Jenkins Pipeline per branch environment variable configuration

I have several Jenkins Pipeline jobs set up on my Jenkins installation all of them with a Jenkinsfile inside the repository.
These pipelines are run for all branches, and contains all steps necessary to build and deploy the branch. However, there are some differences for the different branches with regards to building and deploying them, and I would like to be able to configure different environment variables for the different branches.
Is that possible with Jenkins, or do I need to reevaluate my approach or use another CI system?
#rednax answer works if you're using a branch-per-environment git strategy. But if you're using git-flow (or any strategy where you assume that changes will be propogated up, possibly without human intervention, to master/production) you'll run into headaches where a merge will overwrite scripts/variables.
We use a set of folders which match the environment names : infrastructure/Jenkinsfile contains the common steps, and infrastructure/test/Jenkinsfile contains the steps specific to the test environment (the folders also contain Dockerfiles and cloudformation scripts). You could make that very complex with cascading includes or file merges, or simply have almost-identical copies of each file in each folder.
When configuring the job you can specify for Jenkins to grab the script (Jenkins file) from the branch on which you are running. This mean that technically you can adjust the script on each of your branches to set up parameters there. Or you can grab the script from the same source control location, but commit a configuration file in each of your branches and have the script read that file after the checkout.

Jenkins Job DSL Plugin - Include another Jenkinsfile

I want to build a Common Jenkinsfile for a couple of Build Jobs in different languages. And then I want to add a specific Jenkinsfile that depends on some parameters.
For example: the common file should contain information about Docker Hub and Nexus Repository. It's always the same. And the specific file should contain language specific build steps.
Is it possible to "include" another file?
Using the Pipeline Shared Groovy Libraries Plugin it is possible to define your own Job DSL. This section of the plugin's manual explains how to do this.

Resources