Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[JENKINS-72015] Make reference build computation more flexible #712

Merged
merged 23 commits into from
Feb 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
3cff469
Do not update `net.javacrumbs.json-unit:json-unit-assertj` (Java 17).
uhafner Oct 20, 2023
190ac7c
Add a field that stores the SCM.
uhafner Jan 25, 2024
b38f858
Bump version of analysis-pom to 7.0.0 and Jenkins to 2.426.3.
uhafner Jan 25, 2024
26a5000
Fix test.
uhafner Jan 25, 2024
ebc9473
Add forensics version in tests.
uhafner Jan 26, 2024
be09e88
Remove scm key handling.
uhafner Jan 26, 2024
f636534
Improve naming.
uhafner Jan 29, 2024
7786396
[JENKINS-72015] Add new property `requiredResult` for reference jobs.
uhafner Jan 30, 2024
84bf3be
Remove unused classes.
uhafner Jan 30, 2024
76a43a9
Merge remote-tracking branch 'origin/main' into reference-job
uhafner Jan 31, 2024
ed1f7fd
Merge remote-tracking branch 'origin/cleanup' into reference-job
uhafner Jan 31, 2024
96719f2
Delete unused test.
uhafner Jan 31, 2024
83aad4d
[JENKINS-69597] Do not fail when large files are processed.
uhafner Feb 1, 2024
2a6e6f7
Bump version of forensics to 2.4.0-rc1560.b_4b_993ec6a_9f.
uhafner Feb 5, 2024
c8b5547
Fix tests due to new default value.
uhafner Feb 5, 2024
fcb0f8f
Increase timeout.
uhafner Feb 6, 2024
7eeed0a
Fix handling of required status.
uhafner Feb 6, 2024
51a71cb
Add another test case.
uhafner Feb 6, 2024
7d192b2
Merge remote-tracking branch 'origin/main' into reference-job
uhafner Feb 7, 2024
208af0e
Merge remote-tracking branch 'origin/main' into reference-job
uhafner Feb 7, 2024
67a6e99
Bump version of forensics-api to 2.4.0-rc1565.4c3ec58d800d.
uhafner Feb 20, 2024
6b57543
Update version of Maven and setup-maven action.
uhafner Feb 23, 2024
06fde4c
Bump version of forensics-api to 2.4.0.
uhafner Feb 23, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ jobs:
check-latest: true
cache: 'maven'
- name: Set up Maven
uses: stCarolas/setup-maven@v4.5
uses: stCarolas/setup-maven@v5
with:
maven-version: 3.9.6
- name: Build with Maven
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/codeql.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ jobs:
cache: maven

- name: Set up Maven
uses: stCarolas/setup-maven@v4.5
uses: stCarolas/setup-maven@v5
with:
maven-version: 3.9.6

Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/coverage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ jobs:
check-latest: true
cache: 'maven'
- name: Set up Maven
uses: stCarolas/setup-maven@v4.5
uses: stCarolas/setup-maven@v5
with:
maven-version: 3.9.6
- name: Generate coverage with JaCoCo
Expand Down
5 changes: 4 additions & 1 deletion plugin/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<parent>
<groupId>org.jvnet.hudson.plugins</groupId>
<artifactId>analysis-pom</artifactId>
<version>6.14.0</version>
<version>7.0.0</version>
<relativePath />
</parent>

Expand All @@ -30,6 +30,7 @@
<!-- Maven Surefire ArgLine -->
<argLine>-Djava.awt.headless=true -Xmx1024m -Djenkins.test.timeout=1000 --add-opens java.base/java.lang=ALL-UNNAMED --add-opens java.base/java.io=ALL-UNNAMED --add-opens java.base/java.util=ALL-UNNAMED --add-opens java.base/java.util.concurrent=ALL-UNNAMED</argLine>

<forensics-api.version>2.4.0</forensics-api.version>
</properties>

