Triggering job on github pr to a specific branch - jenkins

I am using the github branch source plugin: https://github.com/jenkinsci/github-branch-source-plugin to trigger jobs from github pr.
I would like jenkins trigger a build only when a pr to the master branch is made. I tried to use the branch filter plugin but it doesn't trigger at any pr. I guess it doesnt work on prs, only on direct push to branches.
is that possible?

this should to the trick. (there is a downside though as this condition is not on a plugin level, so the build will be triggered on other events too)
stage('build') {
when {
allOf {
branch 'PR-*'
environment name: 'CHANGE_TARGET', value: 'master'
}
}
steps {
sh 'building pr on master'
}
}

Related

Disable script from git SCM changelog in Jenkins pipeline job

I have a question when I use pipeline with git SCM, currently I push all Jenkinsfile script in git with master branch. But when I modify one Jenkinsfile script when the another pipeline job be trigger will only show the changes, It's very upset when I only when to check build changes.
for example:
I config pipeline with git SCM (git: xxx/jenkinsJob, branch: master, script: a.jenkinsfile)
# a.jenkinsfile
stage('Checkout external proj') {
steps {
git branch: 'my_specific_branch',
credentialsId: 'my_cred_id',
url: 'ssh://git#test.com/proj/test_proj.git'
}
}
After I modify b.jenkinsJob in git://xxx/jenkinsJob, when I trigger e A pipeline job,
the A job will show two git change for "xxx/jenkinsJob" and "git#test.com/proj/test_proj"
like:
# changes
b.jenkinsfile change message 1
b.jenkinsfile change message 2
b.jenkinsfile change message 3
a.jenkinsfile change message 2
..
test_proj change message
I know how to disable changelog in jenkinsfile.
git changelog: false, branch: 'my_specific_branch', url: 'ssh://git#test.com/proj/test_proj.git'
But in jenkins job configuration page, can not find any way to do that..
https://plugins.jenkins.io/git/
Is there any way to avoid disable changelog in jenkins pipeline script for Git SCM ?, let only show test_proj changes.
thanks!
Currently I use this way to clear changeLog, use currentBuild.getChangeSets().clear()
pipeline {
stages {
stage('Checkout') {
steps {
script {
currentBuild.getChangeSets().clear()
}
git branch: "master", url: 'ssh://xxx/test.git'
}
}
}
}

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

Using Jenkins declarative pipeline, how do I fetch and compare another branch with a private github repo?

Background
My team wants to update several linting rules in our project, however, doing so will cause our Jenkins build pipeline which lints, tests and builds each feature branch to break. We don't want to lose the value of linting each feature branch before merging, so we agree that linting only the files that the feature branch changes is a reasonable way to introduce these new lint rules without forcing us to re-lint the whole project up-front. Given that our entire project is already linted, this seems like a reasonable move.
A while ago I wrote a git tool to do exactly this. It determines which files have changed since the feature branch diverged from master and outputs those files so they can be consumed by eslint, pycodestyle and other linters. Here's the source if you're interested in how this is done.
Problem
Jenkins declarative build process and it's GitHub Branch Source Plugin seem to have a brittle checkout behavior that can't be modified to checkout more than just the feature branch that it's called on to build.
If I call git fetch origin stage within a build step, Jenkins complains about missing credentials. I don't feel comfortable sticking in credentials into my pipeline file, I'd MUCH prefer to continue using the Git plugin to manage credentials to our private github repo and pull branches, however, I'm at a loss as to how to specify for it to fetch more than just the feature branch.
For reference, here's the relevant portions of my Jenkinsfile
As you can see, I've tried adding the GitSCM code block to no avail. I've read this medium article which solves a similar problem, but I'm not using SSH credentials and I'd prefer not to given than we're already managing credentials using the Git plugin.
pipeline {
agent any
tools {
nodejs 'node12.7.0'
}
stages {
stage('checkout') {
steps {
checkout([
$class: 'GitSCM',
branches: [[name: '*']],
extensions: scm.extensions,
userRemoteConfigs: [],
doGenerateSubmoduleConfigurations: true
])
}
}
stage('install') {
steps {
script {
sh 'git config --add remote.origin.fetch +refs/heads/master:refs/remotes/origin/master'
sh 'yarn install'
}
}
}
stage('lint & test') {
failFast true
parallel {
stage('lint') {
when {
not {
anyOf {
branch 'stage'; branch 'int'; branch 'prod'
}
}
}
steps {
script {
sh """
git submodule update --init
yarn run lint
"""
}
}
}
...
}
}
stage('deploy') {...}
}
}
post {
failure {
notifySlack()
}
}
}
Create credential in your Jenkins with ssh key and private key, which can be added to the checkout userRemoteConfigs which will be used while checking out (Value given down just an example of one the credential id in my Jenkins environment)
userRemoteConfigs: [[credentialsId: '7969s7612-adruj-au2cd-492msa802f']]
One frequent root cause - mentioned on the referenced medium article, too - is that Jenkins only checks out the current branch that needs to be build.
An easy option I just found to have other project branches available is to
Configure your pipeline job
Under Behaviors->General, add Specify ref specs
Optionally adjust the parameter to the refs you need, e.g. the branches to compare to. Or you can get all branches by maintaining the default +refs/heads/*:refs/remotes/#{remote}/* as shown in the screenshot:
Jenkins Pipeline Job - Ref Config
P.S.: This seems to be part of the GIT Jenkins plugin, but I couldn't find it in the docs...

How git merge works for multibranch pipeline?

I am setting up a multi-branch pipeline in Jenkins for my application. I am unsure about how different jenkinsfile checked into the repository handles merging.
For example, I have 3 branches, master, develop and feature-1, all those branches require a different pipeline configuration (see below).
master:
1. build
2. test
3. deploy to PROD
4. tell everyone using email
develop:
1. build
2. test
3. deploy to DEV
feature-1:
1. build
2. test
From day 1, master has Jenkinsfile for production release, develop was branched with the same Jenkinsfile content, changes were made to deploy to DEV and removed last step, committed change.
Day 2: feature-1 branched off develop, changes were made to remove deploy step and committed.
When feature-1 is completed, we are merging feature-1 into develop branch, since the commit that removed last step is dated after the develop commit, this is going to result in Auto-Merge and will make "develop" branch not deploy. Same will happen when develop is merged into master
Based on above potential issues, I think I must be doing something wrong here, what is the best practice for managing Jenkinsfile in Multi-branch pipeline?
Implement some flow control (https://jenkins.io/doc/book/pipeline/syntax/#flow-control) and maintain the same Jenkinsfile in all your branches.
if (env.BRANCH_NAME == 'master'){
echo 'do all the things'
} else if (env.BRANCH_NAME == 'develop'){
echo 'do a few things'
} else if (env.BRANCH_NAME == 'feature-1'){
echo 'do a couple things'
}
The BRANCH_NAME information is exposed by Jenkins when using Multibranch Pipelines (https://jenkins.io/doc/book/pipeline/multibranch/#additional-environment-variables).
You could use conditional statements like
// Note: this is a declarative pipeline
stage('deploy PROD'){
when { branch 'master' }
steps {
...do deploy...
}
}
stage('deploy DEV'){
when { branch 'develop' }
steps {
...do deploy...
}
}
...
For more info see:
https://github.com/jenkinsci/pipeline-examples/blob/master/declarative-examples/simple-examples/whenBranchMaster.groovy#L13
https://jenkins.io/doc/book/pipeline/syntax/#when

Trigger workflow on Github push - Pipeline plugin - Multibranch configuration

We are using the pipeline plugin with multibranch configuration for our CD.
We have checked in the Jenkinsfile which works off git.
git url: "$url",credentialsId:'$credentials'
The job works fine, but does not auto trigger when a change is pushed to github.
I have set up the GIT web hooks correctly.
Interestingly, when I go into a branch of the multibranch job and I click "View Configuration", I see that the "Build when a change is pushed to Github" is unchecked. There is no way to check it since I can not modify the configuration of the job (since it takes from parent) and the same option is not there in parent.
Any ideas how to fix this?
For declarative pipelines try:
pipeline {
...
triggers {
githubPush()
}
...
}
For me this enables the checkbox "GitHub hook trigger for GITScm polling", but polling is not actually required. This requires the GitHub plugin.
I found a way to check the checkbox "Build when a change is pushed to Github".
This line did the trick:
properties([pipelineTriggers([[$class: 'GitHubPushTrigger'], pollSCM('H/15 * * * *')])])
I think the polling is needed to make it work. Would be nice if no polling is needed.
Here's a Jenkinsfile example with this implemented:
#!/usr/bin/env groovy
node ('master'){
stage('Build and Test') {
properties([pipelineTriggers([[$class: 'GitHubPushTrigger'], pollSCM('H/15 * * * *')])])
checkout scm
env.PATH = "${tool 'Maven 3'}/bin:${env.PATH}"
sh 'mvn clean package'
}
}
For declarative pipelines, try this:
pipeline {
agent any
triggers {
pollSCM('') //Empty quotes tells it to build on a push
}
}
If you use Stash for example you can register a Post-Receive WebHook where you have to insert your URL form Jenkins like : http://jenkinsHost:9090/git/notifyCommit?url=ssh://git#gitHost:1234/test.git
In your jenkins Job you have to set at least the Build trigger "Poll SCM".
And set a polling time of e.g 5 mins.
This enables also the automatic branch indexing for your multibranch project configuration.
Resorting to polling adds latency - time that it takes for a build to start and hence finish giving back a result.
It seemed to me that the basic plugins have a low level of abstraction, so I switched to the Github Organization Folder plugin, which depends on all of them and sets up an organization hook for triggering builds branches and/or pull requests.
Before I start, I would like to emphasize that I had no previous experience with Jenkins so far, so there might be a bunch of better solutions out there.
What I wanted to achieve in a nutshell:
After every push made to a Bitbucket repo(test2), on every branch,
pull and build another Bitbucket repo(test1), from an identical
branch name and right after that, build test2 using test1 as a
dependency.
How I managed to achieve that?
I started a new job with type 'Multibranch Pipeline'
I added the following Jenkinsfile to test2:
pipeline {
agent any
stages {
stage('build') {
steps {
dir('test1') {
git branch: BRANCH_NAME, url: 'git#bitbucket.org:user/test1.git', credentialsId: 'credentials_id'
}
sh('build_process')
}
}
}
}
I come across the issue that you can't set up a Bitbucket hook for pipelines
I added Bitbucket Branch Source Plugin to Jenkins
I selected Bitbucket at 'Branch Sources' when setting up the job
I added credentials and put a checkmark to Auto-register webhook
Under 'Scan Multibranch Pipeline Triggers' I put a checkmark to Periodically if not otherwise run, with an interval of 1 min
I added a webhook to my Bitbucket repo
I updated all my plugins, restarted Jenkins and it's ready to go
Other plugins I have installed: Bitbucket Plugin, Pipeline plugin. Hope this helps for somebody, I did manage to solve it this way after hours of struggling without the Bitbucket Branch Source Plugin.
node{
stage('Build and Test') {
properties([pipelineTriggers([[$class: 'GitHubPushTrigger'], pollSCM('* * * * *')])])
checkout([$class: 'GitSCM', branches: [[name: '*/master']], doGenerateSubmoduleConfigurations: false, extensions: [], submoduleCfg: [], userRemoteConfigs: [[credentialsId: 'xxx-xxx-xxxx[your credentails Id]', url: 'https://github.com/git']]])
echo 'Build and Test has been done'
}
}

Resources