32

I am trying to get a prebuild merge to work inside a multibranch pipeline and I would like to avoid having to hardcode the git url in my pipeline script.

It seems like scm step must store the url somehow, but I cannot figure out how to access it.

BitwiseMan
  • 1,887
  • 13
  • 24
Isaac Stefanek
  • 321
  • 1
  • 3
  • 3

2 Answers2

40

You are correct, the scm object does have the information you need.

When using git as the source control in a Pipeline project (or Multibranch Pipeline project), the scm global variable will be an instance of GitSCM. That means that `scm.getUserRemoteConfigs()' will return a list of UserRemoteConfig instances. Those instances have the git remote's name, url, and refspec. You can iterate over that list to find a matching remote, or just take the first one if your sure you only have one url.

def scmUrl = scm.getUserRemoteConfigs()[0].getUrl()

NOTES

  • RejectedAccessException - The getUserRemoteConfigs and getUrl methods will both throw org.jenkinsci.plugins.scriptsecurity.sandbox.RejectedAccessException until you manually approve them, under "Manage Jenkins -> In-process Script Approval". The only way I've found to do this is to try running the script, have it throw an access exception, approve the one method that caused the exception, and repeat for each method until no more access exceptions are thrown. Happily the setting is server-wide, so you only have to do this once per jenkins controller, not for each pipeline job.

  • GitHub - While testing with a GitHub-sourced multibranch pipeline, getUserRemoteConfigs returned two UserRemoteConfig instances, one for regular branches and another for pull requests. These had the same url so no big deal, but something to keep in mind. For example, in a project using an HTTPS-based connection:

    echo scm.getUserRemoteConfigs()
    
    "[
        +refs/heads/*:refs/remotes/origin/* => https://github.com/bitwiseman/project.git (origin),
        +refs/pull/*/head:refs/remotes/origin/pr/* => https://github.com/bitwiseman/project.git (origin)
    ]"
    
BitwiseMan
  • 1,887
  • 13
  • 24
  • Thanks, this is exactly what I was looking for. – Isaac Stefanek Jul 08 '16 at 22:00
  • 4
    Your answer also made me realize that the url would be available by parsing the ```.git/config``` file. This has the benefit of avoiding the RejectedAccessException problem, but adds more complexity to the build script. – Isaac Stefanek Jul 08 '16 at 22:06
  • where does jenkins get that https URL from? `git remote -v` outputs the SSH URL as expected. I'm rather disappointed at how trivial things like a submodule update need giant workarounds. Multibranch pipeline does not feel ready for prime-time at all... – andsens Sep 13 '17 at 11:17
  • 4
    As of this writing, on my Jenkins instance, the "Approved Signatures" required are as follows: `method hudson.plugins.git.GitSCM getUserRemoteConfigs` `method hudson.plugins.git.UserRemoteConfig getUrl` – rubicks Oct 18 '17 at 18:26
  • @andsens I updated the answer to address your point. If you're using ssh, the output would match. I'm not familiar as familar with the submodule aspects of this area. Have you tried checking on the Jenkins IRC and/or email lists? Also, if you see missing features or bugs, make sure they are filed in the Jenkins project JIRA. That is how folks on the project track what needs improvement. – BitwiseMan Nov 16 '17 at 21:01
  • 1
    If you came here like me looking for the solution for subversion, use `scm.getLocations()[0].getURL()`. https://github.com/jenkinsci/subversion-plugin/blob/master/src/main/java/hudson/scm/SubversionSCM.java – 1800 INFORMATION Aug 08 '19 at 04:49
23

Inspired by a comment in answer by @BitwiseMan, I have found a (hacky) way to get the URL without RejectedAccessException:

checkout scm
def url = sh(returnStdout: true, script: 'git config remote.origin.url').trim()

Please note that it must be done after checkout scm. Basically, you must be in a checked out git repository (i.e. has .git/config file in it)

akhy
  • 5,760
  • 6
  • 39
  • 60
  • 1
    This works. In my case I'm using this to avoid configuring the url within the pom.xml of a maven project. I'd say automatically discovering the url in this way is strictly less hacky than having to maintain the url in the maven project (which can give confusing errors if it is wrong). – drrob Aug 03 '17 at 10:46
  • 2
    It's also possible to capture the output of 'checkout scm" as shown here: https://stackoverflow.com/a/48567672/2896799 – Apteryx Jun 27 '18 at 22:01
  • 1
    It will work the same under Windows by replacing "sh" with "powershell", if you use it. – Raúl Salinas-Monteagudo Jul 18 '19 at 11:21