public void generateMergeRequestBuild(
      String json, Job project, StaplerRequest req, StaplerResponse rsp) {
    GitLabMergeRequest request = GitLabMergeRequest.create(json);
    if ("closed".equals(request.getObjectAttribute().getState())) {
      LOGGER.log(Level.INFO, "Closed Merge Request, no build started");
      return;
    }
    if ("merged".equals(request.getObjectAttribute().getState())) {
      LOGGER.log(Level.INFO, "Accepted Merge Request, no build started");
      return;
    }
    if ("update".equals(request.getObjectAttribute().getAction())) {
      LOGGER.log(
          Level.INFO,
          "Existing Merge Request, build will be trigged by buildOpenMergeRequests instead");
      return;
    }
    if (request.getObjectAttribute().getLastCommit() != null) {
      Run mergeBuild =
          getBuildBySHA1(project, request.getObjectAttribute().getLastCommit().getId(), true);
      if (mergeBuild != null) {
        LOGGER.log(
            Level.INFO,
            "Last commit in Merge Request has already been built in build #" + mergeBuild.getId());
        return;
      }
    }
    if (request.getObjectAttribute().getDescription().contains("[ci-skip]")) {
      LOGGER.log(
          Level.INFO,
          "Skipping MR " + request.getObjectAttribute().getTitle() + " due to ci-skip.");
      return;
    }

    Authentication old = SecurityContextHolder.getContext().getAuthentication();
    SecurityContextHolder.getContext().setAuthentication(ACL.SYSTEM);
    try {
      GitLabPushTrigger trigger = null;
      if (project instanceof ParameterizedJobMixIn.ParameterizedJob) {
        ParameterizedJobMixIn.ParameterizedJob p = (ParameterizedJobMixIn.ParameterizedJob) project;
        for (Trigger t : p.getTriggers().values()) {
          if (t instanceof GitLabPushTrigger) {
            trigger = (GitLabPushTrigger) t;
          }
        }
      }
      if (trigger == null) {
        return;
      }
      trigger.onPost(request);
    } finally {
      SecurityContextHolder.getContext().setAuthentication(old);
    }
  }
  public void generatePushBuild(String json, Job project, StaplerRequest req, StaplerResponse rsp) {
    GitLabPushRequest request = GitLabPushRequest.create(json);
    String repositoryUrl = request.getRepository().getUrl();
    if (repositoryUrl == null) {

      LOGGER.log(Level.WARNING, "No repository url found.");
      return;
    }

    Authentication old = SecurityContextHolder.getContext().getAuthentication();
    SecurityContextHolder.getContext().setAuthentication(ACL.SYSTEM);
    try {

      GitLabPushTrigger trigger = null;
      if (project instanceof ParameterizedJobMixIn.ParameterizedJob) {
        ParameterizedJobMixIn.ParameterizedJob p = (ParameterizedJobMixIn.ParameterizedJob) project;
        for (Trigger t : p.getTriggers().values()) {

          if (t instanceof GitLabPushTrigger) {
            trigger = (GitLabPushTrigger) t;
          }
        }
      }

      if (trigger == null) {
        return;
      }

      if (trigger.getCiSkip() && request.getLastCommit() != null) {
        if (request.getLastCommit().getMessage().contains("[ci-skip]")) {
          LOGGER.log(Level.INFO, "Skipping due to ci-skip.");
          return;
        }
      }

      trigger.onPost(request);

      if (!trigger.getTriggerOpenMergeRequestOnPush().equals("never")) {
        // Fetch and build open merge requests with the same source branch
        buildOpenMergeRequests(trigger, request.getProject_id(), request.getRef());
      }
    } finally {
      SecurityContextHolder.getContext().setAuthentication(old);
    }
  }
  protected void buildOpenMergeRequests(
      GitLabPushTrigger trigger, Integer projectId, String projectRef) {
    try {
      GitLab api = new GitLab();
      // TODO Replace this with a call to GitlabAPI.getOpenMergeRequests, once timols has deployed
      // version 1.1.7
      String tailUrl =
          GitlabProject.URL
              + "/"
              + projectId
              + GitlabMergeRequest.URL
              + "?state=opened&per_page=100";
      List<GitlabMergeRequest> mergeRequests =
          api.instance().retrieve().getAll(tailUrl, GitlabMergeRequest[].class);

      for (org.gitlab.api.models.GitlabMergeRequest mr : mergeRequests) {
        if (projectRef.endsWith(mr.getSourceBranch())
            || (trigger.getTriggerOpenMergeRequestOnPush().equals("both")
                && projectRef.endsWith(mr.getTargetBranch()))) {

          if (trigger.getCiSkip() && mr.getDescription().contains("[ci-skip]")) {
            LOGGER.log(Level.INFO, "Skipping MR " + mr.getTitle() + " due to ci-skip.");
            continue;
          }
          GitlabBranch branch =
              api.instance().getBranch(api.instance().getProject(projectId), mr.getSourceBranch());
          LastCommit lastCommit = new LastCommit();
          lastCommit.setId(branch.getCommit().getId());
          lastCommit.setMessage(branch.getCommit().getMessage());
          lastCommit.setUrl(
              GitlabProject.URL
                  + "/"
                  + projectId
                  + "/repository"
                  + GitlabCommit.URL
                  + "/"
                  + branch.getCommit().getId());

          LOGGER.log(
              Level.FINE,
              "Generating new merge trigger from "
                  + mr.toString()
                  + "\n source: "
                  + mr.getSourceBranch()
                  + "\n target: "
                  + mr.getTargetBranch()
                  + "\n state: "
                  + mr.getState()
                  + "\n assign: "
                  + mr.getAssignee()
                  + "\n author: "
                  + mr.getAuthor()
                  + "\n id: "
                  + mr.getId()
                  + "\n iid: "
                  + mr.getIid()
                  + "\n last commit: "
                  + lastCommit.getId()
                  + "\n\n");
          GitLabMergeRequest newReq = new GitLabMergeRequest();
          newReq.setObject_kind("merge_request");
          newReq.setObjectAttribute(new GitLabMergeRequest.ObjectAttributes());
          if (mr.getAssignee() != null)
            newReq.getObjectAttribute().setAssigneeId(mr.getAssignee().getId());
          if (mr.getAuthor() != null)
            newReq.getObjectAttribute().setAuthorId(mr.getAuthor().getId());
          newReq.getObjectAttribute().setDescription(mr.getDescription());
          newReq.getObjectAttribute().setId(mr.getId());
          newReq.getObjectAttribute().setIid(mr.getIid());
          newReq.getObjectAttribute().setMergeStatus(mr.getState());
          newReq.getObjectAttribute().setSourceBranch(mr.getSourceBranch());
          newReq.getObjectAttribute().setSourceProjectId(mr.getSourceProjectId());
          newReq.getObjectAttribute().setTargetBranch(mr.getTargetBranch());
          newReq.getObjectAttribute().setTargetProjectId(projectId);
          newReq.getObjectAttribute().setTitle(mr.getTitle());
          newReq.getObjectAttribute().setLastCommit(lastCommit);

          Authentication old = SecurityContextHolder.getContext().getAuthentication();
          SecurityContextHolder.getContext().setAuthentication(ACL.SYSTEM);
          try {
            trigger.onPost(newReq);
          } finally {
            SecurityContextHolder.getContext().setAuthentication(old);
          }
        }
      }
    } catch (Exception e) {
      LOGGER.warning(
          "failed to communicate with gitlab server to determine is this is an update for a merge request: "
              + e.getMessage());
      e.printStackTrace();
    }
  }