public void populate(@NotNull AbstractProject project) { synchronized (populateLock) { Run lastBuild = project.getLastBuild(); if (lastBuild == null) { return; } if (lastBuild.getNumber() <= oldest) { return; } for (int number = lastBuild.getNumber(); number > oldest; number--) { Run build = project.getBuildByNumber(number); if (build == null) { continue; } String externalizableId = build.getExternalizableId(); size++; put("projectName", project.getName(), externalizableId); populateWithChangeInformation(build, externalizableId); populateWithCauseInformation(build, externalizableId); populateWithParameters(build, externalizableId); } oldest = lastBuild.getNumber(); } }
public int compare(Run record, String key) { try { int k = Integer.parseInt(key); return record.getNumber() - k; } catch (NumberFormatException nfe) { return String.valueOf(record.getNumber()).compareTo(key); } }
public int compare(Run o1, Run o2) { if (o1 == null) { if (o2 == null) { return 0; } else { return -1; } } if (o2 == null) { return 1; } return ((Integer) o2.getNumber()).compareTo(o1.getNumber()); }
/** * @param project * @param commitSHA1 * @return */ private Run getBuildBySHA1(Job project, String commitSHA1, boolean triggeredByMergeRequest) { List<Run> builds = project.getBuilds(); for (Run build : builds) { BuildData data = build.getAction(BuildData.class); MergeRecord mergeRecord = build.getAction(MergeRecord.class); if (mergeRecord == null) { // Determine if build was triggered by a Merge Request event ParametersAction params = build.getAction(ParametersAction.class); if (params == null) continue; StringParameterValue sourceBranch = (StringParameterValue) params.getParameter("gitlabSourceBranch"); StringParameterValue targetBranch = (StringParameterValue) params.getParameter("gitlabTargetBranch"); boolean isMergeRequestBuild = (sourceBranch != null && !sourceBranch.value.equals(targetBranch.value)); if (!triggeredByMergeRequest) { if (isMergeRequestBuild) // skip Merge Request builds continue; if (data.getLastBuiltRevision().getSha1String().contains(commitSHA1)) { return build; } } else { if (!isMergeRequestBuild) // skip Push builds continue; if (hasBeenBuilt(data, ObjectId.fromString(commitSHA1), build)) { return build; } } } else { Build b = data.lastBuild; boolean isMergeBuild = mergeRecord != null && !mergeRecord.getSha1().equals(b.getMarked().getSha1String()); if (b != null && b.getMarked() != null && b.getMarked().getSha1String().equals(commitSHA1)) { if (triggeredByMergeRequest == isMergeBuild) { LOGGER.log( Level.FINE, build.getNumber() + " Build found matching " + commitSHA1 + " " + (isMergeBuild ? "merge" : "normal") + " build"); return build; } } } } return null; }
/** * Returns true if any of the builds recorded in this fingerprint is still retained. * * <p>This is used to find out old fingerprint records that can be removed without losing too much * information. */ public synchronized boolean isAlive() { if (original != null && original.isAlive()) return true; for (Entry<String, RangeSet> e : usages.entrySet()) { Job j = Jenkins.getInstance().getItemByFullName(e.getKey(), Job.class); if (j == null) continue; Run firstBuild = j.getFirstBuild(); if (firstBuild == null) continue; int oldest = firstBuild.getNumber(); if (!e.getValue().isSmallerThan(oldest)) return true; } return false; }
private void generateStatusJSON( String commitSHA1, Job project, StaplerRequest req, StaplerResponse rsp) { SCMTriggerItem item = SCMTriggerItems.asSCMTriggerItem(project); GitSCM gitSCM = getGitSCM(item); if (gitSCM == null) { throw new IllegalArgumentException("This repo does not use git."); } Run mainBuild = this.getBuildBySHA1(project, commitSHA1, true); JSONObject object = new JSONObject(); object.put("sha", commitSHA1); if (mainBuild == null) { try { object.put("status", "pending"); this.writeJSON(rsp, object); return; } catch (IOException e) { throw HttpResponses.error(500, "Could not generate response."); } } object.put("id", mainBuild.getNumber()); Result res = mainBuild.getResult(); // TODO: add status of pending when we figure it out. if (mainBuild.isBuilding()) { object.put("status", "running"); } else if (res == Result.SUCCESS) { object.put("status", "success"); } else { object.put("status", "failed"); } try { this.writeJSON(rsp, object); } catch (IOException e) { throw HttpResponses.error(500, "Could not generate response."); } }
public String id(Run run) throws UnsupportedEncodingException { return URLEncoder.encode(run.getParent().getFullDisplayName() + run.getNumber(), "UTF-8"); }
/** * Waits for the given configurations to finish, retrying any that qualify to be rerun. * * @param execution Provided by the plugin. * @param patterns List of regular expression patterns used to scan the log to determine if a * build should be rerun. * @param retries Mutable map that tracks the number of times a specific configuration has been * retried. * @param configurations The configurations that have already been scheduled to run that should be * waited for to finish. * @return The worst result of all the runs. If a build was rerun, only the result of the rerun is * considered. * @throws InterruptedException * @throws IOException */ private Result waitForMatrixRuns( MatrixBuild.MatrixBuildExecution execution, List<Pattern> patterns, Map<MatrixConfiguration, Integer> retries, LinkedList<MatrixConfiguration> configurations) throws InterruptedException, IOException { BuildListener listener = execution.getListener(); PrintStream logger = listener.getLogger(); Map<String, String> whyBlockedMap = new HashMap< String, String>(); // keep track of why builds are blocked so we can print unique messages when // they change. Result finalResult = Result.SUCCESS; int iteration = 0; boolean continueRetrying = true; while (!configurations.isEmpty()) { ++iteration; MatrixConfiguration configuration = configurations.removeFirst(); if (isBuilding(execution, configuration, whyBlockedMap)) { if (iteration >= configurations.size()) { // Every time we loop through all the configurations, sleep for a bit. // This is to prevent polling too often while everything is still building. iteration = 0; Thread.sleep(1000); } configurations.add(configuration); continue; } Run parentBuild = execution.getBuild(); MatrixRun matrixRun = configuration.getBuildByNumber(parentBuild.getNumber()); Result runResult = matrixRun.getResult(); if (continueRetrying && runResult.isWorseOrEqualTo(getWorseThanOrEqualTo()) && runResult.isBetterOrEqualTo(getBetterThanOrEqualTo())) { if (matchesPattern(matrixRun, patterns)) { int retriedCount = retries.get(configuration); if (retriedCount < getMaxRetries()) { ++retriedCount; retries.put(configuration, retriedCount); // rerun String logMessage = String.format( "%s was %s. Matched pattern to rerun. Rerunning (%d).", matrixRun, runResult, retriedCount); listener.error(logMessage); HealedAction action = parentBuild.getAction(HealedAction.class); if (action == null) { //noinspection SynchronizationOnLocalVariableOrMethodParameter synchronized (parentBuild.getActions()) { action = parentBuild.getAction(HealedAction.class); if (action == null) { action = new HealedAction(matrixRun.getCharset()); parentBuild.addAction(action); } } } action.addAutoHealedJob(matrixRun); MatrixConfiguration parent = matrixRun.getParent(); if (parent != null) { // I'm paranoid about NPEs parent.removeRun(matrixRun); matrixRun.delete(); } else { LOGGER.severe( "couldn't remove old run, parent was null. This is a Jenkins core bug."); } scheduleConfigurationBuild( execution, configuration, new SelfHealingCause(parentBuild, retriedCount)); configurations.add(configuration); continue; } else { String logMessage = String.format( "%s was %s. Matched pattern to rerun, but the max number of retries (%d) has been met.", matrixRun, runResult, getMaxRetries()); listener.error(logMessage); if (getStopRetryingAfterOneFails()) { listener.error("Not retrying any more builds."); continueRetrying = false; } } } else { String logMessage = String.format( "%s was %s. It did not match the pattern to rerun. Accepting result.", matrixRun, runResult); logger.println(logMessage); } } notifyEndRun(matrixRun, execution.getAggregators(), execution.getListener()); finalResult = finalResult.combine(runResult); } return finalResult; }
public BuildPtr(Run run) { this(run.getParent().getFullName(), run.getNumber()); }
/** Returns true if {@link BuildPtr} points to the given run. */ public boolean is(Run r) { return r.getNumber() == number && r.getParent().getFullName().equals(name); }
public String getKey(Run record) { return String.valueOf(record.getNumber()); }