gitlab_service.js 3.2 KB
Newer Older
1
const vscode = require('vscode');
2 3
const request = require('request-promise');
const gitService = require('./git_service');
F
Fatih Acet 已提交
4
let glToken = null;
5 6

async function fetch(path) {
7 8 9
  const { instanceUrl } = vscode.workspace.getConfiguration('gitlab');
  const apiRoot = `${instanceUrl}/api/v4`;

F
Fatih Acet 已提交
10
  if (!glToken) {
11
    return vscode.window.showInformationMessage('GitLab Workflow: Cannot make request. No token found.');
F
Fatih Acet 已提交
12 13
  }

14 15 16
  const config = {
    url: `${apiRoot}${path}`,
    headers: {
F
Fatih Acet 已提交
17
      'PRIVATE-TOKEN': glToken,
18 19 20 21 22 23 24 25
    }
  };

  const response = await request(config);

  try {
    return JSON.parse(response);
  } catch (e) {
26
    vscode.window.showInformationMessage('GitLab Workflow: Failed to perform your operation.');
27 28 29 30
    return { error: e };
  }
}

31 32 33 34 35 36 37 38
async function fetchUser() {
  try {
    return await fetch('/user');
  } catch (e) {
    vscode.window.showInformationMessage('GitLab Workflow: GitLab user not found. Check your Personal Access Token.');
  }
}

39
async function fetchMyOpenMergeRequests() {
F
Fatih Acet 已提交
40 41 42 43 44 45
  const project = await fetchCurrentProject();

  if (project) {
    return await fetch(`/projects/${project.id}/merge_requests?scope=created-by-me&state=opened`);
  }

46
  return [];
47 48 49
}

async function fetchLastPipelineForCurrentBranch() {
F
Fatih Acet 已提交
50
  const project = await fetchCurrentProject();
51

F
Fatih Acet 已提交
52 53 54 55
  if (project) {
    const branchName = await gitService.fetchTrackingBranchName();
    const pipelinesRootPath = `/projects/${project.id}/pipelines`;
    const pipelines = await fetch(`${pipelinesRootPath}?ref=${branchName}`);
56 57

    if (pipelines.length) {
F
Fatih Acet 已提交
58
      return await fetch(`${pipelinesRootPath}/${pipelines[0].id}`);
59 60 61 62 63 64 65 66
    }

    return null;
  }

  return null;
}

F
Fatih Acet 已提交
67 68 69 70 71 72 73 74 75 76 77 78 79
async function fetchCurrentProject() {
  const remote = await gitService.fetchGitRemote();

  if (remote) {
    const { namespace, project } = remote;
    const projectData = await fetch(`/projects/${namespace}%2F${project}`);

    return projectData || null;
  }

  return null;
}

F
Fatih Acet 已提交
80 81 82 83 84
/**
 * GitLab API doesn't support getting open MR by commit ID or branch name.
 * Using this recursive fetcher method, we fetch 100 MRs at a time and do pagination
 * until we find the MR for current branch. This method will retry max 5 times.
 */
F
Fatih Acet 已提交
85 86 87 88 89
async function fetchOpenMergeRequestForCurrentBranch() {
  const project = await fetchCurrentProject();
  const branchName = await gitService.fetchTrackingBranchName();
  let page = 1;

F
Fatih Acet 已提交
90
  // Recursive fetcher method to find the branch MR in MR list.
F
Fatih Acet 已提交
91 92 93 94 95 96 97 98 99 100 101
  async function fetcher() {
    const mrs = await fetch(`/projects/${project.id}/merge_requests?state=opened&per_page=100&page=${page}`);

    const [mr] = mrs.filter((mr) => {
      return mr.source_branch === branchName;
    });

    if (mr) {
      return mr;
    }

F
Fatih Acet 已提交
102
    if (page <= 5) { // Retry max 5 times.
F
Fatih Acet 已提交
103 104 105 106 107 108 109 110
      page = page + 1;
      return await fetcher();
    }
  }

  return project ? await fetcher() : null;
}

F
Fatih Acet 已提交
111 112 113 114
/**
 * @private
 * @param {string} token GL PAT
 */
F
Fatih Acet 已提交
115 116 117 118
const _setGLToken = (token) => {
  glToken = token;
}

119
exports.fetchUser = fetchUser;
120 121 122
exports.fetchMyOpenMergeRequests = fetchMyOpenMergeRequests;
exports.fetchOpenMergeRequestForCurrentBranch = fetchOpenMergeRequestForCurrentBranch;
exports.fetchLastPipelineForCurrentBranch = fetchLastPipelineForCurrentBranch;
F
Fatih Acet 已提交
123
exports.fetchCurrentProject = fetchCurrentProject;
F
Fatih Acet 已提交
124
exports._setGLToken = _setGLToken;