CI/CD - zuul Vs Jenkins in Java EE applications
I am looking for a detailed answer for these two questions to compare Zuul vs Jenkins If your company is about to develop a new Java EE application, Then Which of these tools(Zuul ,Jenkins) would you recommned? why?
If your compnay wants to introduce the CI/CD practice for an existing Java EE application, then which of these tools(Zuul ,Jenkins) would you recommend? why?
1 answer
-
answered 2021-02-22 22:54
Rob Evans
This isn't the right type of question for an SO question ... BUT I'll humour you...
If I was starting a company and I wanted to pick between the two I'd go for Jenkins. Why? Widely supported/documented, its battle tested, its flexible, its used by developers of all abilities and most people have used CI/CD before so even if devs don't have experience in Jenkins specifically, they'll at least have used something else - GoCD, Bamboo, TeamCity, etc. So hiring someone with the right/relevant experience won't be difficult.
For an application Jenkins as a CI/CD pipeline is designed for exactly this purpose. Its open source. Its free.
Zuul, which (from a very brief glance) looks like an API Gateway/proxy type service (similar to Google Apigee, Kong, Nginx type software).
Zuul is not really targetted at CI/CD in the same way. Its a technology to expose your applications to a wider audience... enabling routing, security (Authorisation/Authentication - OAuth), Load balancing, etc. So for me at least, it doesn't seem like the right tool for the job.
With Jenkins pipelines your free to do whatever you want in your build/deploy process - add/remove steps (run unit tests, run integration tests, run static analysis, package application(s), deploy application(s)), notify people on the chat rooms (for visibility), email the committer/team when a step fails, etc.
For CI/CD Jenkins.
See also questions close to this topic
-
Use Ascii string as value of a environment variable in spring-boot app
In my spring boot application, I've defined a template field in a ConfigurationProperties with a default value (in Ascii):
@Getter @Setter @Configuration @ConfigurationProperties("app.template") public class AppTemplateProps { String greeting = "\u00bfQu\u00e9 est\u00e1s haciendo %s?"; }
The value of
AppTemplateProps.greeting
is correct (is native):¿Qué estás haciendo %s?
But when i define
app.template.greeting
environment variable with the same value, the value ofAppTemplateProps.greeting
is incorrect (is not native):\u00bfQu\u00e9 est\u00e1s haciendo %s?
So what should i do to get the correct (native) value from environment variable?
-
Validation for File Size Limit Multipart using Spring Java
Can someone help me? I have a issue in validation of file size limit in Rest controller using multipart but it does not work. I already get the size of multipart and add some if statement to message the exceed limit of the file but its not working.
@RequestMapping(value = "/importCsvFile", method = RequestMethod.POST) public ResponseEntity<?> importCsvFile(MultipartFile inputFile) throws Exception { if (inputFile == null || inputFile.isEmpty()) { return new ResponseEntity<>("Please insert a CSV file.", HttpStatus.NOT_FOUND); } if (!inputFile.getContentType().equals("application/vnd.ms-excel")) { return new ResponseEntity<>("Upload CSV file only.", HttpStatus.NOT_ACCEPTABLE); } if (inputFile.getSize() > 1048576) { **====> File size limit** return new ResponseEntity<>("File too Large.", HttpStatus.NOT_ACCEPTABLE); } else { List<Object> items = objectSrvc.importCsvFile(inputFile.getInputStream()); if (items == null) { return new ResponseEntity<List<Object>>(HttpStatus.NO_CONTENT); } return new ResponseEntity<List<Object>>(items, HttpStatus.OK); } }
-
Combining text in 2 EditText into one file.txt in internal storage
Im trying to make a card like this.
Name: Message: To:
And i want to save it in 1 file like .txt into my internal storage. This is the example picture.
I try this code.
writeTofile(edt_txt + txtme.getText().toString());
but didnt work only one EditText is working to save in file. Help me please. Im newbie here.This is my code below:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { requestPermissions(new String[] {WRITE_EXTERNAL_STORAGE,READ_EXTERNAL_STORAGE},1); } init(); btn_save.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { writeToFile(edt_text + txtme.getText().toString()); } });
-
Run helm in jenkins pipeline
I have added helm as podtemplate in value.yaml file
podTemplates: helm: | - name: helm label: jenkins-helm serviceAccount: jenkins containers: - name: helm image: lachlanevenson/k8s-helm:v3.1.1 command: "/bin/sh -c" args: "cat" ttyEnabled: true privileged: true resourceRequestCpu: "400m" resourceRequestMemory: "512Mi" resourceLimitCpu: "1" resourceLimitMemory: "1024Mi"
so i want to run helm in pipeline as
steps { container('helm') { sh "helm upgrade --install --force ./helm" } }
but i got error
/home/jenkins/workspace/coverwhale@tmp/durable-4d1fbfd5/script.sh: 1: /home/jenkins/workspace/coverwhale@tmp/durable-4d1fbfd5/script.sh: helm: not found
Version of Helm and Kubernetes:
Helm Version:
$ helm version version.BuildInfo{Version:"v3.5.2", GitCommit:"167aac70832d3a384f65f9745335e9fb40169dc2", GitTreeState:"dirty", GoVersion:"go1.15.7"}
Kubernetes Version:
$ kubectl version Client Version: version.Info{Major:"1", Minor:"20", GitVersion:"v1.20.2", GitCommit:"faecb196815e248d3ecfb03c680a4507229c2a56", GitTreeState:"clean", BuildDate:"2021-01-13T13:28:09Z", GoVersion:"go1.15.5", Compiler:"gc", Platform:"linux/amd64"} Server Version: version.Info{Major:"1", Minor:"20", GitVersion:"v1.20.2", GitCommit:"faecb196815e248d3ecfb03c680a4507229c2a56", GitTreeState:"clean", BuildDate:"2021-01-13T13:20:00Z", GoVersion:"go1.15.5", Compiler:"gc", Platform:"linux/amd64"}
Which version of the chart:
What happened: /home/jenkins/workspace/coverwhale@tmp/durable-4d1fbfd5/script.sh: 1: /home/jenkins/workspace/coverwhale@tmp/durable-4d1fbfd5/script.sh: helm: not found
What you expected to happen: run helm chart
pipeline code
pipeline { agent any stages { stage('Initialize Docker'){ steps { script { def docker = tool 'whaledocker' echo "${docker}" echo "${env.PATH}" env.PATH = "${docker}/bin:${env.PATH}" echo "${env.PATH}" } } } stage('Checkout Source') { steps { git url:'https://github.com/alialrabi/laravel-example.git', branch: 'uat', credentialsId: 'github' } } stage("Build image") { steps { script { myapp = docker.build("alialrabi/coverwhale:${env.BUILD_ID}") } } } stage("Run Test") { steps { script { docker.image("alialrabi/coverwhale:${env.BUILD_ID}").inside { // sh 'composer install' // sh 'php artisan test' } } } } stage("Push image") { steps { script { docker.withRegistry('https://registry.hub.docker.com', 'dockerhub') { myapp.push("latest") myapp.push("${env.BUILD_ID}") } } } } stage('Deploy Uat') { steps { script { echo "Done Uat" sh "helm upgrade --install --force" } } } } }
-
Jenkins check the existence of a parameter
Say I have this Jenkinsfile
pipeline { agent any parameters { choice(choices: ['x', 'y', 'z'], name: 'MyChoiceParam') } stages { stage ('Foo') { steps { script { echo "MyChoiceParam: ${params.MyChoiceParam}" if (!binding.hasVariable('MyChoiceParam')) { params.MyChoiceParam = 'x' // this is an error, cannot assign to param env.MyChoiceParam = 'x' // this is okay } echo "MyChoiceParam: ${params.MyChoiceParam}" // if it got into the if, then we need to check env } } } } }
Say I have a multibranch pipeline job. I create a new branch, I get a new job. The first run of that job would fail because Jenkins does not render the parameters and it will break the logic afterwards.
I found that you can use
binding.hasVariable
but this doesn't really work because it enters the if every time.How could I check if a parameter exists and if not, assign a default value?
-
Jenkins pipeline runs recursivly due to git push file
During the pipeline, I need to update the version file based on a new generated tag.
I got it to work, but since I am updating the repo file, the pipeline is run again, which will cause the version file to be updated and that would cause the pipeline to run again (enter recursive behavior). Here is what I have:
if (env.GIT_BRANCH == 'master' && !env.CHANGE_TARGET) { //creeate tag based on next_tag which is calculated prior to this step dir('./src'){ writeFile file: "version.json", text: "{\"version\":\"${next_tag}\"}" } sh 'cat ./src/version.json' withCredentials([ usernamePassword( credentialsId: 'sc-github-app', usernameVariable: 'GITHUB_APP', passwordVariable: 'GITHUB_TOKEN', ) ]) { script { sh 'git config --global url."https://x-oauth-basic:${GITHUB_TOKEN}@github.*****.com/".insteadof https://github.*****.com/' sh 'git config user.email "GITHUB_APP@******.com"' sh 'git config --global user.name "GITHUB_APP"' sh 'git add ./src/version.json' sh 'git commit -am "update version"' sh 'git push origin `git rev-parse --abbrev-ref HEAD`:master' } }
The last line does update the version.json file in the repo but that will trigger the pipeline to run again since the repo was updated.
Is there a way to update the file without causing the pipeline to run again? Or any other approach?
-
Inject GitHub secret string in CI/CD pipeline
I am currently working on setting CI/CD pipeline for a UWP C# app. The app uses Visual Studio App Center for crash analytics and needs a secret key (That would be provided via App Center account and stored in GitHub secrets). The code by default passes
null
to startAppCenter
services but during CD job I intend to replace null with with the actual key. What are different options I can go about to achieve this?The ways I have found about going this way is either doing a direct find and replace on the C# code file where I start
AppCenter
, using string resources either in.resw
file or.xaml
file (this seems more elegant since these arexml
files and can be easily edited). What is the pro/con for each methods and is there any other alternatives achieving this? -
Azure Release Pipeline - How to Set Agent Pool
I am using Azure Classic UI to setup Release pipeline. I have 2 stages in a pipeline to reflect TEST and PRD. Also I am using self hosted agents to do build and release.
I have 2 Release Agent Pools (One for doing TEST and one for doing PRD releases) at Org level with a single agent in each. Each of these Agents is running on separate self hosted servers. Additionally I have another Agent Pool with single agent in it running build pipeline runs.
In the project I have a single release pipeline with 2 stages TEST and PRD. I want to be able to utilize the TEST Agent Pool for TEST stage and PRD for PRD stage. But I cant seem to define it anywhere. Is this possible ? I mean I can add an Agent Job in the pipeline where I can select one of the Agent Pools but When I add a Deployment group, I cant specify which Release Agent pool to use. It only does it by Deployment Group and I don't know if I can specify Deployment groups to run on a specific Release Agent ?
The Short of it is, how can I configure entire release pipeline to run on a specific Release Agent Pool ? Or define a specific stage of a pipeline to run on a specific Release Agent ? Maybe I am not understanding how release pipelines run. Thanks for any help
-
pull requests between two tags in git
Is there a way to get pull requests between two tags on a specific branch.
Right now, I am using git log to do this. But, seems like this is bringing pull requests created before the first tag(PreviousVersion).
git log --grep 'Merged PR' --oneline $CurrentVersion...$PreviousVersion --pretty=format:\"%s\"|cut -d':' -f 1|cut -d' ' -f3
Can you help.
-
How to configure fail-fast strategy for Zull CI jobs for a specific project?
How can someone configure a specific project (repository) to use a fail-fast strategy for jobs running inside it?
fail-fast strategy on CI means that you want to cancel any running jobs as soon the first one that counts towards final result is failing (saving compute resources and providing a faster feedback).
Please note that I explicitly asked about a specific project as this option should not affect other project that may have different preferences.
-
Define multiple jobs using loop
I have today on my YAML file that define the jobs I need something like this:
- job: name: test-job-001 description: | Test job 001 nodeset: nodes: - name: node label: worker-001.abcd - job: name: test-job-002 description: | Test job 002 nodeset: nodes: - name: node label: worker-002.abcd - job: name: test-job-003 description: | Test job 003 nodeset: nodes: - name: node label: worker-003.abcd
And so on, up until 40 jobs like these.
Is there a way to make it more dynamic using iteration somehow ? I'm not sure a job name could contain any sort of
for
operation, for example.Thanks in advance