diff --git a/README.adoc b/README.adoc index 7f9839d2e3..4c5afed797 100644 --- a/README.adoc +++ b/README.adoc @@ -997,6 +997,7 @@ GIT_LOCAL_BRANCH:: Name of branch being built without remote name, as in `master GIT_COMMIT:: SHA-1 of the commit used in this build GIT_PREVIOUS_COMMIT:: SHA-1 of the commit used in the preceding build of this project GIT_PREVIOUS_SUCCESSFUL_COMMIT:: SHA-1 of the commit used in the most recent successful build of this project +GIT_COMMIT_TITLE:: The text up to the first blank line in the commit message used in this build [#system-configuration-variables] === System Configuration Variables diff --git a/src/main/java/hudson/plugins/git/GitSCM.java b/src/main/java/hudson/plugins/git/GitSCM.java index d319e47797..16d5f2826f 100644 --- a/src/main/java/hudson/plugins/git/GitSCM.java +++ b/src/main/java/hudson/plugins/git/GitSCM.java @@ -146,6 +146,7 @@ public class GitSCM extends GitSCMBackwardCompatibility { public static final String GIT_LOCAL_BRANCH = "GIT_LOCAL_BRANCH"; public static final String GIT_CHECKOUT_DIR = "GIT_CHECKOUT_DIR"; public static final String GIT_COMMIT = "GIT_COMMIT"; + public static final String GIT_COMMIT_TITLE = "GIT_COMMIT_TITLE"; public static final String GIT_PREVIOUS_COMMIT = "GIT_PREVIOUS_COMMIT"; public static final String GIT_PREVIOUS_SUCCESSFUL_COMMIT = "GIT_PREVIOUS_SUCCESSFUL_COMMIT"; @@ -1352,6 +1353,9 @@ public void checkout(Run build, Launcher launcher, FilePath workspace, Tas // Needs to be after the checkout so that revToBuild is in the workspace try { + String shortMessage = getCommitMessage(listener, git, revToBuild); + listener.getLogger().println("Commit message: \"" + shortMessage + "\""); + environment.put(GIT_COMMIT_TITLE, shortMessage); printCommitMessageToLog(listener, git, revToBuild); } catch (IOException | ArithmeticException | GitException ge) { // JENKINS-45729 reports a git exception when revToBuild cannot be found in the workspace. @@ -1380,14 +1384,27 @@ public void checkout(Run build, Launcher launcher, FilePath workspace, Tas } } - private void printCommitMessageToLog(TaskListener listener, GitClient git, final Build revToBuild) - throws IOException { + /** + * Get the short message from the last commit + * + * @param listener + * Used for writing to build console + * @param git + * Used for invoking Git + * @param revToBuild + * Points to the revision we'll be building. This includes all the branches we've merged. + * + * @return Short message for the commit + * @throws IOException + */ + private String getCommitMessage(TaskListener listener, GitClient git, final Build revToBuild) throws IOException { try { RevCommit commit = git.withRepository(new RevCommitRepositoryCallback(revToBuild)); - listener.getLogger().println("Commit message: \"" + commit.getShortMessage() + "\""); + return commit.getShortMessage(); } catch (InterruptedException | MissingObjectException e) { e.printStackTrace(listener.error("Unable to retrieve commit message")); } + return ""; } /** diff --git a/src/main/resources/hudson/plugins/git/GitSCM/buildEnv.groovy b/src/main/resources/hudson/plugins/git/GitSCM/buildEnv.groovy index e60e30e19a..2f8e00c935 100644 --- a/src/main/resources/hudson/plugins/git/GitSCM/buildEnv.groovy +++ b/src/main/resources/hudson/plugins/git/GitSCM/buildEnv.groovy @@ -3,7 +3,7 @@ package hudson.plugins.git.GitSCM def l = namespace(lib.JenkinsTagLib) // TODO handle GitSCMExtension.populateEnvironmentVariables somehow, say by optionally including GitSCMExtension/buildEnv.groovy; though GIT_{COMMITTER,AUTHOR}_{NAME,EMAIL} are only overridden by UserIdentity -['GIT_COMMIT', 'GIT_PREVIOUS_COMMIT', 'GIT_PREVIOUS_SUCCESSFUL_COMMIT', 'GIT_BRANCH', 'GIT_LOCAL_BRANCH', 'GIT_CHECKOUT_DIR', 'GIT_URL', 'GIT_COMMITTER_NAME', 'GIT_AUTHOR_NAME', 'GIT_COMMITTER_EMAIL', 'GIT_AUTHOR_EMAIL'].each {name -> +['GIT_COMMIT', 'GIT_PREVIOUS_COMMIT', 'GIT_PREVIOUS_SUCCESSFUL_COMMIT', 'GIT_BRANCH', 'GIT_LOCAL_BRANCH', 'GIT_CHECKOUT_DIR', 'GIT_URL', 'GIT_COMMITTER_NAME', 'GIT_AUTHOR_NAME', 'GIT_COMMITTER_EMAIL', 'GIT_AUTHOR_EMAIL', 'GIT_COMMIT_TITLE'].each {name -> l.buildEnvVar(name: name) { raw(_("${name}.blurb")) } diff --git a/src/main/resources/hudson/plugins/git/GitSCM/buildEnv.properties b/src/main/resources/hudson/plugins/git/GitSCM/buildEnv.properties index 100915c95a..94b60fe463 100644 --- a/src/main/resources/hudson/plugins/git/GitSCM/buildEnv.properties +++ b/src/main/resources/hudson/plugins/git/GitSCM/buildEnv.properties @@ -1,6 +1,7 @@ GIT_COMMIT.blurb=The commit hash being checked out. GIT_PREVIOUS_COMMIT.blurb=The hash of the commit last built on this branch, if any. GIT_PREVIOUS_SUCCESSFUL_COMMIT.blurb=The hash of the commit last successfully built on this branch, if any. +GIT_COMMIT_TITLE.blurb=The text up to the first blank line in a commit message is treated as the commit title. GIT_BRANCH.blurb=The remote branch name, if any. GIT_LOCAL_BRANCH.blurb=The local branch name being checked out, if applicable. GIT_CHECKOUT_DIR.blurb=The directory that the repository will be checked out to. This contains the value set in Checkout to a sub-directory, if used. diff --git a/src/test/java/hudson/plugins/git/GitSCMTest.java b/src/test/java/hudson/plugins/git/GitSCMTest.java index 7c16e78c13..91d18bea3e 100644 --- a/src/test/java/hudson/plugins/git/GitSCMTest.java +++ b/src/test/java/hudson/plugins/git/GitSCMTest.java @@ -3064,6 +3064,24 @@ public void testCommitMessageIsPrintedToLogs() throws Exception { assertThat(values, hasItem("Commit message: \"test commit\"")); } + @Test + public void testCommitMessageIsEnvVar() throws Exception { + String title = "test commit"; + sampleRepo.init(); + sampleRepo.write("file", "v1"); + sampleRepo.git("commit", "--all", "--message", title); + FreeStyleProject p = setupSimpleProject("master"); + Run run = rule.buildAndAssertSuccess(p); + TaskListener mockListener = Mockito.mock(TaskListener.class); + Mockito.when(mockListener.getLogger()).thenReturn(Mockito.spy(StreamTaskListener.fromStdout().getLogger())); + + p.getScm().checkout(run, new Launcher.LocalLauncher(listener), + new FilePath(run.getRootDir()).child("tmp-" + "master"), + mockListener, null, SCMRevisionState.NONE); + + assertEquals("Commit message should be an env var", title, getEnvVars(p).get(GitSCM.GIT_COMMIT_TITLE)); + } + /** * Method performs HTTP get on "notifyCommit" URL, passing it commit by SHA1 * and tests for build data consistency.