Jenkins : Last Changes Plugin

Plugin Information

View Last Changes on the plugin site for more information.

The simplest way to know what has changed on your Jenkins builds!.

Introduction

The plugin uses diff2html to show last changes of a given build via VCS diffs, example:


Or using side-by-side configuration:



Last changes means compare current repository revision with an old revision. By default the plugin will diff current and previous revision.

Only Git and Svn based projects are supported. 

Objectives

The main objective of this plugin is to have fast access to what has changed on a Jenkins build.
Another interesting aspect is that it can easily help to find the root cause of a failling build by highlighting what has changed.

And finally the plugin shines in a continuous delivery environment, where each commit generates a release candidate.

How it works?

  1. This plugin expects .git or .svn folders present on your build workspace and will use it to retrieve repository information .

  2. While your job runs the plugin reads your build workspace to retrieve the current VCS revision;

  3. The diff between actual and a previous revision will be stored; Note that the previous revision can be:

    • A provided revision id;

    • Revision of Last successful build;

    • Revision of an specific build;
    • Revision of Last tag;


      By default previous revision is current revision -1.



      You can use parameters in specificRevision parameter. In case of git, expressions like HEAD^{tree}or HEAD^^ can be used.
  4. The diff for each build can be viewed later in html format.

To get most from this plugin use periodically SCM pooling to trigger your builds, more details here.

The plugin always compare current revision with previous one even no new commit has been made. Since version 1.0.7 it is possible to provide a specific revision.

Usage

After installation, activate the post build action Publish Last Changes. 

Activate post build action

Last changes menu

Last changes menu will be available after job execution:

The job level menu will take you to Last changes history.

Build changes history

Each link will take you to the changes of the build: 

View Last changes menu

At the build level, View Last Changes menu is available for builds that published changes. It will also take you to the changes published by the build

View changes published by builds

Finally, you can view what has changed on the build: 

commits


You can also see what has changed on a specific commit by clicking on it:


commit changes



Configuration

The setup is done via build configuration:


The possible values for Since attribute is Previous revision (the default), Last successful build and Last tag.


If SpecificRevision parameter is provided then Since configuration will be ignored and the diff will be done with provided revision id.


Advanced configuration reflects diff2html options:


last changes config2

Jenkins pipeline step


Following is an example of pipeline step using this plugin:

node {
      stage ('Build') {
           svn 'https://subversion.assembla.com/svn/cucumber-json-files/trunk/'
           step([$class: 'LastChangesPublisher', since:'PREVIOUS_REVISION',specificRevision: '', format: 'LINE', matchWordsThreshold: '0.25', matching: 'NONE', matchingMaxComparisons: '1000', showFiles: true, synchronisedScroll: true])

      }

}

Pipeline DSL

Following are examples of pipeline dsl usage:


node {
     git 'https://github.com/jenkinsci/last-changes-plugin.git'
     lastChanges() //will use defaults
}


Parameters should be declared as key: 'value' as example below:


node {
     git 'https://github.com/jenkinsci/last-changes-plugin.git'
     lastChanges format:'SIDE',matching: 'WORD', specificRevision: 'c546ec31e854de3f27755273d3e1db6185aee4b4'
}


pipeline {
    agent any
    stages {
        stage('Checkout') {
            steps {
                git 'https://github.com/jenkinsci/last-changes-plugin.git'
                lastChanges since: 'LAST_SUCCESSFUL_BUILD', format:'SIDE',matching: 'LINE'
            }
        }
    }
}


Or using build params for specificRevision:


pipeline {
    agent any
    stages {
        stage('Checkout') {
            steps {
                git 'https://github.com/jenkinsci/last-changes-plugin.git'
                lastChanges format:'SIDE',matching: 'WORD', specificRevision: "${REV}"
            }
        }
    }
}


Refer to parameterized builds to use parameters.


Pipeline scripting

It is possible to invoke LastChanges inside groovy script, instead of just declaring it as we saw above. See example below:


node {
      stage("checkout") {
        git url: 'https://github.com/jenkinsci/last-changes-plugin.git'
      }

      stage("last-changes") {
        def publisher = LastChanges.getLastChangesPublisher "PREVIOUS_REVISION", "SIDE", "LINE", true, true, "", "", "", "", ""
              publisher.publishLastChanges()
              def changes = publisher.getLastChanges()
              println(changes.getEscapedDiff())
              for (commit in changes.getCommits()) {
                  println(commit)
                  def commitInfo = commit.getCommitInfo()
                  println(commitInfo)
                  println(commitInfo.getCommitMessage())
                  println(commit.getChanges())
              }
      }

}