<licenses>
Expand Down Expand Up @@ -68,6 +69,7 @@
<dependency>
<groupId>io.jenkins.plugins</groupId>
<artifactId>forensics-api</artifactId>
<version>${forensics-api.version}</version>
</dependency>
<dependency>
<groupId>io.jenkins.plugins</groupId>
Expand All @@ -86,6 +88,7 @@
<dependency>
<groupId>io.jenkins.plugins</groupId>
<artifactId>forensics-api</artifactId>
<version>2.3.0</version>
<scope>test</scope>
<classifier>tests</classifier>
</dependency>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ static class BlameCallback extends AbstractRepositoryCallback<RemoteResultWrappe
@Override @SuppressWarnings("PMD.UseTryWithResources")
public RemoteResultWrapper<Blames> invoke(final Repository repository, final VirtualChannel channel)
throws InterruptedException {
try {
try (repository) {
RemoteResultWrapper<Blames> log = new RemoteResultWrapper<>(blames, "Errors while running Git blame:");
log.logInfo("-> Git commit ID = '%s'", headCommit.getName());
log.logInfo("-> Git working tree = '%s'", getWorkTree(repository));
Expand All @@ -148,9 +148,6 @@ public RemoteResultWrapper<Blames> invoke(final Repository repository, final Vir

return log;
}
finally {
repository.close();
}
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,9 @@
import org.eclipse.jgit.diff.DiffFormatter;
import org.eclipse.jgit.diff.Edit;
import org.eclipse.jgit.diff.RawTextComparator;
import org.eclipse.jgit.errors.LargeObjectException;
import org.eclipse.jgit.errors.MissingObjectException;
import org.eclipse.jgit.errors.LargeObjectException;

Check warning on line 18 in plugin/src/main/java/io/jenkins/plugins/forensics/git/delta/DeltaRepositoryCallback.java

View check run for this annotation

ci.jenkins.io / PMD

UnnecessaryImport

NORMAL: Duplicate import 'org.eclipse.jgit.errors.LargeObjectException'.
Raw output
Reports import statements that can be removed. They are either unused, duplicated, or the members they import are already implicitly in scope, because they're in java.lang, or the current package. <pre> <code> import java.io.File; // not used, can be removed import java.util.Collections; // used below import java.util.*; // so this one is not used import java.lang.Object; // imports from java.lang, unnecessary import java.lang.Object; // duplicate, unnecessary public class Foo { static Object emptyList() { return Collections.emptyList(); } } </code> </pre> <a href="https://pmd.github.io/pmd-6.55.0/pmd_rules_java_codestyle.html#unnecessaryimport"> See PMD documentation. </a>
import org.eclipse.jgit.lib.ObjectDatabase;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.ObjectLoader;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
import java.io.IOException;
import java.util.Optional;

import org.apache.commons.lang3.StringUtils;

import edu.hm.hafner.util.FilteredLog;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;

Expand All @@ -28,29 +30,30 @@
static final String DELTA_ERROR = "Computing delta information failed with an exception:";
static final String EMPTY_COMMIT_ERROR = "Calculating the Git code delta is not possible due to an unknown commit ID";

private final GitClient git;

Check warning on line 33 in plugin/src/main/java/io/jenkins/plugins/forensics/git/delta/GitDeltaCalculator.java

View check run for this annotation

ci.jenkins.io / Java Compiler

compiler:compile

NORMAL: non-transient instance field of a serializable class declared with a non-serializable type
private final String scmKey;

/**
* Constructor for an instance of {@link DeltaCalculator} which can be used for Git.
*
* @param git
* The {@link GitClient}
* @param scmKey
* the key of the SCM repository (substring that must be part of the SCM key)
*/
public GitDeltaCalculator(final GitClient git) {
public GitDeltaCalculator(final GitClient git, final String scmKey) {
super();

this.git = git;
this.scmKey = scmKey;
}

@Override
public Optional<Delta> calculateDelta(final Run<?, ?> build, final Run<?, ?> referenceBuild,

Check warning on line 52 in plugin/src/main/java/io/jenkins/plugins/forensics/git/delta/GitDeltaCalculator.java

View check run for this annotation

ci.jenkins.io / Java Compiler

compiler:compile

NORMAL: ,hudson.model.Run ,java.lang.String,edu.hm.hafner.util.FilteredLog) in io.jenkins.plugins.forensics.delta.DeltaCalculator has been deprecated calculateDelta(hudson.model.Run
final String scmKeyFilter, final FilteredLog log) {
log.logInfo("-> Obtaining commits in SCM '%s' for current build '%s'",
scmKeyFilter, build.getFullDisplayName());
Optional<GitCommitsRecord> buildCommits = GitCommitsRecord.findRecordForScm(build, scmKeyFilter);
log.logInfo("-> Obtaining commits in SCM '%s' for reference build '%s'",
scmKeyFilter, referenceBuild.getFullDisplayName());
Optional<GitCommitsRecord> referenceCommits = GitCommitsRecord.findRecordForScm(referenceBuild, scmKeyFilter);
String scm = StringUtils.defaultIfEmpty(scmKeyFilter, scmKey);
Optional<GitCommitsRecord> buildCommits = GitCommitsRecord.findRecordForScm(build, scm);
Optional<GitCommitsRecord> referenceCommits = GitCommitsRecord.findRecordForScm(referenceBuild, scm);
if (buildCommits.isPresent() && referenceCommits.isPresent()) {
String currentCommit = getLatestCommit(build.getFullDisplayName(), buildCommits.get(), log);
String referenceCommit = getLatestCommit(referenceBuild.getFullDisplayName(), referenceCommits.get(), log);
Expand All @@ -77,11 +80,11 @@
* Returns the latest commit of the {@link GitCommitsRecord commits record} of a Git repository.
*
* @param buildName
* The name of the build the commits record corresponds to
* the name of the build the commits record corresponds to
* @param record
* The commits record
* the commits record
* @param log
* The log
* the log
*
* @return the latest commit
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public Optional<DeltaCalculator> createDeltaCalculator(final SCM scm, final Run<
GitClient client = validator.createClient();
logger.logInfo("-> Git delta calculator successfully created in working tree '%s'",
new PathUtil().getAbsolutePath(client.getWorkTree().getRemote()));
return Optional.of(new GitDeltaCalculator(client));
return Optional.of(new GitDeltaCalculator(client, scm.getKey()));
}
logger.logInfo("-> Git Delta Calculator could not be created for SCM '%s' in working tree '%s'", scm,
workspace);
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,11 @@
import edu.umd.cs.findbugs.annotations.NonNull;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;

import org.kohsuke.stapler.AncestorInPath;
import org.kohsuke.stapler.DataBoundConstructor;
import org.kohsuke.stapler.DataBoundSetter;
import org.kohsuke.stapler.QueryParameter;
import org.kohsuke.stapler.verb.POST;
import org.jenkinsci.Symbol;
import hudson.Extension;
import hudson.model.BuildableItem;
import hudson.model.Item;
import hudson.model.Run;
import hudson.util.ComboBoxModel;
import hudson.util.FormValidation;
import jenkins.scm.api.SCMHead;

import io.jenkins.plugins.forensics.reference.ReferenceRecorder;
Expand Down Expand Up @@ -50,8 +43,8 @@ public GitReferenceRecorder() {

/**
* Sets the maximal number of additional commits in the reference job that will be considered during the
* comparison with the current branch. In order to avoid an indefinite scanning of the build history until a
* matching reference has been found this value is used as a stop criteria.
* comparison with the current branch. To avoid an indefinite scanning of the build history until a
* matching reference has been found, this value is used as a stop criteria.
*
* @param maxCommits
* maximal number of commits
Expand Down Expand Up @@ -87,23 +80,19 @@ public boolean isSkipUnknownCommits() {
final FilteredLog log) {
Optional<GitCommitsRecord> referenceCommit
= GitCommitsRecord.findRecordForScm(lastCompletedBuildOfReferenceJob, getScm());

Optional<Run<?, ?>> referenceBuild;
if (referenceCommit.isPresent()) {
Optional<GitCommitsRecord> thisCommit = GitCommitsRecord.findRecordForScm(owner, getScm());
if (thisCommit.isPresent()) {
GitCommitsRecord commitsRecord = thisCommit.get();
Optional<Run<?, ?>> referencePoint = commitsRecord.getReferencePoint(
referenceCommit.get(), getMaxCommits(), isSkipUnknownCommits(), log);
if (referencePoint.isPresent()) {
log.logInfo("-> found build '%s' in reference job with matching commits",
referencePoint.get().getDisplayName());

return referencePoint;
}
}
referenceBuild = findByCommits(owner, referenceCommit.get(), log);
}
else {
log.logInfo("-> selected build '%s' of reference job does not yet contain a `GitCommitsRecord`",
lastCompletedBuildOfReferenceJob.getDisplayName());
referenceBuild = Optional.empty();
}

if (referenceBuild.isPresent()) {
return referenceBuild;
}

Optional<SCMHead> targetBranchHead = findTargetBranchHead(owner.getParent());
Expand All @@ -117,6 +106,30 @@ public boolean isSkipUnknownCommits() {
return Optional.empty();
}

private Optional<Run<?, ?>> findByCommits(final Run<?, ?> owner, final GitCommitsRecord referenceCommit,
final FilteredLog log) {
Optional<GitCommitsRecord> ownerCommits = GitCommitsRecord.findRecordForScm(owner, getScm());
if (ownerCommits.isPresent()) {
GitCommitsRecord commitsRecord = ownerCommits.get();
Optional<Run<?, ?>> referencePoint = commitsRecord.getReferencePoint(
referenceCommit, getMaxCommits(), isSkipUnknownCommits(), log);
if (referencePoint.isPresent()) {
Run<?, ?> referenceBuild = referencePoint.get();
log.logInfo("-> found build '%s' in reference job with matching commits",
referenceBuild.getDisplayName());

return referencePoint;
}
else {
log.logInfo("-> found no build with matching commits");
}
}
else {
log.logInfo("-> found no `GitCommitsRecord` in current build '%s'", owner.getDisplayName());
}
return Optional.empty();
}

@Override
@SuppressFBWarnings("BC")
public Descriptor getDescriptor() {
Expand All @@ -129,66 +142,22 @@ public Descriptor getDescriptor() {
@Extension
@Symbol("discoverGitReferenceBuild")
public static class Descriptor extends SimpleReferenceRecorderDescriptor {
private final JenkinsFacade jenkins;

/**
* Creates a new descriptor with the concrete services.
* Creates a new instance of {@link Descriptor}.
*/
@SuppressWarnings("unused") // Required for extension point
public Descriptor() {
this(new JenkinsFacade(), new GitReferenceJobModelValidation());
this(new JenkinsFacade());
}

@VisibleForTesting
Descriptor(final JenkinsFacade jenkins, final GitReferenceJobModelValidation model) {
super();

this.jenkins = jenkins;
this.model = model;
Descriptor(final JenkinsFacade jenkins) {
super(jenkins);
}

@NonNull
@Override
public String getDisplayName() {
return Messages.Recorder_DisplayName();
}

private final GitReferenceJobModelValidation model;

/**
* Returns the model with the possible reference jobs.
*
* @param project
* the project that is configured
*
* @return the model with the possible reference jobs
*/
@POST
public ComboBoxModel doFillReferenceJobItems(@AncestorInPath final BuildableItem project) {
if (jenkins.hasPermission(Item.CONFIGURE, project)) {
return model.getAllJobs();
}
return new ComboBoxModel();
}

/**
* Performs on-the-fly validation of the reference job.
*
* @param project
* the project that is configured
* @param referenceJob
* the reference job
*
* @return the validation result
*/
@POST
@SuppressWarnings("unused") // Used in jelly validation
public FormValidation doCheckReferenceJob(@AncestorInPath final BuildableItem project,
@QueryParameter final String referenceJob) {
if (!jenkins.hasPermission(Item.CONFIGURE, project)) {
return FormValidation.ok();
}
return model.validateJob(referenceJob);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,5 +36,4 @@ public Optional<CommitDecorator> createCommitDecorator(final SCM scm, final Filt
}
return Optional.empty();
}

}
Loading
Loading