Child pages
  • Stash pullrequest builder plugin
Skip to end of metadata
Go to start of metadata

Plugin Information

View Stash Pullrequest Builder on the plugin site for more information.

This plugin builds pull requests from an Atlassian Stash instance and will report the test results.

Stash Pull Request Builder Plugin

This Jenkins plugin builds pull requests from an Atlassian Stash server and will report the test results as a comment. This plugin was inspired by the GitHub & BitBucket pull request builder plugins.

Prerequisites

Parameter variables

The plugin makes available to the job the following parameter variables:

* ${sourceBranch}
* ${targetBranch}
* ${sourceRepositoryOwner}
* ${sourceRepositoryName}
* ${pullRequestId}
* ${destinationRepositoryOwner}
* ${destinationRepositoryName}
* ${pullRequestTitle}
* ${sourceCommitHash}

Creating a Job
Source Code Management

Select Git then configure:

  • Repository URL:

    git@example.com:/${destinationRepositoryOwner}/${destinationRepositoryName}.git
  • Advanced -> Refspec:

    +refs/pull-requests/*:refs/remotes/origin/pr/*
  • Branch Specifier:

    origin/pr/${pullRequestId}/from

    Build Triggers

Select Stash Pull Request Builder then configure:

  • Cron: must be specified. eg: every 2 minute H/2 * * * *
  • Stash Host: the http or https URL of the Stash host (NOT ssh). eg: https://example.com
  • Stash Credentials: Select or Add the login username/password for the Stash Host
  • Project: abbreviated project code. eg: PRJ or ~user
  • RepositoryName: eg: Repo

Advanced options

  • Ignore ssl certificates:
  • Build PR targetting only these branches: common separated list of branch names. Blank for all.
  • Rebuild if destination branch changes:
  • Build only if Stash reports no conflicts:
  • Build only if PR is mergeable:
  • CI Skip Phrases: default: "NO TEST"
  • Only build when asked (with test phrase):
  • CI Build Phrases: default: "test this please"

Building the merge of Source Branch into Target Branch

You may want Jenkins to build the merged PR (that is the merge of sourceBranch into targetBranch) to catch any issues resulting from this. To do this change the Branch Specifier from

origin/pr/${pullRequestId}/from

to

origin/pr/${pullRequestId}/merge

If you are building the merged PR you probably want Jenkins to do a new build when the target branch changes. There is an advanced option in the build trigger, "Rebuild if destination branch changes?" which enables this.

You probably also only want to build if the PR was mergeable, and possibly also without conflicts. There are advanced options in the build trigger for both of these.

If you are using the StashNotifier plugin and have enabled the 'Notify Stash Instance' Post-build Action while building the merged PR, you need to set

${sourceCommitHash}

as Commit SHA-1 to record the build result against the source commit.
Notify Stash Instance

If you have enabled the 'Notify Stash Instance' Post-build Action and also enabled the 'Merge before build' extension you need to add '${pullRequestCommit}' as Commit SHA-1. Otherwise you'll notify Stash with the commit hash resulting from the merge which isn't known to Stash (since it's merged locally).

Rerun test builds

If you want to rerun pull request test, write “test this please” comment to your pull request.

Adding additional parameters to a build

If you want to add additional parameters to the triggered build, add comments using the pattern p:<parameter_name>=<value>, one at each line, prefixed with 'p:'. If the same parameter name appears multiple times the latest comment with that parameter will decide the value.

Example:

test this please
p:country=USA
p:env=dev1

Post Build Comment

It is possible to add a post build action that gives the option to post additional information to Stash when a build has been either successful or failed. These comments can contain environment variables that will be translated when posted to Stash.

This feature can be used to post for instance a url to the deployed application or code coverage at a successful build and why the build failed like what tests that did not pass.

Versions

Release notes;

v1.6.0
  • Bug fix - Jenkins issue #30558 - sockets causing problems with hanging triggers
  • Bug fix - include default parameter values in build queue
  • Added project name to log messages
v1.5.3
  • Branch name filters can now be regular expressions
  • Support all build states (now all states are reported, not just success or everything else as failure in the build PR comment)
v1.5.2
  • Fix PR branch filters
v1.5.1
  • Added ability to only keep the most recent PR status comment
  • Logging improvements
  • Ability to limit PR builds to specified target branches only
v1.5.0
  • Added credentials support - this is a breaking change, please add a username/password credential for the user you want PR build comments to be posted from. Old builds will fail until you update them with the right credentials from the credentials plugin. 
  • Fixup branch & ref specs in git config - again this is a breaking change and you should update your git configuration (URL, ref spec & branch specifier), please see the updated README  
v1.4.2
  • Fix bug with Stash response code handling 
v1.4.1
  • Better error handling when Stash returns 200/OK response
  • Added support for custom parameters in the 'test this please' comment
  • Option to ignore SSL certificates (useful if you dont have proper certificates with your Stash instance)
  • Fixes for PR pagination
v1.4.0
  • Added build duration to build finished message in PR - useful for tracking runtimes/test overheads added in PRs. 
  • Improved Stash polling
  • Better JSON handling 
  • Added better support for the notify Stash plugin to only tag the source commit SHA1
  • Bugfixes
v1.3.1
  • Use Git SCM as provider for hostname and credentials needed for the pull request builder
  • Now it is also possible to verify pull requests from another fork (while previously it would only work in the same repository, or at least with the merge before build feature). Prerequisite is that you add +refs/pull-requests/:refs/remotes/origin/pr/ as refspec.
  • Additionally you can filter on the target branch which makes you able to restrict checking pull requests on a specific (release) branch.
  • Support for global environment variables has been added.
v1.2.0
  • Added post build custom comment support
  • Marked credentials plugin as required dependency for upcoming v1.3.0 release with Credentials support
v1.1.0
  • Added ability to customise the build phrase (change from the default of 'test this please')
  • Added ability to only have PR built if its merge-able (i..e has been approved)
  • Added ability to only have PR built if its not conflicted
  • Added check to only build PR on comment (don't auto build) based on build phrase (default is 'test this please')
v1.0.1
  • Fix bug with passing branch names with a '/'
  • Reduce logging verbosity
v1.0.0
  • Initial release

13 Comments

  1. At the moment, each time a new comment is added to the Stash Pull Request, Jenkins is picking it up as a change and re-running the tests.  Is there a configuration that can be updated or set to avoid this?  We only want to re-run the tests if the commit changes.

  2. Is there a way to exclude specific branches by name?

  3. Thanks for the plugin. Just gave it a spin, using it as a trigger to launch another job, which has some complicated default/changeable build params for developers, so it was easier to call it than hack into it.

    A few tricks to note are:

    • I added to that called job's build params a CI_FORK_REPO, CI_FORK_BRANCH and CI_FORK_REFSPEC build param, and referenced them as the git repo, branch and refspec to check out. We actually had the former two in place all over our jobs, inherited when one calls another (mostly we use multiphase in this setup), so developers could run their version of code against "standard conditions" on independent platform (not their workstation) before posting a pull request. The default Repo is one from a selectable list (Extensible list or a Global variable, depending on a job), the branch is a String (defaults to `*master`) and now the refspec is also a string, defaults to empty unless set by this plugin calling that job.
    • I defined a job that does not check out anything by itself, just has the Stash pullrequest builder ticked and fields filled out per article above. As its activity it "Triggers/calls builds on another job" and calls the specified job (and waits for it to finish). Our typical setup adds Build on same node, use same Build parameters (though there are none, at least explicitly, in this stash-poller job), and defines a few parameters for the called job:

      CI_REPO_FORK=ssh://git@stash.hostname.com:7999/${destinationRepositoryOwner}/${destinationRepositoryName}.git
      CI_REPO_REFSPEC=+refs/pull-requests/*:refs/remotes/origin/pr/*
      CI_REPO_BRANCH=origin/pr/${pullRequestId}/from

      Note to NOT use quoting in these definition of values - those quotes propagate to Git client and upset it (wink) Don't forget the "ssh://" schema part, either.

    • The Stash Host is a base URL, not bare hostname, so don't forget to type in the schema ("http://")
    • The credentials for polling Stash REST API are an account and password (for web-interface); credentials for Git over SSH are a ssh-key added to the profile of that same account on Stash. That account is added to the organizations and developers' repos with a right to read. Note that the SSH key added to a profile can not be explicitly added to a project and vice-versa. If you want to access some projects by a dedicated key - it must be a separate key in SSH and credential in Jenkins.
      • Thinking of it, we might use http:// for repo access too... at least to read them. For some reason we do not. 
        UPDATE: tested that we can, and see also the nits below. The corresponding format would be:

        CI_REPO_FORK=http://stash.hostname.com/scm/${destinationRepositoryOwner}/${destinationRepositoryName}.git

        Note that the project names are "as is" (lowercased), and user names are prefixed with a tilde character. Also note that your stack of called jobs would then have to use the HTTP (not ssh-key) credentials to access the repo over this transport, at least if the repo is not marked as publically accessible (otherwise, it can allow anonymous HTTP cloning). If your Stash admins did not block HTTP cloning (which is possible and some recommend), you can enjoy faster checkouts over HTTP, or so they say - in my few tests it was indeed marginally faster, but not enough to be a game-changer by itself.

    • The Jenkins-cron granularity for 1 minute should be specified as an asterisk; the soft-scheduler syntax with `H/1` is not 1 minute but 1 hour, or documented so per long-standing bug (https://issues.jenkins-ci.org/browse/JENKINS-22129 and other posts). The `H/2` is indeed around once every two minutes.
    • "test this please" in comments to the PR is indispensable while tinkering with the recipe on Jenkins side, and unchanged code in Git (wink)
    • I also added a Stash notification plugin as a post-job task, so the Stash PR interface has an icon to report the statistics of PR builds happening and passing or not. Ultimately it can be among automated criteria that the PR can be merged.

    • Per JENKINS-35219 - Getting issue details... STATUS  note to mark Build if PR is mergeable in the polling job config. UPDATE: See the post below for alternative solution, if requiring mergeability is too harsh for your practical use-case.

    One thing slightly missing for ease of integration is a prepopulated variable with the hostname (or URL) that should be passed to Git client - having to type in "ssh://git@example.com", and retype when making jobs for different stashes, is annoying (wink) I posted a bug on this: JENKINS-46605 - Getting issue details... STATUS  (including details of URLs reported back by Stash REST API).

    Another, maybe related to recent security revisions in Jenkins core, is that the job description provided by the plugin (I guess) is posted as verbatim HTML markup of the a-href tag with URL to PR web-interface enclosing the title of the PR. This HTML markup ends up seen in both the Jenkins interface (list of built jobs on the left) and in the notifications posted back to Stash (not the PR comments, but the "X builds failed" summary and the popup that details it).

    • UPDATE: JENKINS-22028 - Getting issue details... STATUS   details about enabling HTML markup in Jenkins Web-GUI, and it works for the job list. The notifications posted back to Stash (not comments) still have the verbatim markup, but that's probably the other plugin's problem.
    1. UPDATE: As an alternative to requiring "Build if PR is mergeable" above (this checkbox indeed avoided testing PRs that were deemed not readily mergeable), or similarly requiring "Build only if Stash reports no conflicts", the issue behind JENKINS-35219 can be worked around by crafting the request ourselves. For this I defined an additional "Execute Shell" step in the PR polling job described above, to be executed before triggering/calling the build on actual job which is the implementation of our test. This new step calls the Stash REST API with the curl (command-line HTTP client; on platforms that do not have it you might use wget as well, or many other equivalent methods to GET an HTTP request) to trigger the lazy-merge attempt (or fail one, does not matter here) so the git refspecs are re-calculated.

      This workaround as described only applies if you have PR poller and actual builder in separate jobs. Otherwise, CI is checked out (with wrong refspec) before the build steps run. An alternative solution is to post the script provided below into "" category, but then you'd have to hardcode the username and password for Stash REST API access, it seems.

      #
      # Workaround for broken git references that appear due to PRs,
      # popping up in other jobs trying to use just the master branch.
      #
      # See https://issues.jenkins-ci.org/browse/JENKINS-35219 and
      # https://community.atlassian.com/t5/Bitbucket-questions/Change-pull-request-refs-after-Commit-instead-of-after-Approval/qaq-p/194702
      
      set +x
      
      echo "Triggering lazy-merge of the PR on stash, by inspecting the special URL..."
      curl -k http://${STASH_USERNAME}:${STASH_PASSWORD}@stash.hostname.com/rest/api/latest/projects/${destinationRepositoryOwner}/repos/${destinationRepositoryName}/pull-requests/${pullRequestId}/merge

      Response from the command should be a meaningful JSON not with an authentication error (smile) In my case it was: 

      {"canMerge":false,"conflicted":false,
       "vetoes":[{"summaryMessage":"Requires approvers","detailedMessage":"You need 1 more approval before this pull request can be merged."}]}

      The login values for curl come from Jenkins credential storage, courtesy of the Credentials Binding Plugin and https://support.cloudbees.com/hc/en-us/articles/203802500-Injecting-Secrets-into-Jenkins-Build-Jobs how-to. In my simpler case, the credential was already stored and used for other REST API calls, and I only had to click Build Environment / Use secret text(s) or file(s), and selected a "Username and password (separated)" which I named STASH_USERNAME and STASH_PASSWORD, and picked the same credential used for the Stash-Jenkins PR integration. Note that if you don't use set +x, Jenkins should replace the credentials by asterisks in the log; but better safe than sorry (wink)

      Note that in our case the credentials are chosen to not upset the URL parser (no special characters that are part of URL markup and must be percent-encoded); you may have to add the encoder into the script above if your passwords use the @:/ and similarly important characters.

  4. What is the difference of this plugin to the bitbucket-pullrequest-builder-plugin?

    Are they solving different problems, is one of them deprecated, or are they just two alternatives created by different authors?

    1. I'd say the primary one is on the tin, per their READMEs, one is for Bitbucket.org (the cloud service), the other is for on-premise Stash instances (later rebranded to Bitbucket name as well). "This plugin was inspired by the GitHub & BitBucket pull request builder plugins." - this likely explains why many configuration variables are named the same.

      There may be functional differences as well (e.g. with Stash PR builder, we can set up the URL to the instance as a global Jenkins config value, and individual PR jobs just use that), not sure if there's something else. Not even sure which one end up in our case to query and build the on-premise Stash we track as an Organization Folder with the Pipeline support - likely that other one. In the end we've kept both older dedicated PR jobs and the new pipeline support active, because Stash PR builder can query the magic Stash REST API to recalculate ephemeral PR branches before build, so they can be resolved as the target (e.g. upstream/master) branch state changes; had some issues without that feature active.

  5. Thanks for the previous answers. I now managed to set up a working Jenkins job that correctly triggers on pull requests.

    However, manually triggering of my job causes a build failure, because the variables ${destinationRepositoryOwner} and ${destinationRepositoryName} are unknown in that case. For example:

    1. build the master branch when triggered manually?
    2. disable manual triggers?
    1. Indeed, same for us. Just don't do it (smile)

      To rebuild a PR (e.g. after sporadic failure in code like race conditions, fixed issue on test-farm's side, updated scripts and other stuff outside the tested branch that can influence the results), go to the open pull request in Stash web-gui and add a comment that includes "test this please" (see above for syntax and additional setup like build arg passing).

  6. Where can I find the jobdsl syntax for this plugin?

  7. Is the use of wildcard supported under "Build PR targetting only these branches"? I could not get this to work.

  8. Guys thanks for the great plugin! Quick question. Is there any way to attach code coverage information as part of this build status comment ? Has anyone done it ?

  9. Please fix getting the Jenkins root URL with the new Jenkins versions. Without the fix, the Stash posts have an error message instead of a link to Jenkins. The pull request is on GitHub: https://github.com/jenkinsci/stash-pullrequest-builder-plugin/pull/27

    1. Note that you can build your own with `mvn package`.

      The HPI I use at work includes I think all or most of the PRs against the jenkins fork and nemccarthy's origin, which is easily done at home with a `git merge` while waiting for upstream to wake up.

      Hope this helps, Jim