Jenkins simple pipeline not triggered by github push - jenkins

I have created a jenkins pipeline job called "pipelinejob" with the below script:
pipeline {
agent any
stages {
stage ('Setup'){
steps{
//echo "${BRANCH_NAME}"
echo "${env.BRANCH_NAME}"
//echo "${GIT_BRANCH}"
echo "${env.GIT_BRANCH}"
}
}
}
}
Under General, I have selected "GitHub project" and inserted my company's github in the form:
https://github.mycompany.com/MYPROJECTNAME/MY_REPOSITORY_NAME/
Under Build Triggers, i have checked "GitHub hook trigger for GITScm polling
I have created a simple job called "simplejob" with same configuration as 1) and 2)
In my company's Github, i have created a webhook like "jenkins_url/jenkins/github-webhook/"
I commit a change in "mybranch" in "MY_REPOSITORY_NAME"
My simple job "simplejob" is triggered and built successfully
My pipeline job "pipelinejob" is not triggered
In Jenkins log i see the below:
Sep 12, 2019 2:42:45 PM INFO org.jenkinsci.plugins.github.webhook.subscriber.DefaultPushGHEventSubscriber$1 run
Poked simplejob
Nothing regarding my "pipelinejob".
Could you please point me to the right directions as to what to check next?
P.S. I have manually executed my "pipelinejob" successfully

I wasted two days of work on this, as none of the previous solutions worked for me. :-(
Eventually I found the solution on another forum:
The problem is that if you use a Jenkinsfile that is stored in GitHub, along with your project sources, then this trigger must be configured in the Jenkinsfile itself, not in the Jenkins or project configuration.
So add a triggers {} block like this to your Jenkinsfile:
pipeline {
agent any
triggers {
githubPush()
}
stages {
...
}
}
Then...
Push your Jenkinsfile into GitHub
Run one build manually, to let Jenkins know about your will to use this trigger.
You'll notice that the "GitHub hook trigger for GITScm polling" checkbox will be checked at last!
Restart Jenkins.
The next push should trigger an automated build at last!

On the left side-pane of your pipeline job, click GitHub Hook log. If it says 'Polling has not run yet', you will need to manually trigger the pipeline job once before Jenkins registers it to poke on receiving hooks.
Henceforth, the job should automatically trigger on GitHub push events.

I found an answer to this question with scripted pipeline file. We need to declare the Github push event trigger in Jenkins file as follows.
properties([pipelineTriggers([githubPush()])])
node {
git url: 'https://github.com/sebin-vincent/Treasure_Hunt.git',branch: 'master'
stage ('Compile Stage') {
echo "compiling"
echo "compilation completed"
}
stage ('Testing Stage') {
echo "testing completed"
echo "testing completed"
}
stage("Deploy") {
echo "deployment completed"
}
}
}
The declaration should be in the first line.
git url: The URL on which pipeline should be triggered.
branch: The branch on which pipeline should be triggered. When you specify the branch as master and make changes to other branches like develop or QA, that won't trigger the pipeline.
Hope this could help someone who comes here for an answer for the same problem with Jenkins scripted pipeline :-(.

The thing is whenever you create a pipeline job for git push which is to be triggered by github-webhook, first you need to build the pipeline job manually for one time. If it builds successfully, then Jenkins registers it to poke on receiving hooks. And from the next git push, your pipeline job will trigger automatically.
Note: Also make sure that the pipeline job built manually for the first time should be built successfully, otherwise Jenkins will not poke it. If it fails to build, you can never trigger the job again.

Related

Need option to fill values in Jenkins parameterized pipeline script stored in Github whenever it run

I have created a jenkins parameterized pipeline script as below. I have stored it on my Github repository.
properties([parameters([string(defaultValue: 'Devasish', description: 'Enter your name', name: 'Name'),
choice(choices: ['QA', 'Dev', 'UAT', 'PROD'], description: 'Where you want to deploy?', name: 'Environnment')])])
pipeline {
agent any
stages {
stage('one') {
steps {
echo "Hello ${Name} Your code is Building in ${Environnment} "
}
}
stage('Two') {
steps {
echo "Hello ${Name} hard testing in ${Environnment}"
}
}
stage('Three') {
steps {
echo "Hello1 ${Name} deploying in ${Environnment}"
}
}
}
}
Then, I have created a jenkins job by choosing pipeline option. While creating jenkins pipeline Under build triggers section, I have checked GitHub hook trigger for GITScm polling checkbox and Under Pipeline section, I have chosen Pipeline script from SCM followed by choosing Git in SCM, providing Repository URL where the above written JenkinsFile script is stored.
Then, Under Github repository settings, I have gone to webhooks and added one webhook where I specified my Payload URL as myJenkinsServerURL/github-webhook/. which will enable a functionality like whenever there will be any push event occurred within the repository, it will run the jenkins pipeline I created above.
Now, the situation is, when I am running this jenkins job from Classic UI by clicking Build with parameters, I am getting a text box to fill my name and a dropdown having list of 4 options ('QA', 'Dev', 'UAT', 'PROD') I gave above in script to choose, in which server I want to deploy my code, then it gets run.
But when I am committing in Github, it starts jenkins pipeline but not asking for parameters value instead just taking default value Devasish in name and QA in server.
What should I do to get an option of filling these details but not from Classic UI.
Thanks in advance.
As you have noted, when you trigger your pipeline manually, it will ask for the Build Parameters and let you specify values before proceeding.
However, when triggering the pipeline thru automatic triggers (e.g. SCM triggers/webhooks), then it is assumed to be an unattended build and it will use the defaultValue settings from your Jenkinsfile build parameters" definition.

In Jenkins, Is there a way to execute a pipeline when the source branch of a PR is updated?

This is my Jenkinsfile:
pipeline {
agent { docker { image 'node:10.16' } }
stages {
stage('PR To Dev') {
when {
changeRequest target: 'dev'
}
steps {
sh 'npm install'
sh 'npm run lint'
}
}
}
}
I'm trying to run linting upon every PR made (on Github). This pipeline works and runs as intended when I make the initial PR to the dev branch. However, subsequent commits to the open PR are ignored by Jenkins, which defeats the usefulness of the initial lint check. How can I configure Jenkins to lint upon any updates to a branch that has an open PR to the dev (or any arbitrary) branch?
Achieving this goal is possible. It depends greatly on the plugin that you are using to integrate GitHub with Jenkins, and how you configure GitHub to use Jenkins' webhooks.
On the GitHub end, you can configure to trigger the webhook on different events. Default config is Push events (to any branch, whether on PR or not), All events (these can have many false positives), and the option to Select individual events (find your right balance between events coverage and false positives)
On the Jenkins end, some plugins will offer more customization options to discard unnecessary triggers, for example to avoid triggering a project on PR updates of the title or description (instead of code), etc.
I, personally, use the Generic Webhook Plugin on the Jenkins end and then I analyze the json of the webhook to determine whether to run a job or not

commit based job using declarative pipeline

I am new Jenkins. I was able to configure commit-based job trigger using Freestyle job. This way, any new commit to GitHub was triggering the given job.
But when it comes to pipeline job, I am not able to achieve the same. Please help regarding the same.
In Build Triggers section of pipeline, I have enabled GitHub hook trigger for GITScm polling.
pipeline{
agent {
node 'npm-linux'
}
options {
timeout(time: 15, unit: 'MINUTES')
disableConcurrentBuilds()
}
stages {
stage('build') {
steps {
sh 'git clone link'
sh 'mvn clean install'
}
}
}
}
As you're able to successfully see the freestyle job getting triggered on commit, we know for sure that GitHub has been configured correctly. Now, to fix the declarative pipeline issue, you have to make use of triggers in your pipeline code.
For example,
pipeline {
agent any
triggers {
// Instead of '* * * * *', you may use 'H/2 * * * *' which will check for source code changes every two minutes
pollSCM '* * * * *'
}
stages {
stage ('Echo') {
steps {
echo 'Hello, World!'
}
}
}
}
Note:
In Build Triggers section of your job configuration, you still have to keep the check box enabled for GitHub hook trigger for GITScm polling
Even after the above setting, the declarative pipeline job did not trigger automatically when i pushed my commit. When i ran the job manually once, thereafter things went fine. All subsequent commits triggered the pipeline job. So, just manually trigger the job once and things should be fine.
Also remember that polling is resource intensive so it is generally not a good idea to use it. However, in this case, where you are using GitHub, i'm not sure whether post-commit functionality can be configured using any way other than GitHub Webhooks. And sadly, just with GitHub Webhooks enabled, pipeline job wasn't getting triggered without the help of triggers directive.

How to "Scan Repository Now" from a Jenkinsfile

I can call another jenkins job using the build command. Is there a way I can tell another job to do a branch scan?
A multibranch pipeline job has a UI button "Scan Repository Now". When you press this button, it will do a checkout of the configured SCM repository and detect all the branches and create subjobs for each branch.
I have a multibranch pipeline job for which I have selected the "Suppress automatic SCM triggering" option because I only want it to run when I call it from another job. Because this option is selected, the multibranch pipeline doesn't automatically detect when new branches are added to the repository. (If I click "Scan Repository Now" in the UI it will detect them.)
Essentially I have a multibranch pipeline job and I want to call it from another multibranch pipeline job that uses the same git repository.
node {
if(env.BRANCH_NAME == "the-branch-I-want" && other_criteria) {
//scanScm "../my-other-multibranch-job" <--- scanScm is a fake command I made up
build "../my-other-multibranch-job/${env.BRANCH_NAME}"
I get an error on that build line, because the target multibranch pipeline job does not yet know that BRANCH_NAME exists. I need a way to trigger an SCM re-scan in the target job from this current job.
Similar to what you figured out yourself, I can contribute my optimization that actually waits until the scan has finished (but is subject to Script Security):
// Helper functions to trigger branch indexing for a certain multibranch project.
// The permissions that this needs are pretty evil.. but there's currently no other choice
//
// Required permissions:
// - method jenkins.model.Jenkins getItemByFullName java.lang.String
// - staticMethod jenkins.model.Jenkins getInstance
//
// See:
// https://github.com/jenkinsci/pipeline-build-step-plugin/blob/3ff14391fe27c8ee9ccea9ba1977131fe3b26dbe/src/main/java/org/jenkinsci/plugins/workflow/support/steps/build/BuildTriggerStepExecution.java#L66
// https://stackoverflow.com/questions/41579229/triggering-branch-indexing-on-multibranch-pipelines-jenkins-git
void scanMultiBranchAndWaitForJob(String multibranchProject, String branch) {
String job = "${multibranchProject}/${branch}"
// the `build` step does not support waiting for branch indexing (ComputedFolder job type),
// so we need some black magic to poll and wait until the expected job appears
build job: multibranchProject, wait: false
echo "Waiting for job '${job}' to appear..."
while (Jenkins.instance.getItemByFullName(job) == null || Jenkins.instance.getItemByFullName(job).isDisabled()) {
sleep 3
}
}
Ended up figuring this out shortly after posting the question. Calling build against the base multibranch pipeline job as opposed to a branch causes it to re-scan. The solution to my above snippet would have ended up looking something like...
node {
if(env.BRANCH_NAME == "the-branch-I-want" && other_criteria) {
build job: "../my-other-multibranch-job", wait: false, propagate: false // scan for branches
sleep 2 // scanning takes time
build "../my-other-multibranch-job/${env.BRANCH_NAME}"
The wait: false is important because otherwise you get "ERROR: Waiting for non-job items is not supported". The multibranch "parent" job is closer to a folder than a job, but it's a folder that supports the build command, and it does so by scanning the SCM.
But solving this just led to another problem, which is that with wait: false we have no way of knowing when the SCM Scan finished. If you have a large repository (or you're short on jenkins agents), the branch won't get discovered until after the second build command has already failed due to the branch not existing. You could bump the sleep time even higher, but that doesn't scale.
Fortunately, it turns out manually initiating the SCM scan isn't even needed if you have github webhooks set up for your jenkins. The branch will be discovered more-or-less instantly, so for my purposes this is solved another way. The reason I was running into it is we don't have webhooks set up in our dev jenkins, but once I move this code to prod it will work fine.
If you're trying to use JobDSL to set up multibranches calling multibranches and you don't have webhooks or something equivalent, the better path is probably to abandon multibranch for your second tier of jobs and use JobDSL to create folders and manage the branch jobs yourself.

Notifications on jenkins job failures - with pipeline from scm

We have several jenkins pipeline jobs setup as "pipeline from scm" that checkout a jenkins file from github and runs it. There is sufficient try/catch based error handling inside the jenkinsfile to trap error conditions and notify the right channels.This blog post goes into a quite a bit of depth about how to achieve this.
However, if there is issue fetching the jenkinsfile in the first place, the job fails silently. How does one generate notifications from general job launch failures before the pipeline is even started?
Jenkins SCM pipeline doesn't have any execution provision similar to catch/finally that will be called if Jenkinsfile load is failed, And I don't think there will be any in future.
However there is this global-post-script which runs groovy script after every build of every job on Jenkins. You have to place that script in $JENKINS_HOME/global-post-script/ directory.
Using this you can send notifications or email to admins based on project that failed and/or reason/exceptions of failure.
Sample code that you can put in script
if ("$BUILD_RESULT" != 'SUCCESS') {
def job = hudson.model.Hudson.instance.getItem("$JOB_NAME")
def build = job.getBuild("$BUILD_NUMBER")
def exceptionsToHandle = ["java.io.FileNotFoundException","hudson.plugins.git.GitException"]
def foundExection = build
.getLog()
.split('\n')
.toList()
.stream()
.filter{ line ->
!line.trim().isEmpty() && !exceptionsToHandle.stream().filter{ex -> line.contains(ex)}.collect().isEmpty()
}
.collect()
.size() > 0;
println "do something with '$foundExection'"
}
You can validate your Jenkinsfile before pushing it to repository.
Command-line Pipeline Linter
There are some IDE Integrations as well
Apparently this is an open issue with Jenkins: https://issues.jenkins.io/browse/JENKINS-57946
I have decided not to use Yogesh answer mentioned earlier. For me it is simpler to just copy the content of the Jenkinsfile directly into the Jenkins project instead of pointing Jenkins to the GIT location of the Jenkinsfile. However, in addition I keep the Jenkinsfile in GIT. But make sure to keep the GIT and the Jenkins version identical.

Resources