13

As in subject - is there any way to verify if current build is effect of using 'Replay' button?

Marcello DeSales
  • 21,361
  • 14
  • 77
  • 80
hi_my_name_is
  • 4,894
  • 3
  • 34
  • 50
  • Looking for the same answer... Maybe through the initial description? @freakman have you found anything? – Marcello DeSales Sep 11 '18 at 19:00
  • I haven't found any flag/variable. In our solution job was ran automatically when some change was pushed to git - so 'currentBuild.changeSets' was not empty. Notice that when you use 'replay' currentBuild.changeSets' is not filled. It may be indication for you that job was replayed. – hi_my_name_is Sep 12 '18 at 08:00
  • that's exactly the same I have observed! Thank you! Let me try that! – Marcello DeSales Sep 12 '18 at 18:58
  • I'm taking it back... I constantly see it being filled with the changes... :( Still looking for an answer :( – Marcello DeSales Sep 12 '18 at 19:50
  • 1
    wow, you are lucky - I was hoping to have those changes even when it's replay :D. Maybe there is some difference when other version / plugins are used. Thank you for getting back with solution below. – hi_my_name_is Sep 13 '18 at 07:11
  • Yeah, I'm using it as a step condition!!! It works like a charm! – Marcello DeSales Sep 13 '18 at 07:41

1 Answers1

13

I found the following solution using the rawBuild instance from currentBuild. Since we can't get the class of the causes, we just verify its string value.

def replayClassName = "org.jenkinsci.plugins.workflow.cps.replay.ReplayCause​"
def isReplay = currentBuild.rawBuild.getCauses().any{ cause -> cause.toString().contains(replayClassName) }

This solution works for Jenkins with Blue-Ocean. References to how to get to this answer is Jenkins declarative pipeline: find out triggering job

Update

Using this a step condition works like a charm!

You can define a shared library like jenkins.groovy

def isBuildAReplay() {
  // https://stackoverflow.com/questions/51555910/how-to-know-inside-jenkinsfile-script-that-current-build-is-an-replay/52302879#52302879
  def replyClassName = "org.jenkinsci.plugins.workflow.cps.replay.ReplayCause"
  currentBuild.rawBuild.getCauses().any{ cause -> cause.toString().contains(replyClassName) }
}

You can reuse it in a Jenkins pipeline

stage('Conditional Stage') {
  when {
    expression { jenkins.isBuildAReplay() }
  }
  steps {
    ...
    ...
  }
}
Marcello DeSales
  • 21,361
  • 14
  • 77
  • 80
  • This is really helpful, thanks! I would avoid casting the cause to a string though, you can just do: `cause instanceof org.jenkinsci.plugins.workflow.cps.replay.ReplayCause` – Aaron Mar 18 '19 at 05:55
  • To avoid a script approval using rawBuild and getCauses, in "Pipeline: Supporting APIs" >2.22, you can use the following function that returns a list of JSON objects, `currentBuild.getBuildCauses("org.jenkinsci.plugins.workflow.cps.replay.ReplayCause")` – KymikoLoco Mar 23 '20 at 16:03