use of com.atlassian.stash.scm.git.revlist.GitRevListBuilder in project stashbot by palantir.
the class TriggerJenkinsBuildHook method onReceive.
@Override
public void onReceive(@Nonnull Repository repo, @Nonnull Collection<RefChange> changes, @Nonnull HookResponse response) {
final RepositoryConfiguration rc;
try {
rc = cpm.getRepositoryConfigurationForRepository(repo);
} catch (SQLException e) {
throw new RuntimeException("Failed to get repositoryConfiguration for repo " + repo.toString());
}
if (!rc.getCiEnabled()) {
log.debug("CI disabled for repo " + repo.getName());
return;
}
Set<String> publishBuilds = new HashSet<String>();
// First trigger all publish builds (if they are enabled)
if (cpm.getJobTypeStatusMapping(rc, JobType.PUBLISH)) {
for (RefChange refChange : changes) {
if (!refChange.getRefId().matches(rc.getPublishBranchRegex())) {
continue;
}
// but it seems more reliable to use RefChangeType
if (refChange.getType().equals(RefChangeType.DELETE)) {
log.debug("Detected delete, not triggering a build for this change");
continue;
}
// if matches publication regex, no verify build needed for that hash
// Only perform publish builds of the "to ref", not commits between
// I.E. if you have A-B-C and you push -D-E-F, a verify build of D and E might be triggered, but F would be
// published and not verified, if the ref matches both build and verify.
log.info("Stashbot Trigger: Triggering PUBLISH build for commit " + refChange.getToHash());
// trigger a publication build
jenkinsManager.triggerBuild(repo, JobType.PUBLISH, refChange.getToHash(), refChange.getRefId());
publishBuilds.add(refChange.getToHash());
}
}
// Nothing to do if VERIFY_COMMIT not enabled
if (!cpm.getJobTypeStatusMapping(rc, JobType.VERIFY_COMMIT)) {
return;
}
// Calculate the sum of all new commits introduced by this change
// This would be:
// (existing refs matching regex, deleted refs, changed refs old values)..(added refs, changed refs new values)
// We will need a list of branches first
GitScmCommandBuilder gcb = gcbf.builder(repo).command("branch");
CommandOutputHandler<Object> gboh = cohf.getBranchContainsOutputHandler();
gcb.build(gboh).call();
@SuppressWarnings("unchecked") ImmutableList<String> branches = (ImmutableList<String>) gboh.getOutput();
HashSet<String> plusBranches = new HashSet<String>();
HashSet<String> minusBranches = new HashSet<String>();
// add verify-matching branches to the minusBranches set
minusBranches.addAll(ImmutableList.copyOf(Iterables.filter(branches, new Predicate<String>() {
@Override
public boolean apply(String input) {
if (input.matches(rc.getVerifyBranchRegex())) {
return true;
}
return false;
}
})));
// now calculate the changed/added/deleted refs
for (RefChange refChange : changes) {
if (!refChange.getRefId().matches(rc.getVerifyBranchRegex())) {
continue;
}
// Since we are a verify branch that changed, we need to not be in minusBranches anymore
minusBranches.remove(refChange.getRefId());
switch(refChange.getType()) {
case DELETE:
minusBranches.add(refChange.getFromHash());
break;
case ADD:
plusBranches.add(refChange.getToHash());
break;
case UPDATE:
minusBranches.add(refChange.getFromHash());
plusBranches.add(refChange.getToHash());
break;
default:
throw new IllegalStateException("Unknown change type " + refChange.getType().toString());
}
}
// we can now calculate all the new commits introduced by this change in one revwalk.
GitScmCommandBuilder gscb = gcbf.builder(repo);
GitRevListBuilder grlb = gscb.revList();
for (String mb : minusBranches) {
grlb.revs("^" + mb);
}
for (String pb : plusBranches) {
grlb.revs(pb);
}
Integer maxVerifyChain = getMaxVerifyChain(rc);
if (maxVerifyChain != 0) {
log.debug("Limiting to " + maxVerifyChain.toString() + " commits for verification");
grlb.limit(maxVerifyChain);
}
CommandOutputHandler<Object> rloh = cohf.getRevlistOutputHandler();
grlb.build(rloh).call();
// returns in old-to-new order, already limited by max-verify-build limiter
@SuppressWarnings("unchecked") ImmutableList<String> changesets = (ImmutableList<String>) rloh.getOutput();
// For each new commit
for (String cs : changesets) {
if (publishBuilds.contains(cs)) {
log.info("Stashbot Trigger: NOT triggering VERIFICATION build for commit " + cs + " because it already triggered a PUBLISH build");
continue;
}
log.info("Stashbot Trigger: Triggering VERIFICATION build for commit " + cs);
// trigger a verification build (no merge)
jenkinsManager.triggerBuild(repo, JobType.VERIFY_COMMIT, cs, "");
}
}
Aggregations