title: How do I use sh in Jenkins Global library
body: <p>I am creating my own global library for Jenkins, which I have <a href="https://github.com/JoSSte/JenkinsGlobalLibraries" rel="nofollow noreferrer">hosted on github</a>, and to simplify some run-of-the-mill tasks, I wanted to add a function that returns the GIT tag.</p>
  <p>Therefore I created something like this:</p>
  <pre><code>    class Myclass{
        static String getGitTag() {
          return &quot;${sh(returnStdout: true, script: 'git tag --sort version:refname | tail -1').trim()}&quot;
        }
      }
  </code></pre>
  <p>... which results in this error:</p>
  <blockquote>
  <p>No signature of method: static com.stevnsvig.jenkins.release.ReleaseUtil.sh()</p>
  </blockquote>
  <p>So I'm left with two questions:</p>
  <ol>
  <li>Is the solution to import the <code>sh()</code> library that Jenkins' groovy flavor obviously already has imported? (and if so how)</li>
  <li>What is the best practice here? I am wondering why there isn't a <code>GIT_TAG</code> global variable when you use declarative pipelines, and something like this should (in my opinion) be easy as pie.</li>
  </ol>
  <h2>EDIT #1:</h2>
  <pre><code>    static String getGitTag() {
          stdout = script.sh(script: &quot;git tag --sort version:refname | tail -1&quot;, returnStdout: true)
          return stdout.trim()
      }
  </code></pre>
  <p>produces a similar error:</p>
  <blockquote>
  <p>No signature of method: static com.stevnsvig.jenkins.release.ReleaseUtil.sh() is applicable for argument types: (java.util.LinkedHashMap) values: [[returnStdout:true, script:git tag --sort version:refname | tail -1]]</p>
  </blockquote>
  <h2>EDIT #2:</h2>
  <pre><code>   static String getGitTag() {
          def stdout = &quot;git tag --sort version:refname | tail -1&quot;.execute()
          return stdout.in.text
      }
  </code></pre>
  <p>completes, but the output is blank. Running the same command with <code>pwd</code> returns <code>/</code> which indicaes that the environment is not set, which makes sense, since all the commands running under Jenkins are designed to rununder pipelines</p>
  <h2>EDIT #3:</h2>
  <p>I went hunting for the import. Stumbled across the Jenkins CI project on github and started searching the many repositories. <a href="https://github.com/jenkinsci/workflow-durable-task-step-plugin/blob/master/src/main/java/org/jenkinsci/plugins/workflow/steps/durable_task/ShellStep.java" rel="nofollow noreferrer">Found a promising one</a>... and put a file called <code>pwd.groovy</code> in <code>/vars</code> with this content:</p>
  <pre><code>import org.jenkinsci.plugins.workflow.steps.durable_task.ShellStep
  
  
      static String getPWD() {
          def ret = ShellStep.sh(returnStdout: true, script: &quot;git tag --sort version:refname | tail -1&quot;).trim()
          echo &quot;currently in ${ret}&quot;
      }
  </code></pre>
  <p>The error I got is a variation of the same. I guess since itsa plugin, the definition is different...</p>
  <blockquote>
  <p>hudson.remoting.ProxyException: groovy.lang.MissingMethodException: No signature of method: static org.jenkinsci.plugins.workflow.steps.durable_task.ShellStep.sh() is applicable ...</p>
  </blockquote>