See model classes to know what can be accessed in pipeline script. Note that only attributes annotated with @Whitelisted are visible to be accessed in pipeline script.



If you use declarative pipeline you can use script section.


SVN Limitation

Svn based jobs have a limitation, to get last changes from latest tag you need to checkout the entire project repository otherwise the plugin will not find last tag. This is due to the way SVN handle tags.

Download the diff

You can also download the diff as DIFF or HTML. The download links are at the bottom right of the page:

Sending the diff as email

Using email ext plugin and pipeline scripting we can send the diff as an email attachment, see example below:

  1. Diff in plain text

    pipeline {
        agent any
        stages {
            stage('send diff') {
                steps {
                    git url: 'https://github.com/jenkinsci/last-changes-plugin'
                }
            }
            stage("send diff") {
                steps {
                    script {
                        def publisher = LastChanges.getLastChangesPublisher null, "SIDE", "LINE", true, true, "", "", "", "", ""
                        publisher.publishLastChanges()
                        def diff = publisher.getDiff()
                        writeFile file: 'build.diff', text: diff
                        emailext (
                          subject: "Jenkins - changes of ${env.JOB_NAME} #${env.BUILD_NUMBER}",
                          attachmentsPattern: '**/*.diff',
                          mimeType: 'text/html',
                          body: """<p>See attached diff of <b>${env.JOB_NAME} #${env.BUILD_NUMBER}</b>.</p>
                            <p>Check build changes on Jenkins <b><a href="${env.BUILD_URL}/last-changes">here</a></b>.</p>""",
                          to: "YOUR-EMAIL@gmail.com"
                        )
    
                   }
    
                }
            }
        }
    }


  2. Diff in Html format

    pipeline {
        agent any
        stages {
            stage('send html diff') {
                steps {
                    git 'https://github.com/jenkinsci/last-changes-plugin.git'
                    script {
                      def publisher = LastChanges.getLastChangesPublisher "PREVIOUS_REVISION", "SIDE", "LINE", true, true, "", "", "", "", ""
                      publisher.publishLastChanges()
                      def htmlDiff = publisher.getHtmlDiff()
                      writeFile file: 'build-diff.html', text: htmlDiff
                        emailext (
                          subject: "Jenkins - changes of ${env.JOB_NAME} #${env.BUILD_NUMBER}",
                          attachmentsPattern: '**/*build-diff.html',
                          mimeType: 'text/html',
                          body: """<p>See attached diff of build <b>${env.JOB_NAME} #${env.BUILD_NUMBER}</b>.</p>
                            <p>Check build changes on Jenkins <b><a href="${env.BUILD_URL}/last-changes">here</a></b>.</p>""",
                          to: "YOUR-EMAIL@gmail.com" )
                    } //end script
                }
            }
        }
    }

Docker

An easy way to test this plugin is using a docker container, here are the steps (assumming you have docker installed):

  1. Run the image: docker run -it -p 8080:8080 rmpestano/jenkins-last-changes
  2. Access http://localhot:8080/ and create a job
  3. Configure this svn repository: https://subversion.assembla.com/svn/cucumber-json-files/trunk/
  4. Add the Publish last changes post build action;
  5. Just run the job

Job output should look like:

Contributing

See contributors guide.

Change Log

Version 2.7.6 (aug 14, 2019) 
Version 2.7.5 (apr 25, 2019) 
  • Performance: Also compress commit diffs bigger than 250kb.
Version 2.7.4 (apr 05, 2019) 
  • Performance: Diffs bigger than 250kb will be compressed to not consume too much memory on Jenkins.

    The 250kb can be configured using SystemProperty: lastchanges.diff.compress-threshold=500 will make only diffs bigger than 500kb to be compressed.

Version 2.7.2/2.73 (apr 03, 2019) 
  • Prevent NPE on html diff download

Version 2.7.1 (apr 03, 2019) 
  • #65 - Add previous and current revision information on html diff download
Version 2.7.0 (apr 02, 2019) 
  • #48 - VCS dir should only be deleted if it was copied before
  • Support for sending html diffs as email attachments
  • Upgrade base line to 2.73.3
  • Update test dependencies to support declarative pipeline in integration tests
Version 2.6.8 (oct 01, 2018) 
Version 2.6.7 (sep 10, 2018) 
  • #58 - Serialization issues in pipeline script section
  • #59 - Adjust css on downloaded diff html
Version 2.6.6 (sep 09, 2018) 
  • #57 - Download the diff as HTML
