@Override
  public Collection<? extends Action> getProjectActions(AbstractProject<?, ?> project) {
    ArrayList<TestflightBuildAction> actions = new ArrayList<TestflightBuildAction>();
    RunList<? extends AbstractBuild<?, ?>> builds = project.getBuilds();

    Collection predicated =
        CollectionUtils.select(
            builds,
            new Predicate() {
              public boolean evaluate(Object o) {
                Result result = ((AbstractBuild<?, ?>) o).getResult();
                if (result == null) return false; // currently running builds can have a null result
                return result.isBetterOrEqualTo(Result.SUCCESS);
              }
            });

    ArrayList<AbstractBuild<?, ?>> filteredList = new ArrayList<AbstractBuild<?, ?>>(predicated);

    Collections.reverse(filteredList);
    for (AbstractBuild<?, ?> build : filteredList) {
      List<TestflightBuildAction> testflightActions = build.getActions(TestflightBuildAction.class);
      if (testflightActions != null && testflightActions.size() > 0) {
        for (TestflightBuildAction action : testflightActions) {
          actions.add(new TestflightBuildAction(action));
        }
        break;
      }
    }

    return actions;
  }
  /**
   * visit project chain, from current through parents.
   *
   * @param visitor
   * @param run
   */
  public static void traverseChain(HudsonVisitor visitor, Run run) {
    if (run == null) return;

    traverse(visitor, run);

    RepositoryAction repositoryAction = run.getAction(RepositoryAction.class);

    if (repositoryAction != null) {
      if (repositoryAction instanceof ProjectRepositoryAction) {
        final ProjectRepositoryAction projectRepositoryAction =
            (ProjectRepositoryAction) repositoryAction;

        AbstractProject item =
            (AbstractProject)
                Hudson.getInstance().getItem(projectRepositoryAction.getProjectName());

        Optional<Run> r =
            Iterables.tryFind(
                item.getBuilds(),
                new Predicate<Run>() {
                  public boolean apply(Run run) {
                    return run.getNumber() == projectRepositoryAction.getBuildNumber();
                  }
                });

        if (r.isPresent()) traverseChain(visitor, r.get());
      }
    }
  }
 void cancelBuilds(PullRequestData pullRequestData) {
   final String pullRequestUrl = pullRequestData.pullRequestUrl.toString();
   List<AbstractBuild> pullRequestBuilds = new ArrayList<AbstractBuild>();
   for (Object b : project.getBuilds()) {
     if (b instanceof AbstractBuild) {
       AbstractBuild build = (AbstractBuild) b;
       if (build.isBuilding() && isPullRequestBuild(build, pullRequestUrl)) {
         pullRequestBuilds.add(build);
       }
     }
   }
   if (!pullRequestBuilds.isEmpty()) {
     String[] buildNumbers = new String[pullRequestBuilds.size()];
     for (int i = 0; i < pullRequestBuilds.size(); i++) {
       buildNumbers[i] = String.valueOf(pullRequestBuilds.get(i).getNumber());
     }
     LOGGER.info(
         MessageFormat.format(
             "Aborting the following builds of pull request {0}: {1}",
             pullRequestUrl, StringUtils.join(buildNumbers, ", ")));
     for (AbstractBuild build : pullRequestBuilds) {
       Executor executor = build.getExecutor();
       if (executor != null) {
         executor.interrupt();
       }
     }
   } else {
     LOGGER.fine(
         "There is no previous running builds to cancel for Pull Request: " + pullRequestUrl);
   }
 }
  /**
   * Populates and return pipelines for the supplied pipeline prototype with the current status.
   *
   * @param noOfPipelines number of pipeline instances
   */
  public List<Pipeline> createPipelineLatest(int noOfPipelines, ItemGroup context) {
    List<Pipeline> result = new ArrayList<Pipeline>();

    Iterator it = firstProject.getBuilds().iterator();
    for (int i = 0; i < noOfPipelines && it.hasNext(); i++) {
      AbstractBuild firstBuild = (AbstractBuild) it.next();
      List<Change> pipelineChanges = Change.getChanges(firstBuild);
      String pipeLineTimestamp = PipelineUtils.formatTimestamp(firstBuild.getTimeInMillis());
      List<Stage> pipelineStages = new ArrayList<Stage>();
      for (Stage stage : getStages()) {
        pipelineStages.add(stage.createLatestStage(context, firstBuild));
      }
      Pipeline pipelineLatest =
          new Pipeline(
              getName(),
              firstProject,
              firstBuild.getDisplayName(),
              pipeLineTimestamp,
              Trigger.getTriggeredBy(firstBuild),
              UserInfo.getContributors(firstBuild),
              pipelineStages,
              false);
      pipelineLatest.setChanges(pipelineChanges);
      result.add(pipelineLatest);
    }
    return result;
  }
 private BuildData getBuildData(StringParameterValue pullRequestUrlParam) {
   for (Run<?, ?> build : project.getBuilds()) {
     ParametersAction paramsAction = build.getAction(ParametersAction.class);
     if (paramsAction != null) {
       for (ParameterValue param : paramsAction.getParameters()) {
         if (param.equals(pullRequestUrlParam)) {
           List<BuildData> buildDataList = build.getActions(BuildData.class);
           if (!buildDataList.isEmpty()) {
             return buildDataList.get(0);
           }
         }
       }
     }
   }
   return null;
 }
 @Override
 public boolean processWorkspaceBeforeDeletion(
     AbstractProject<?, ?> project, FilePath workspace, Node node)
     throws IOException, InterruptedException {
   if (node == null) {
     // HUDSON-7663 : deleting a job that has never run
     return true;
   }
   StreamTaskListener listener = StreamTaskListener.fromStdout();
   Launcher launcher = node.createLauncher(listener);
   ClearTool ct =
       createClearTool(
           null,
           createClearToolLauncher(
               listener, project.getSomeWorkspace().getParent().getParent(), launcher));
   try {
     if (isUseDynamicView() && !isCreateDynView()) {
       return true;
     }
     AbstractBuild<?, ?> latestBuildOnNode = null;
     for (AbstractBuild<?, ?> build : project.getBuilds()) {
       if (node.equals(build.getBuiltOn())) {
         latestBuildOnNode = build;
         break;
       }
     }
     if (latestBuildOnNode == null) {
       latestBuildOnNode = project.getLastBuild();
     }
     BuildVariableResolver buildVariableResolver = new BuildVariableResolver(latestBuildOnNode);
     ct.rmviewtag(generateNormalizedViewName(buildVariableResolver));
   } catch (Exception e) {
     Logger.getLogger(AbstractClearCaseScm.class.getName())
         .log(Level.WARNING, "Failed to remove ClearCase view", e);
   }
   return true;
 }