Skip to content

Commit 25ca71b

Browse files
rhit-gawronjarhit-inskeedaUltimateGeekMarkEWaite
authored
[JENKINS-4162] Optionally report the most recent commit as the changelog of a new build (#1565)
* Add files via upload * code for gui * trait file * gitscm changes * testing for new trait behavior * null check time * update to proper version number Co-authored-by: UltimateGeek <10050028+UltimateGeek@users.noreply.github.com> * Update FirstBuildChangelogTrait Removed improper CloudBees copyright documentation, updated @param for the constructor * Format new files with spotless:apply Use line termination that is consistent with the other files in the repository. Use import ordering as defined by spotless. * Remove trailing space characters * Changed equals to use proper equals method * Changed equals to use proper equals method * Changed equals to use proper equals method * changed to compatible equal * Fix Mark's poor code review * Use leading lower case letter for the symbol Jenkins symbol names consistently start with a lower case letter. * Use sentence case for display name * Set API release to 5.3.0 * removed groovy and checkbox * Update to documentation and applying spotless * Pushing documentation image * Undo spotless changes - not ready for spotless * Reduce doc diffs * Use Unix file format for help * Jenkins Pipeline symbols start with a lower case letter * Remove blank line from doc example * First build changelog reports most recent commit as changelog The new extension reports the most recent commit as the changelog. It does not report the changes from a base branch, because there is no reliable method to identify the base branch from command line git. Also adjusts capitalization to be consistent with other parts of the documentation. * Format new example same as prior examples. * Clarify first build option help and docs * Remove comment as suggested by reviewer --------- Co-authored-by: Derek Inskeep <77685829+rhit-inskeeda@users.noreply.github.com> Co-authored-by: UltimateGeek <10050028+UltimateGeek@users.noreply.github.com> Co-authored-by: Mark Waite <mark.earl.waite@gmail.com> Co-authored-by: Derek Inskeep <inskeeda@rose-hulman.edu>
1 parent a2b54b1 commit 25ca71b

File tree

7 files changed

+175
-3
lines changed

7 files changed

+175
-3
lines changed

README.adoc

+17
Original file line numberDiff line numberDiff line change
@@ -1220,6 +1220,23 @@ Inverse::
12201220
This is useful, for example, when you have jobs building your master and various release branches and you want a second job which builds all new feature branches.
12211221
For example, branches which do not match these patterns without redundantly building master and the release branches again each time they change.
12221222

1223+
[#first-build-changelog]
1224+
==== First build changelog
1225+
1226+
image:/images/git-extension-for-first-build.png[First build changelog]
1227+
1228+
The Jenkins git plugin provides an option to trigger a Pipeline build on the first commit on a branch.
1229+
By default, no changelog is generated for the first build because the first build has no predecessor build for comparison.
1230+
When the first build changelog option is enabled, the most recent commit will be used as the changelog of the first build.
1231+
1232+
[source,groovy]
1233+
----
1234+
checkout scmGit(
1235+
branches: [[name: 'master']],
1236+
extensions: [ firstBuildChangelog() ],
1237+
userRemoteConfigs: [[url: 'https://github.com/jenkinsci/git-plugin.git']])
1238+
----
1239+
12231240
[#merge-extensions]
12241241
=== Merge Extensions
12251242

9.51 KB
Loading

src/main/java/hudson/plugins/git/GitSCM.java

+9-3
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import hudson.plugins.git.extensions.impl.BuildSingleRevisionOnly;
2929
import hudson.plugins.git.extensions.impl.ChangelogToBranch;
3030
import hudson.plugins.git.extensions.impl.CloneOption;
31+
import hudson.plugins.git.extensions.impl.FirstBuildChangelog;
3132
import hudson.plugins.git.extensions.impl.PathRestriction;
3233
import hudson.plugins.git.extensions.impl.LocalBranch;
3334
import hudson.plugins.git.extensions.impl.RelativeTargetDirectory;
@@ -1493,9 +1494,14 @@ private void computeChangeLog(GitClient git, Revision revToBuild, TaskListener l
14931494
}
14941495

14951496
if (!exclusion) {
1496-
// this is the first time we are building this branch, so there's no base line to compare against.
1497-
// if we force the changelog, it'll contain all the changes in the repo, which is not what we want.
1498-
listener.getLogger().println("First time build. Skipping changelog.");
1497+
FirstBuildChangelog firstBuildChangelog = getExtensions().get(FirstBuildChangelog.class);
1498+
if (firstBuildChangelog != null && firstBuildChangelog.isMakeChangelog()) {
1499+
changelog.to(out).max(1).execute();
1500+
executed = true;
1501+
listener.getLogger().println("First time build. Latest changes added to changelog.");
1502+
} else {
1503+
listener.getLogger().println("First time build. Skipping changelog.");
1504+
}
14991505
} else {
15001506
changelog.to(out).max(MAX_CHANGELOG).execute();
15011507
executed = true;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
package hudson.plugins.git.extensions.impl;
2+
3+
import hudson.Extension;
4+
import hudson.plugins.git.extensions.GitSCMExtension;
5+
import hudson.plugins.git.extensions.GitSCMExtensionDescriptor;
6+
import java.util.Objects;
7+
import org.jenkinsci.Symbol;
8+
import org.kohsuke.stapler.DataBoundConstructor;
9+
import org.kohsuke.stapler.DataBoundSetter;
10+
11+
/**
12+
* First Build generates a changelog.
13+
*
14+
* @author Derek Inskeep
15+
*/
16+
public class FirstBuildChangelog extends GitSCMExtension {
17+
private boolean makeChangelog;
18+
19+
@DataBoundConstructor
20+
public FirstBuildChangelog() {
21+
makeChangelog = true;
22+
}
23+
24+
public boolean isMakeChangelog() {
25+
return makeChangelog;
26+
}
27+
28+
@DataBoundSetter
29+
public void setMakeChangelog(boolean makeChangelog) {
30+
this.makeChangelog = makeChangelog;
31+
}
32+
33+
/**
34+
* {@inheritDoc}
35+
*/
36+
@Override
37+
public boolean equals(Object o) {
38+
if (this == o) {
39+
return true;
40+
}
41+
if (o == null || getClass() != o.getClass()) {
42+
return false;
43+
}
44+
FirstBuildChangelog that = (FirstBuildChangelog) o;
45+
return makeChangelog == that.makeChangelog;
46+
}
47+
48+
/**
49+
* {@inheritDoc}
50+
*/
51+
@Override
52+
public int hashCode() {
53+
return Objects.hash(makeChangelog);
54+
}
55+
56+
/**
57+
* {@inheritDoc}
58+
*/
59+
@Override
60+
public String toString() {
61+
return "FirstBuildChangelog{" + "makeChangelog=" + makeChangelog + '}';
62+
}
63+
64+
@Extension
65+
@Symbol("firstBuildChangelog")
66+
public static class DescriptorImpl extends GitSCMExtensionDescriptor {
67+
68+
/**
69+
* {@inheritDoc}
70+
*/
71+
@Override
72+
public String getDisplayName() {
73+
return "First build changelog";
74+
}
75+
}
76+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package jenkins.plugins.git.traits;
2+
3+
import edu.umd.cs.findbugs.annotations.CheckForNull;
4+
import hudson.Extension;
5+
import hudson.plugins.git.extensions.impl.FirstBuildChangelog;
6+
import jenkins.scm.api.trait.SCMSourceTrait;
7+
import org.jenkinsci.Symbol;
8+
import org.kohsuke.stapler.DataBoundConstructor;
9+
10+
/**
11+
* Exposes {@link FirstBuildChangelog} as a {@link SCMSourceTrait}.
12+
*
13+
* @since 5.3.0
14+
*/
15+
public class FirstBuildChangelogTrait extends GitSCMExtensionTrait<FirstBuildChangelog> {
16+
17+
/**
18+
* @deprecated Use constructor that accepts extension instead.
19+
*/
20+
@Deprecated
21+
public FirstBuildChangelogTrait() {
22+
this(null);
23+
}
24+
25+
/**
26+
* Stapler constructor.
27+
*
28+
* @param extension the option to force first build to have a non-empty changelog.
29+
*/
30+
@DataBoundConstructor
31+
public FirstBuildChangelogTrait(@CheckForNull FirstBuildChangelog extension) {
32+
super(extension == null ? new FirstBuildChangelog() : extension);
33+
}
34+
35+
/**
36+
* Our {@link hudson.model.Descriptor}
37+
*/
38+
@Extension
39+
@Symbol("firstBuildChangelog")
40+
public static class DescriptorImpl extends GitSCMExtensionTraitDescriptor {
41+
/**
42+
* {@inheritDoc}
43+
*/
44+
@Override
45+
public String getDisplayName() {
46+
return "First Build Changelog";
47+
}
48+
}
49+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<div>
2+
First builds will populate the changelog with the latest commit, if any, to allow Pipelines to check and test for file changes.
3+
By default, no changelog is generated for the first build because the first build has no predecessor build for comparison.
4+
When the first build changelog option is enabled, the most recent commit on the branch will be used as the changelog of the first build.
5+
</div>

src/test/java/hudson/plugins/git/GitSCMTest.java

+19
Original file line numberDiff line numberDiff line change
@@ -1188,6 +1188,25 @@ public void testCleanBeforeCheckout() throws Exception {
11881188
assertThat("Cleaning should happen before fetch", cleaningLogLine, is(lessThan(fetchingLogLine)));
11891189
}
11901190

1191+
@Test
1192+
public void testFirstBuiltChangelog() throws Exception {
1193+
assumeTrue("Test class max time " + MAX_SECONDS_FOR_THESE_TESTS + " exceeded", isTimeAvailable());
1194+
FreeStyleProject p = setupProject("master", false, null, null, "Jane Doe", null);
1195+
FirstBuildChangelog fbc = new FirstBuildChangelog();
1196+
((GitSCM) p.getScm()).getExtensions().add(fbc);
1197+
1198+
/* First build should should generate a changelog */
1199+
final String commitFile1 = "commitFile1";
1200+
commit(commitFile1, johnDoe, janeDoe, "Commit number 1");
1201+
final FreeStyleBuild firstBuild = build(p, Result.SUCCESS, commitFile1);
1202+
assertThat(firstBuild.getLog(50), hasItem("First time build. Latest changes added to changelog."));
1203+
/* Second build should have normal behavior */
1204+
final String commitFile2 = "commitFile2";
1205+
commit(commitFile2, johnDoe, janeDoe, "Commit number 2");
1206+
final FreeStyleBuild secondBuild = build(p, Result.SUCCESS, commitFile2);
1207+
assertThat(secondBuild.getLog(50), not(hasItem("First time build. Latest changes added to changelog.")));
1208+
}
1209+
11911210
@Issue("JENKINS-8342")
11921211
@Test
11931212
public void testExcludedRegionMultiCommit() throws Exception {

0 commit comments

Comments
 (0)