Skip to content

Commit

Permalink
JENKINS-68822 added support for removing all builds with LogRotator
Browse files Browse the repository at this point in the history
  • Loading branch information
madisparn committed Jun 20, 2024
1 parent 7d5b8ec commit 3bc4ff1
Show file tree
Hide file tree
Showing 4 changed files with 96 additions and 7 deletions.
5 changes: 4 additions & 1 deletion core/src/main/java/hudson/tasks/ArtifactArchiver.java
Original file line number Diff line number Diff line change
Expand Up @@ -389,7 +389,10 @@ public boolean isApplicable(Class<? extends AbstractProject> jobType) {
if (bd instanceof LogRotator) {
LogRotator lr = (LogRotator) bd;
if (lr.getArtifactNumToKeep() == -1) {
p.setBuildDiscarder(new LogRotator(lr.getDaysToKeep(), lr.getNumToKeep(), lr.getArtifactDaysToKeep(), 1));
LogRotator newLr = new LogRotator(lr.getDaysToKeep(), lr.getNumToKeep(), lr.getArtifactDaysToKeep(), 1);
newLr.setRemoveLastSuccessfulBuild(lr.isRemoveLastSuccessfulBuild());
newLr.setRemoveLastStableBuild(lr.isRemoveLastStableBuild());
p.setBuildDiscarder(newLr);

Check warning on line 395 in core/src/main/java/hudson/tasks/ArtifactArchiver.java

View check run for this annotation

ci.jenkins.io / Code Coverage

Not covered lines

Lines 392-395 are not covered by tests
} else {
LOG.log(Level.WARNING, "will not clobber artifactNumToKeep={0} in {1}", new Object[] {lr.getArtifactNumToKeep(), p});
}
Expand Down
37 changes: 34 additions & 3 deletions core/src/main/java/hudson/tasks/LogRotator.java
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
import jenkins.util.io.CompositeIOException;
import org.jenkinsci.Symbol;
import org.kohsuke.stapler.DataBoundConstructor;
import org.kohsuke.stapler.DataBoundSetter;

/**
* Default implementation of {@link BuildDiscarder}.
Expand Down Expand Up @@ -108,6 +109,18 @@ public CollatedLogRotatorException(String msg, Collection<Exception> values) {
*/
private final Integer artifactNumToKeep;

/**
* If enabled also remove last successful build.
* @since 2.464
*/
private boolean removeLastSuccessfulBuild;

/**
* If enabled also remove last stable build.
* @since 2.464
*/
private boolean removeLastStableBuild;

@DataBoundConstructor
public LogRotator(String daysToKeepStr, String numToKeepStr, String artifactDaysToKeepStr, String artifactNumToKeepStr) {
this (parse(daysToKeepStr), parse(numToKeepStr),
Expand Down Expand Up @@ -140,6 +153,16 @@ public LogRotator(int daysToKeep, int numToKeep, int artifactDaysToKeep, int art

}

@DataBoundSetter
public void setRemoveLastSuccessfulBuild(boolean removeLastSuccessfulBuild) {
this.removeLastSuccessfulBuild = removeLastSuccessfulBuild;
}

@DataBoundSetter
public void setRemoveLastStableBuild(boolean removeLastStableBuild) {
this.removeLastStableBuild = removeLastStableBuild;
}

@Override
@SuppressWarnings("rawtypes")
public void perform(Job<?, ?> job) throws IOException, InterruptedException {
Expand All @@ -148,9 +171,9 @@ public void perform(Job<?, ?> job) throws IOException, InterruptedException {

LOGGER.log(FINE, "Running the log rotation for {0} with numToKeep={1} daysToKeep={2} artifactNumToKeep={3} artifactDaysToKeep={4}", new Object[] {job, numToKeep, daysToKeep, artifactNumToKeep, artifactDaysToKeep});

// always keep the last successful and the last stable builds
Run lsb = job.getLastSuccessfulBuild();
Run lstb = job.getLastStableBuild();
// if configured keep the last successful and the last stable builds
Run lsb = removeLastSuccessfulBuild ? null : job.getLastSuccessfulBuild();
Run lstb = removeLastStableBuild ? null : job.getLastStableBuild();

if (numToKeep != -1) {
// Note that RunList.size is deprecated, and indeed here we are loading all the builds of the job.
Expand Down Expand Up @@ -270,6 +293,14 @@ public int getArtifactNumToKeep() {
return unbox(artifactNumToKeep);
}

public boolean isRemoveLastSuccessfulBuild() {
return removeLastSuccessfulBuild;
}

public boolean isRemoveLastStableBuild() {
return removeLastStableBuild;
}

public String getDaysToKeepStr() {
return toString(daysToKeep);
}
Expand Down
8 changes: 8 additions & 0 deletions core/src/main/resources/hudson/tasks/LogRotator/config.jelly
Original file line number Diff line number Diff line change
Expand Up @@ -41,5 +41,13 @@ THE SOFTWARE.
description="${%if not empty, only up to this number of builds have their artifacts retained}" field="artifactNumToKeepStr">
<f:number clazz="positive-number" min="1" step="1" />
</f:entry>
<f:entry title="${%Remove last successful build}"
field="removeLastSuccessfulBuild">
<f:booleanRadio />
</f:entry>
<f:entry title="${%Remove last stable build}"
field="removeLastStableBuild">
<f:booleanRadio />
</f:entry>
</f:advanced>
</j:jelly>
53 changes: 50 additions & 3 deletions test/src/test/java/hudson/tasks/LogRotatorTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ public class LogRotatorTest {
@Test
public void successVsFailure() throws Exception {
FreeStyleProject project = j.createFreeStyleProject();
project.setLogRotator(new LogRotator(-1, 2, -1, -1));
project.setBuildDiscarder(new LogRotator(-1, 2, -1, -1));
j.buildAndAssertSuccess(project); // #1
project.getBuildersList().replaceBy(Set.of(new FailureBuilder()));
j.buildAndAssertStatus(Result.FAILURE, project); // #2
Expand All @@ -82,11 +82,25 @@ public void successVsFailure() throws Exception {
assertEquals(3, numberOf(project.getLastFailedBuild()));
}

@Test
public void successVsFailureWithRemoveLastSuccess() throws Exception {
FreeStyleProject project = j.createFreeStyleProject();
LogRotator logRotator = new LogRotator(-1, 1, -1, -1);
logRotator.setRemoveLastSuccessfulBuild(true);
project.setBuildDiscarder(logRotator);
project.getPublishersList().replaceBy(Set.of(new TestsFail()));
j.buildAndAssertStatus(Result.UNSTABLE, project); // #1
project.getBuildersList().replaceBy(Set.of(new FailureBuilder()));
j.buildAndAssertStatus(Result.FAILURE, project); // #2
assertNull(project.getBuildByNumber(1));
assertEquals(2, numberOf(project.getLastFailedBuild()));
}

@Test
@Issue("JENKINS-2417")
public void stableVsUnstable() throws Exception {
FreeStyleProject project = j.createFreeStyleProject();
project.setLogRotator(new LogRotator(-1, 2, -1, -1));
project.setBuildDiscarder(new LogRotator(-1, 2, -1, -1));
j.buildAndAssertSuccess(project); // #1
project.getPublishersList().replaceBy(Set.of(new TestsFail()));
j.buildAndAssertStatus(Result.UNSTABLE, project); // #2
Expand All @@ -98,11 +112,44 @@ public void stableVsUnstable() throws Exception {
assertNull(project.getBuildByNumber(2));
}

@Test
public void stableVsUnstableWithRemoveLastStableAndLastSuccessful() throws Exception {
FreeStyleProject project = j.createFreeStyleProject();
LogRotator logRotator = new LogRotator(-1, 1, -1, -1);
logRotator.setRemoveLastSuccessfulBuild(true);
logRotator.setRemoveLastStableBuild(true);
project.setBuildDiscarder(logRotator);
j.buildAndAssertSuccess(project); // #1
project.getPublishersList().replaceBy(Set.of(new TestsFail()));
j.buildAndAssertStatus(Result.UNSTABLE, project); // #2
project.getBuildersList().replaceBy(Set.of(new FailureBuilder()));
j.buildAndAssertStatus(Result.FAILURE, project); // #3
assertNull(project.getBuildByNumber(1));
assertNull(project.getBuildByNumber(2));
assertEquals(3, numberOf(project.getLastBuild()));
}

@Test
public void stableVsUnstableWithRemoveLastStable() throws Exception {
FreeStyleProject project = j.createFreeStyleProject();
LogRotator logRotator = new LogRotator(-1, 1, -1, -1);
logRotator.setRemoveLastStableBuild(true);
project.setBuildDiscarder(logRotator);
j.buildAndAssertSuccess(project); // #1
project.getPublishersList().replaceBy(Set.of(new TestsFail()));
j.buildAndAssertStatus(Result.UNSTABLE, project); // #2
project.getBuildersList().replaceBy(Set.of(new FailureBuilder()));
j.buildAndAssertStatus(Result.FAILURE, project); // #3
assertNull(project.getBuildByNumber(1));
assertEquals(2, numberOf(project.getLastSuccessfulBuild()));
assertEquals(3, numberOf(project.getLastBuild()));
}

@Test
@Issue("JENKINS-834")
public void artifactDelete() throws Exception {
FreeStyleProject project = j.createFreeStyleProject();
project.setLogRotator(new LogRotator(-1, 6, -1, 2));
project.setBuildDiscarder(new LogRotator(-1, 6, -1, 2));
project.getPublishersList().replaceBy(Set.of(new ArtifactArchiver("f", "", true, false)));
j.buildAndAssertStatus(Result.FAILURE, project); // #1
assertFalse(project.getBuildByNumber(1).getHasArtifacts());
Expand Down

0 comments on commit 3bc4ff1

Please sign in to comment.