Version 2.6.5 (sep 09, 2018) 
  • #53Make it possible to download the diff in 'diff' format (so it can be viewed later on https://diffy.org/ )

  • #56 - Could not load actions from com.github.jenkins.lastchanges.LastChangesProjectAction

Version 2.6.4 (sep 03, 2018) 
  • #55 - LastChanges icon is rendered for all jobs
Version 2.6.3 (sep 01, 2018) 
  • JENKINS-50116 - LastChanges history becomes empty after Jenkins restart
  • #50 - Upgrade to diff2html 2.4.0
  • #51 - Upgrade Jenkins baseline to 2.x
Version 2.6.2 (apr 05, 2018)
Version 2.6.1 (mar 11, 2018)
Version 2.6 (jan 26, 2018)
Version 2.5 (jan 10, 2018)
  • #36 Remove unnecessary call to commitInfo
  • #37 Makes LastChanges available in pipeline script (PR #38)
  • #39 Spelling
  • #40 Use Jenkins 1.642 as baseline to enable pipeline testing

See release notes for more details.

Version 2.4 (dez 26, 2017)
  • #35 Wrong diff of specific commit in git repositories
Version 2.3 (dez 17, 2017)
  • #32 Changes since specific build.
  • #33 findVCSDir researches only one, first folder from workspace.
  • #34 Show the list of commits between current and previous revision.
Version 2.2 (nov 16, 2017)

#29 Cleaning vcs dir after the diff is created
#30 'null' revision in SVN

Version 2.1 (nov 03, 2017)

Fixes SVN authentication issue.

The fix for issue #25 introduced an auth issue for some private repositories:

 org.tmatesoft.svn.core.SVNAuthenticationException: svn: E170001: Authentication required for '<secret> Authorization Realm
Version 2.0 (nov 02, 2017)

#25 SVN changes are retrieved locally now. Before it, repository info was retrieved remotelly from build trigger and there was some serious issues like #4;
#26 Last Changes since Last tag;
#27 The UI and also pipeline DSL attributes has changed.

Breaking changes

sinceLastSuccessfulBuild atribute was removed;
previousRevision was renamed to SpecificRevision

A new attribute Since was added, the possible values are:

  • PREVIOUS_REVISION (default)
  • LAST_SUCCESSFUL_BUILD
  • LAST_TAG
Version 1.1.4 (oct 31, 2017)
  • #24 Skip SCM verification for GIT repositories.
Version 1.1.3 (oct 31, 2017)
  • Bad release, do not use this version.
Version 1.1.2 (oct 30, 2017)
  • #22 NullPointerException when using sinceLastSuccessfulBuild
  • #23 Make workflow-job dependency optional
Version 1.1.1 (oct 28, 2017)
  • #20 Allow git expressions in previous revision field

  • #21 Better error message

Version 1.1.0 (oct 29, 2017)
  • #16 Rename "End revision" to "Previous revision" as it is causing confusion

  • #17 Mismatched heading in side-by-sude revision summary

  • #18 Rename lastSuccessfulBuild to sinceLastSuccessfulBuild

  • #19 Switch current and previous revision summary panel

Version 1.0.12 (oct 28, 2017)
  • #14 Updates to latest DiffToHtml

  • #15 Support for diff against last successful build

Version 1.0.11 (oct 13, 2017)
  • #11 Support parameterized repository url for SVN builds. 

Version 1.0.10 (aug 13, 2017)
  • #8 Simplifies pipeline script execution.

Version 1.0.9 (aug 11, 2017)
  • #6 EndRevision input is replaced when using Environment Variables
  • #7 Javascript error when there is no change between revisions
Version 1.0.8 (aug 10, 2017)
  • #5 Support environment variables in endRevision
Version 1.0.7 (jul 15, 2017)
  • #1 - Updates to latest diff2html - 2.3.0
  • #2 - Support for Jenkins 2 pipelines
  • #3 - Ability to diff to an specific revision
Version 1.0.6 (may 8, 2017)
  • Fixes SVN diff which was in inverse order.
Version 1.0.3 (jul 27, 2016)
Version 1.0.2 (jul 26, 2016)
Version 1.0.1 (jul 15, 2016)
Version 1.0.0 (jul 14, 2016)
  • Initial release

Attachments:

config01.png (image/png)
config.png (image/png)
config02.png (image/png)
initial.png (image/png)
all-docs.png (image/png)
all-docs2.png (image/png)
all-docs3.png (image/png)
cukedoctor-sample.png (image/png)
job-output.png (image/png)
doc-sample.png (image/png)