Jenkinsfile get current tag
Asked Answered
S

8

24

Is there a way to get the current tag ( or null if there is none ) for a job in a Jenkinsfile? The background is that I only want to build some artifacts ( android APKs ) when this commit has a tag. I tried:

env.TAG_NAME

and

binding.variables.get("TAG_NAME")

both are always null - even though this ( https://issues.jenkins-ci.org/browse/JENKINS-34520 ) indicates otherwise

Seductress answered 27/5, 2016 at 16:18 Comment(1)
If you don't mind, would you please explain how to handle the result of tag or null in a Jenkinsfile? I am trying to figure out how to use a git tag if present, or a build number if not.Alembic
P
28

I'd consider returnStdout rather than writing to a file:

sh(returnStdout: true, script: "git tag --sort version:refname | tail -1").trim()

Pandiculation answered 12/10, 2016 at 0:20 Comment(8)
Yep, this is the correct answer, and was present in the documentation at the time I gave my answer.Invention
how can I set a variable equal to that result?Extinguish
also, an easier script is git describe --tags --long --dirty --alwaysExtinguish
@RobWilkinson by just setting a variable i.e def foo = sh(returnStdout: true, script: "git tag --sort version:refname | tail -1").trim()Delirious
This command doesn't return the current tag in the current branch, but the latest tag in general.Romilda
building on @RobWilkinson 's response, git describe has some useful functionality: git describe --tags shows the tag + how many commits since that tag, and a hash id. eg on master, v1.1.0.2-0-gcf75da0 means no commits since v1.1.0.2, on another branch, v1.1.0.2-8-g47938eb means 8 commits since that tag.Pickens
This should not be the accepted answer. It does not do what the OP asked. Instead, the answer by Florian does. git tag --contains or sh(returnStdout: true, script: "git tag --contains").trim()Gefell
This returns the latest tag, not the current tag.Asis
V
34

All the other answers yield an output in any case even if HEAD is not tagged. The question was however to return the current tag and "null" if there is nothing like that.

git tag --contains yields the tag name name if and only if HEAD is tagged.

For Jenkins Pipelines it should look like this:

sh(returnStdout: true, script: "git tag --contains").trim()

Vaporific answered 30/1, 2018 at 14:31 Comment(2)
What's the output if there are multiple tags on HEAD?Degeneracy
Then the git command yields a multiline output. To take multiple tags on HEAD into account you could do something like git tag --contains | head -1.Vaporific
P
28

I'd consider returnStdout rather than writing to a file:

sh(returnStdout: true, script: "git tag --sort version:refname | tail -1").trim()

Pandiculation answered 12/10, 2016 at 0:20 Comment(8)
Yep, this is the correct answer, and was present in the documentation at the time I gave my answer.Invention
how can I set a variable equal to that result?Extinguish
also, an easier script is git describe --tags --long --dirty --alwaysExtinguish
@RobWilkinson by just setting a variable i.e def foo = sh(returnStdout: true, script: "git tag --sort version:refname | tail -1").trim()Delirious
This command doesn't return the current tag in the current branch, but the latest tag in general.Romilda
building on @RobWilkinson 's response, git describe has some useful functionality: git describe --tags shows the tag + how many commits since that tag, and a hash id. eg on master, v1.1.0.2-0-gcf75da0 means no commits since v1.1.0.2, on another branch, v1.1.0.2-8-g47938eb means 8 commits since that tag.Pickens
This should not be the accepted answer. It does not do what the OP asked. Instead, the answer by Florian does. git tag --contains or sh(returnStdout: true, script: "git tag --contains").trim()Gefell
This returns the latest tag, not the current tag.Asis
J
25

The TAG_NAME should work now at least in declarative pipelines.

When condition actually filters on this property. BRANCH_NAME has the same value.

stage('release') {
   when {
     tag 'release-*'
   }
   steps {
     echo "Building $BRANCH_NAME"
     echo "Building $TAG_NAME"
   }
}

See https://jenkins.io/doc/book/pipeline/syntax/#when

Joist answered 3/3, 2020 at 9:28 Comment(1)
MultiBranch Pipelines need Branch Sources configured for the Behavior "Discover tags". jenkins.io/blog/2018/05/16/pipelines-with-git-tagsArmorial
D
11

If the current build is a tag build -- as in, when { buildingTag() } was "true" -- then the (undocumented) environment variable BRANCH_NAME contains the name of the tag being build.

Degeneracy answered 26/2, 2019 at 8:8 Comment(0)
S
6

best way from my site is:

git tag --sort=-creatordate | head -n 1

with:

latestTag = sh(returnStdout:  true, script: "git tag --sort=-creatordate | head -n 1").trim()

Than you can handle with simple regex, for prefix/suffix/version_number what is to do with the tag.

other solution:

git describe --tags --abbrev=0

of course this is the current/latest tag in git. Independent from writing.

sh(returnStdout: true, script: "git describe --tags --abbrev=0").trim()
Slavey answered 5/7, 2019 at 13:11 Comment(1)
I think this is a much better sort option than refname, as it uses git history for determining the most recent tag and not sorting based on tag name.Parochial
A
4

I believe the git command that does what you want is git tag --points-at=HEAD this will list all tags pointing to the current commit or HEAD as it usually called in git. Since HEAD is also the default argument you can also do just git tag --points-at.

The pipeline step for executing and returning the git tags one for each line, then becomes:

sh(returnStdout: true, script: "git tag --points-at")

Annitaanniversary answered 13/6, 2018 at 14:50 Comment(0)
I
1

Returning last tag on current branch, not necessarily on last commit:

sh "git tag --sort version:refname | tail -1 > version.tmp"
String tag = readFile 'version.tmp'
Invention answered 22/8, 2016 at 23:10 Comment(0)
O
1

An example of declarative pipeline following the OP usecase: "do something if this particular commit has a tag attached":

def gitTag = null
pipeline {
  agent any
  stages {
    stage('Checkout') {
      steps {
        checkout(...)
        script {
          gitTag=sh(returnStdout: true, script: "git tag --contains | head -1").trim()
        }
      }
    }
    stage('If tagged') {
      when {
        expression {
          return gitTag;
        }
      }
      steps {
        // ... do something only if there's a tag on this particular commit
      }
    }
  }
}

In my case, I have:

  • one repository for multiple projects
  • each one with their own version tags such as 'MYPROJECT_1.4.23'
  • and I want to use the second part of the tag '1.4.23' to tag my images for example

I need to analyze the current tag to check if it concerns my pipeline project (using a PROJECT_NAME variable per project):

def gitTag = null
def gitTagVersion = null
pipeline {
  agent any
  stages {
    stage('Checkout') {
      steps {
        checkout(...)
        script {
          gitTag=sh(returnStdout: true, script: "git tag --contains | head -1").trim()
          if(gitTag) {
            def parts = gitTag.split('_')
            if( parts.size()==2 && parts[0]==PROJECT_NAME ) {
              gitTagVersion=parts[1]
            }
          }
        }
      }
    }
    stage('If tagged') {
      when {
        expression {
          return gitTagVersion;
        }
      }
      steps {
        // ... do something only if there's a tag for this project on this particular commit
      }
    }
  }
}

Note that I'm new at Jenkins and Groovy and that this may be written more simply/cleanly (suggestions welcome).

(with Jenkins 2.268)

Ongoing answered 12/1, 2021 at 21:56 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.