Skip to content

Commit 6263cfd

Browse files
aeiseleSpace Team
authored andcommitted
TW-84882: if collecting changes fails, still try to publish commit statuses to Space by using the unknown git SHA revision
TW-84882: add tests for fallback revision publishing TW-84882: if collecting changes fails, still try to publish commit statuses to Space by using the unknown git SHA revision (cherry picked from commit b370da8) Merge-request: TC-MR-8046 Merged-by: Andreas Eisele <[email protected]>
1 parent a2a0e35 commit 6263cfd

File tree

6 files changed

+104
-6
lines changed

6 files changed

+104
-6
lines changed

commit-status-publisher-server/src/main/java/jetbrains/buildServer/commitPublisher/BaseCommitStatusPublisher.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616

1717
package jetbrains.buildServer.commitPublisher;
1818

19+
import java.util.Collection;
20+
import java.util.Collections;
1921
import java.util.Map;
2022
import jetbrains.buildServer.serverSide.*;
2123
import jetbrains.buildServer.users.User;
@@ -103,6 +105,12 @@ public void setConnectionTimeout(int timeout) {
103105
myConnectionTimeout = timeout;
104106
}
105107

108+
@NotNull
109+
@Override
110+
public Collection<BuildRevision> getFallbackRevisions() {
111+
return Collections.emptyList();
112+
}
113+
106114
@Nullable
107115
public String getVcsRootId() {
108116
return myParams.get(Constants.VCS_ROOT_ID_PARAM);

commit-status-publisher-server/src/main/java/jetbrains/buildServer/commitPublisher/CommitStatusPublisher.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
package jetbrains.buildServer.commitPublisher;
1818

19+
import java.util.Collection;
1920
import jetbrains.buildServer.serverSide.*;
2021
import jetbrains.buildServer.users.User;
2122
import org.jetbrains.annotations.NotNull;
@@ -69,6 +70,17 @@ public interface CommitStatusPublisher {
6970

7071
void setConnectionTimeout(int timeout);
7172

73+
/**
74+
* Returns the <em>(VCS specific)</em> fallback revisions to be used if no {@link BuildRevision}s could be determined.
75+
* <p>
76+
* <em>Note:</em> Publishing statuses to an unknown / fallback revisions only makes sense in very limited use cases.
77+
* Currently only {@link jetbrains.buildServer.commitPublisher.space.SpacePublisher} supports this.
78+
* </p>
79+
*
80+
* @return empty collection if this publisher doesn't support fallback revisions
81+
*/
82+
@NotNull
83+
Collection<BuildRevision> getFallbackRevisions();
7284

7385
enum Event {
7486
STARTED("buildStarted", EventPriority.FIRST, true), FINISHED("buildFinished", true),

commit-status-publisher-server/src/main/java/jetbrains/buildServer/commitPublisher/CommitStatusPublisherListener.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -645,7 +645,7 @@ private boolean shouldFailBuild(@NotNull SBuildType buildType) {
645645
private Collection<BuildRevision> getQueuedBuildRevisionForVote(@NotNull BuildType buildType,
646646
@NotNull CommitStatusPublisher publisher,
647647
@NotNull BuildPromotion buildPromotion) {
648-
if (buildPromotion.isFailedToCollectChanges()) return Collections.emptyList();
648+
if (buildPromotion.isFailedToCollectChanges()) return publisher.getFallbackRevisions();
649649

650650
if (!((BuildPromotionEx)buildPromotion).isChangeCollectingNeeded(false)) {
651651
return getBuildRevisionForVote(publisher, buildPromotion.getRevisions());
@@ -819,7 +819,7 @@ public RetryInfo publish(Event event, BuildRevision revision, CommitStatusPublis
819819

820820
@Override
821821
public Collection<BuildRevision> getRevisions(BuildType buildType, CommitStatusPublisher publisher) {
822-
if (buildPromotion.isFailedToCollectChanges()) return Collections.emptyList();
822+
if (buildPromotion.isFailedToCollectChanges()) return publisher.getFallbackRevisions();
823823
return getBuildRevisionForVote(publisher, build.getRevisions());
824824
}
825825
};

commit-status-publisher-server/src/main/java/jetbrains/buildServer/commitPublisher/space/SpacePublisher.java

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import jetbrains.buildServer.serverSide.oauth.space.SpaceConnectDescriber;
3030
import jetbrains.buildServer.util.StringUtil;
3131
import jetbrains.buildServer.vcs.VcsModification;
32+
import jetbrains.buildServer.vcs.VcsRootInstance;
3233
import jetbrains.buildServer.vcshostings.http.HttpHelper;
3334
import org.apache.http.HttpHeaders;
3435
import org.apache.http.entity.ContentType;
@@ -39,6 +40,7 @@
3940

4041
public class SpacePublisher extends HttpBasedCommitStatusPublisher<SpaceBuildStatus> {
4142
private static final String UNKNOWN_BUILD_CONFIGURATION = "Unknown build configuration";
43+
private static final String UNKNWON_GIT_SHA = "0000000000000000000000000000000000000000";
4244

4345
private final SpaceConnectDescriber mySpaceConnector;
4446
private final Gson myGson = new Gson();
@@ -366,4 +368,23 @@ public void processResponse(HttpHelper.HttpResponse response) throws HttpPublish
366368
throw new HttpPublisherException(statusCode, response.getStatusText(), "HTTP response error: " + (responseContent != null ? responseContent : "<empty>"));
367369
}
368370
}
371+
372+
/**
373+
* Returns the <em>"unknown git SHA"</em> revision.
374+
* This revision can serve as a fallback.
375+
* Space is able to match safe-merge statuses by build ID.
376+
* See: TW-84882
377+
*
378+
* @return singleton collection of an artificial build revision pointing to {@link #UNKNWON_GIT_SHA}
379+
*/
380+
@NotNull
381+
@Override
382+
public Collection<BuildRevision> getFallbackRevisions() {
383+
final List<VcsRootInstance> vcsRootInstances = myBuildType.getVcsRootInstances();
384+
if (vcsRootInstances.isEmpty()) {
385+
LOG.warn("unable to construct fallback build revision for Space build " + LogUtil.describe(myBuildType) + ": no VCS root instances found");
386+
return super.getFallbackRevisions();
387+
}
388+
return Collections.singletonList(new BuildRevision(vcsRootInstances.get(0), UNKNWON_GIT_SHA, "", UNKNWON_GIT_SHA));
389+
}
369390
}

commit-status-publisher-server/src/test/java/jetbrains/buildServer/commitPublisher/CommitStatusPublisherListenerTest.java

Lines changed: 50 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import jetbrains.buildServer.serverSide.executors.ExecutorServices;
3131
import jetbrains.buildServer.serverSide.impl.BuildTypeImpl;
3232
import jetbrains.buildServer.serverSide.impl.CancelableTaskHolder;
33+
import jetbrains.buildServer.serverSide.impl.MockVcsSupport;
3334
import jetbrains.buildServer.serverSide.impl.RunningBuildState;
3435
import jetbrains.buildServer.serverSide.impl.beans.VcsRootInstanceContext;
3536
import jetbrains.buildServer.serverSide.impl.projects.ProjectsWatcher;
@@ -39,10 +40,7 @@
3940
import jetbrains.buildServer.serverSide.systemProblems.SystemProblemEntry;
4041
import jetbrains.buildServer.users.SUser;
4142
import jetbrains.buildServer.users.UserModel;
42-
import jetbrains.buildServer.util.Dates;
43-
import jetbrains.buildServer.util.DependencyOptionSupportImpl;
44-
import jetbrains.buildServer.util.FileUtil;
45-
import jetbrains.buildServer.util.TestFor;
43+
import jetbrains.buildServer.util.*;
4644
import jetbrains.buildServer.util.http.HttpMethod;
4745
import jetbrains.buildServer.vcs.*;
4846
import jetbrains.buildServer.vcs.impl.VcsRootInstanceImpl;
@@ -934,6 +932,41 @@ public void should_not_publish_featureless_for_dependency_builds() {
934932
then(myPublisher.getEventsReceived()).isEmpty();
935933
}
936934

935+
@TestFor(issues = "TW-84882")
936+
public void should_not_publish_when_collecting_changes_fails() {
937+
addBadVcsRootTo(myBuildType);
938+
final SQueuedBuild queuedBuild = myBuildType.addToQueue("");
939+
assertNotNull(queuedBuild);
940+
myServer.flushQueue();
941+
942+
waitFor(() -> {
943+
SBuild build = queuedBuild.getBuildPromotion().getAssociatedBuild();
944+
return build != null && build.isFinished();
945+
});
946+
947+
waitForTasksToFinish(Event.FINISHED);
948+
then(myPublisher.getEventsReceived()).isEqualTo(Collections.emptyList());
949+
}
950+
951+
@TestFor(issues = "TW-84882")
952+
public void should_publish_to_fallback_when_collecting_changes_fails() {
953+
addBadVcsRootTo(myBuildType);
954+
final VcsRootInstance vcsRootInstance = myBuildType.getVcsRootInstances().iterator().next();
955+
final BuildRevision fallback = new BuildRevision(vcsRootInstance, "000", "", "000");
956+
myPublisher.setFallbackRevisions(Collections.singletonList(fallback));
957+
final SQueuedBuild queuedBuild = myBuildType.addToQueue("");
958+
assertNotNull(queuedBuild);
959+
myServer.flushQueue();
960+
961+
waitFor(() -> {
962+
SBuild build = queuedBuild.getBuildPromotion().getAssociatedBuild();
963+
return build != null && build.isFinished();
964+
});
965+
966+
waitForTasksToFinish(Event.FINISHED);
967+
then(myPublisher.getEventsReceived()).containsExactly(Event.STARTED, Event.FAILURE_DETECTED, Event.FINISHED);
968+
}
969+
937970
private SVcsModification prepareVcs() {
938971
return prepareVcs("vcs1", "111", "rev1_2", SetVcsRootIdMode.EXT_ID);
939972
}
@@ -965,5 +998,18 @@ private void assertIfNoTasks(Event eventType) {
965998
then(myMultiNodeTasks.findTasks(Collections.singleton(eventType.getName())).isEmpty()).isTrue();
966999
}
9671000

1001+
private void addBadVcsRootTo(final BuildTypeEx addTo) {
1002+
final MockVcsSupport failSupport = new MockVcsSupport("fail"){
1003+
@NotNull
1004+
@Override
1005+
public String getCurrentVersion(@NotNull final VcsRoot root) {
1006+
throw new RuntimeException("BAD VCS ROOT");
1007+
}
1008+
};
1009+
1010+
myServer.getVcsManager().registerVcsSupport(failSupport);
1011+
myFixture.addVcsRoot("fail", "", addTo);
1012+
}
1013+
9681014
private enum SetVcsRootIdMode { DONT, EXT_ID, INT_ID }
9691015
}

commit-status-publisher-server/src/test/java/jetbrains/buildServer/commitPublisher/MockPublisher.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ class MockPublisher extends BaseCommitStatusPublisher implements CommitStatusPub
4848
private int mySuccessReceived = 0;
4949
private final Set<Event> myEventsToWait = new HashSet<Event>();
5050
private int myShouldFailToPublish = 0;
51+
private Collection<BuildRevision> myFallbackRevisions = Collections.emptyList();
5152

5253
private final PublisherLogger myLogger;
5354

@@ -359,6 +360,16 @@ public int compareTo(@NotNull Object o) {
359360
}
360361
}
361362

363+
@NotNull
364+
@Override
365+
public Collection<BuildRevision> getFallbackRevisions() {
366+
return myFallbackRevisions;
367+
}
368+
369+
public void setFallbackRevisions(@NotNull Collection<BuildRevision> fallbackRevisions) {
370+
myFallbackRevisions = fallbackRevisions;
371+
}
372+
362373
class MockState {
363374
final MockStatus myStatus;
364375
final String myRevision;

0 commit comments

Comments
 (0)