How to use Jenkins GitHub Organization Folder with github protected branches? - github

It seems that some updates made in the last two weeks to Jenkins plugins or GitHub api introduce a very strange behaviour on GitHub.
Now we can prevent a PR from being merged if a specific Jenkins branch-job is not green but somehow it seems impossible to check if current PR is green.
If we do not select any branch in github repository configuration Jenkins build will not happen and the user would be able to merge the change.
If we check one of them Jenkins will build it and as a surprise we can see the job name that is matching the PR name. Wonderful, but somehow it seems that the generic check named "Jenkins" is still waiting for another status check, one that will never happen, preventing us from merging.
The last screenshot explains it the best: the named merge is green as expected but we also have another generic one "Jenkins" which is still "Waiting for status to be reported" but nothing is to be reported by Jenkins.

You must set Diplay Name for Github plugin, when it doesn't set, plugin fallbacks to build name.
I didn't find correct way to do this when we use Github Organization plugin with pipeline. And I implemented this by setting project properties from Jenkinsfile:
properties properties: [pipelineTriggers([]), [$class: 'GithubProjectProperty', displayName: 'Jenkins']]
And then set status manually:
step([$class: 'GitHubCommitStatusSetter', statusResultSource: [$class: 'ConditionalStatusResultSource', results: [[$class: 'BetterThanOrEqualBuildResult', message: 'Build success', result: 'SUCCESS', state: 'SUCCESS']]]])
This doesn't remove Jenkins job PR-xxxx status, but it adds Jenkins status wich you can use as required check

Related

Can Azure Devops pipelines, where the build failed, show the user of the last commit when triggered with CI?

I'm doing Visual Studio builds on a self hosted agent, which are currently being triggered by the Continuous Integration setting in an Azure Devops pipeline.
When a build completes, it shows: Triggered by Microsoft.VisualStudio.Services.TFS
It also shows the repository, branch and revision number.
However, it is expected it would show Triggered by , If not showing the correct Azure Devops user, at least showing the Subversion user name, that would be something.
There was an expectation it would be possible to send email notifications to the user of the commit. (Not fool proof that they caused the problem, but the most convenient way to give the responsibility to somebody to make sure any build error gets resolved)
Does anybody know if a solution exists?
In both Classic and yaml pipelines, you can specify a condition for a pipeline step. If you want it to run when the pipeline fails, it will be condition: failed() (in yaml), or Control Options -> Run this task -> Only when a previous task has failed (in Classic). Alternativel, you can check Agent.JobStatus variable.
there's no predefined variable for current committer, but you can easily determine the last commit's author by using svn command, then log it. (any other version control system will have its own CLI that should allow it).
In yaml, it could look like this (using git instead of svn):
steps:
... (your build)
- bash: |
author=`git log -1 --pretty=format:'%ae'` # get last commit author from git
echo "last commiter: $author"
# TODO: send email or other kind of notification
condition: failed()
In classic one:
You are using wrong tool for you task. CI build will be triggered after changes was committed to branch. In that case it is not possible to fix those changes. As a result you will have history where a lot of revisions are not stable.
It might be more suitable for you to use PR policy build. It is designed to validate incoming changes so target branch will be always stable and ready to some deploy. In this case, policy build will be triggered by PR creator so he will be informed about it's result. That can be configured in personal notification settings.
In the end I couldn't Continuous Integration triggers to reliably work. They would always stop working after a short time. I'm surprised I have ran into so many issues with this, but I guess it just isn't that well supported.
Instead, now, I am queue the build via an svn post-commit hook which uses the azure devops REST API.
the REST API has setting, requestedFor":{"id":""}, where you can add the user id (which I also needed a rest api command to find)
A lot of messing around to get to this point, for a feature I expected to 'just work', hopefully this keeps working

Azure Pipelines CI not triggered by pushing tags to external git

I have repository on local GitLab server of my organization and want to trigger build pipeline that then will trigger release pipeline and publish to staging/production VMs.
I've read a lot of articles at microsoft docs, SO and tons of blogs that you can trigger pipeline by tags providing branch filter like refs/tags/v*. YAML configuration has additional section special for tags, however YAML is not supported for git repos that are connected as "Other git".
And that tag trigger just never works. After I set up trigger UI shows me just "v*", so it understands that refs/tags has special meaning. I can run pipeline manually specifying exact tag, like refs/tags/v1.0-test, and it works. But never launches automatically. Branch triggers work without problems.
What I've already tried:
set include filter for refs/tags/v* - doesn't work
set include filter for refs/tags/exacttagname - doesn't work
set include filter for refs/tags/v* and another one for master - triggers only for master
set include filter for refs/tags/v*, for * and exclude filters for refs/heads/* and refs/remotes/* - doesn't work
I tried pushing commit, then pushing tag. Tried pushing commit and tag in one requiest with git push ---follow-tags. Tried pushing tags for older commits. Nothing of that works.
This issue about the same problem was resolved on azure side previous summer, however all comments where about GitHub integrations. So maybe it's still broken for "other git" or smth else.
Any help?
I tested and got the same result, tags triggers for other git doesnot work. You can submit a feature request(click suggest a feature and choose Azure devops) for supporting tag triggers for gitlab repo to Micrsoft Development team. Please check this thread for example.
As workaround you can use multiple agent jobs to achieve above currently.
You can add another agent job before your original agent job to run a script task, And add dependency on it in your original agent job. The script task will check if there is tag associated to the current commit. If the tag exits, the script task will pass, and the following agent job will run. Or the script task fails and the following agent job will be skipped.
The detailed steps is as below:
add a agent job with a single powershell task. Check below screenshot.
Run below inline scripts in the powershell task to check the tags
$tags = git describe --tags $(Build.SourceVersion)
if($($tags) -notmatch 'v.'){exit 1} #fail the task if the tag doesnot match v*
In the original agent job, add dependencies to above agent job.
Go to Triggers tab and filter all branches.

How to auto-reject a pull request if tests are failing (Github actions)

I am doing npm test when pull requests are raised using Github actions.
Now if tests fail,
I would like to add a message,
Or at least, reject the PR using actions.
How can I do this?
I assume you have an on: pull_request workflow that runs npm test. This should automatically create a GitHub Check on the pull request that will fail if your tests fail. The best way to "reject" the pull request is to prevent it from being merged unless the tests pass. You can do this by turning on a setting in your repository to "Require status checks to pass before merging," and selecting your workflow as required.
You can find this setting under your repository's Settings > Branches.
There are further details about these settings in the documentation.
https://help.github.com/en/github/administering-a-repository/enabling-required-status-checks
in status checks bar, type the action name you have defined in your workflow yml file, then merge will check your defined workflow action

Using a jenkins pipeline to build github pull requests

This seems to be one of the more important, but less understood and documented features of GH and Jenkins, which seems to defeat the purpose of CI entirely ...
I'm trying to setup a simple, "kick off a build when a pull request is opened" Job in Jenkins. I've scanned though dozens of posts, some several years old, but have yet to find a solution that actually works, start-to-finish. I'm using GH 2.15.4 and Jenkins 2.89.3 with the GH Pull Request Builder plug-in. I've tried setting up a pipeline job, and a freestyle project, following various "how to" posts and docs. Nothing works as expected. Not even close. I've managed to get some functionality working, but not without a lot of trial-and-error experimenting, which doesn't leave me with a warm-fuzzy in using it. Webhooks are equally worthless in accomplishing what is needed, as nothing seems to fire off a job in Jenkins, regardless of how it is configured.
For starters, are there any references or docs that explain what the following status checks are that are automatically created by Jenkins:
continuous-integration/jenkins/branch
continuous-integration/jenkins/pr-head
continuous-integration/jenkins/pr-merge
Apparently there is no way to delete or edit these ... they just "appear" courtesy of Jenkins. I've seen some discussions, but some explanations contradict one another, so they may just be outdated, inaccurate, etc. I want to know "what does what" so I know which should be 'required' as part of the PR status check.
Any pointers would be appreciated!
I agree, this problem is tricky because Jenkins and its plugins have changed so much throughout the years. Let me tell you how I accomplished what you're asking for. I will post all of my version numbers (mostly up to date).
Jenkins Version: 2.176.1 (java -jar /usr/share/jenkins/jenkins.war --version)
Plugins
github 1.29.4
github-api 1.9
github-branch-source 2.5.3
github-pullrequest 0.2.5
pipeline-github-lib 1.0
Also, I use the Blue Ocean interface, which might affect things (who knows)
blueocean 1.17.0
blueocean-git-pipeline 1.17.0
blueocean-github-pipeline 1.17.0
Github Webhooks
First off, set up webhooks for your system. This is a good guide for Github Webhooks
Go to your Github repository and click on the Settings tab. Then select 'Webhooks' in the left menu:
The URL of my Jenkins setup is https://jenkinsci.dorian.com. So, in the 'Payload URL' box, I put https://jenkinsci.dorian.com/github-webhook/
I left the settings as "application/json" and "send me everything" and "active"
The Webhooks area has a handy 'Recent Deliveries' section which can show you if your webhooks are making it to Jenkins. At first, I had the wrong URL so mine has red Xs next to them. Now, they're all green checkmarks.
Github Access Token
Many guides suggest that you provide Jenkins with a personal access token to communicate with your repo. To do that, go to your account avatar in the top right and select Settings -> Developer Settings -> Personal access tokens->Generate Token
Put whatever you want for the description. Under 'select scopes', if you just want it to work, select every checkbox in the list.
I selected:
repo:status
write:repo_hook
read:repo_hook
admin:org_hook
Click save and you'll be shown your secret key. Copy this somewhere safe (we'll use it soon).
Configuring Jenkins
Now for the hard part. Try and install all of the plugins I've listed above.
Go to Jenkins-Manage Jenkins->Configure System
Locate the Github section and click Add Github Server
Name: Github
Api URL: https://api.github.com
Manage Hooks: true
Under credentials, click "Add." You'll be brought to a menu. Select "Secret Text"
Scope: Global
Secret: paste your access token from earlier
ID: (I left this blank)
Description: DorianGithubCreds
Hit save. Then, select DorianGithubCreds from the credentials list.
To test, hit "Test Connection." Mine returns 'Credentials verified for user dnrahamim', rate limit: 4998
Now go down to Github Pull Request Builder
GitHub Server API URL: https://api.github.com
Jenkins URL override: (blank)
Shared Secret: (blank)
Credentials: DorianGithubCreds
Auto-manage webhooks: true
Everything else is blank
Configure Job
Go to the job that should be building your repo
Select 'Configure' in the left menu
Under Projects->Github Organization
Credentials: DorianGithubCreds
Owner: Dorian
Behaviors:
Discover branches
Strategy: Exclude branches that are also filed as PRs
Discover pull requests from origin
Strategy: Merging the pull request with the current target branch revision
Discover pull requests from forks
Strategy: Merging the pull request with the current target branch revision
Trust: From users with Admin or Write permission
Project Recognizers
Pipeline Jenkinsfile
Path: Jenkinsfile (my Jenkinsfile is in the project root)
Build Strategies: (intentionally blank)
Notifications
Now, when I do a pull request, or whenever I post a change to a pull request, Jenkins run a fresh build for that branch.
The Pull Request itself in Github also lists its "Status Checks" at the bottom. When the build is pending, the status check is yellow. If it succeeds it gets a green checkmark. If it fails, it gets a red X.
I initially had a problem because I had an old Jenkins box which was also configured to manage Github webhooks and build pull requests. Its builds were failing so its notifications were the ones getting through to my pull request. I fixed that problem by preventing that old Jenkins box from building my newest branches. Once the old Jenkins box stopped building, the notifications from the new Jenkins box made it through to Github.
Wrapping up
That's it! That's everything I intentionally configured. Please try out my configuration and see if it works for you. Let me know if I left anything out.
The hard part with configuring Jenkins with Github is that, although there are many guides, the suggestions often conflict with each other and very many are out of date (sometimes even official documentation is out of date).
Nonetheless, here are some Resources:
This is a good guide for Github Webhooks
Github's Whitepaper on CI with Jenkins (It doesn't explain much in detail but it gives a good overview)
Github pull request builder plugin
Semi-official SO post for showing build status on Github repo
GitHub has "add webhook" feature which is accessible in the repository settings --> Webhooks section. This has 4 inputs
1. Payload URl - Enter the Jenkins url
2. Content Type - application/json
3. Secret - this is optional if you want to configure secret
4. Which events would you like to trigger this webhook? - select the option "Let me select individual events"
Bunch of checkbox options are visible, check "Pull requests" option. This option will send a request to Jenkins when Pull request is opened
Next step is create a job in Jenkins which will listen to GitHub events and kick off the build

How to set up a github pull request build in a Jenkinsfile?

So, I've been using Jenkins for quite a while. I have set up numerous projects with the Github Pull Request Builder plugin to run tests whenever someone opens a pull request, and then trigger some other job (build, push, deploy, etc) whenever the pull request actually gets merged to master.
So, is there any way to set this up with a Jenkinsfile, or the organization folders, or the multibranch build deal?
The github-organization-folder plugin in combination with the multi-branch plugin plugin offers exactly this awesome feature: It scans a whole organization (optionally restricted to certain patterns in repo/branch names) for Jenkinsfiles and automatically adds jobs. This also happens for Pull Requests.
Once the PR is closed, it automatically removes the job.
To avoid arbitrary code execution, an organization member has to trigger building the job (same as for the GPRB plugin). The phrase can be configured in the Jenkins System settings.
EDIT: Under the Advanced section in Jenkins, you find options about what types of PR you want to build. If you build fork PRs, then there's afaik no way to prevent running code without prior inspecting it.
An example, how this looks like: