gitlab对接,gitlabRestApi,gitlab4j-api

发布于:2025-06-18 ⋅ 阅读:(14) ⋅ 点赞:(0)

https://www.bilibili.com/video/BV1WaNbzQEoZ


gitlab是一个常用的代码存储仓库,通常都是使用各种工具(IDEA等)创建分支,再去gitlab页面去创建/合并MR。

开发流程分支几乎都是固定的,如 feature > dev > master。现在开发几乎都是微服务,比如我们两周发一次版本,一次10-40个服务左右,在文档里面已经写好了每个MR的地址,但依旧需要每个人去合并MR,再创建 dev > master的MR,再合一遍,这里面的步骤是很长的。

基于此做了一个功能,开发填写 feature > dev 的MR,到了合适的时间,1、一键合并(dev),2、一键创建dev > master的mr,3、一键合并(master)。 原本复杂的流程,只需要三个按钮就解决了。


一、系统设计


无非是对接 gitlab的Api,这并不重要,先来看看如何设计的,后面再看怎么写代码。


1、合并的要求


代码合并流程 feature > dev > master
代码合并要求,(防止一些没有准备好的项目被误合并)

  1. 被打上了 confirmed 标签
  2. 目标分支正确(前端可以做多个按钮,一键合并dev、一键合并master)
  3. pom 里面不能有快照版
  4. 代码没有冲突
  5. 其它符合的业务的限制

2、合并的流程


其实我们更愿意先解决问题,再一起合并。所以在合并之前需要先有校验功能,当这一批次的项目都校验通过了,再去合并。(无需考虑校验到合并这期间发生的变换,内部人操作大概率不会出现这样的问题)


整个流程如下:

  1. 填写项目的MR分支(可对接查询接口,模糊搜索MR的分支)
  2. 点击校验,通过后展示「合并按钮」,不通过,弹窗提示原因 (feature > dev)
  3. 一键创建MR(功能分支不一样,但 dev > master 的源分支和目标分支都是确定的,可通过Api快速创建)
  4. 点击校验,通过后展示「合并按钮」,不通过,弹窗提示原因 (dev > master)

二、代码开发


1、gitlab4j-api


虽然gitlab有RestApi,自己封装还是过于麻烦,可以使用 gitlab4j-api

  1. https://archives.docs.gitlab.com/15.11/ee/api/rest/
  2. https://github.com/gitlab4j/gitlab4j-api

上面是原生Api和封装的Sdk,在开发的时候,可以先去原生Api里面找找看是否有符合的接口,再用gitlab4j-api调用


  1. rootUrl 就是gitlab请求的地址前缀
  2. token,可以在gitlab上创建一个拥有所有权限的帐号,然后基于这个帐号生成一个token

导入pom,版本号需要对应当前的gitlab

<dependency>
    <groupId>org.gitlab4j</groupId>
    <artifactId>gitlab4j-api</artifactId>
    <version>5.0.0</version>
</dependency>

2、查询MR


必须要先得到MR,才能去合并MR

try(GitLabApi gitLabApi = new GitLabApi(rootUrl, token)) {
    MergeRequestFilter mergeRequestFilter = new MergeRequestFilter();
    //默认只返回自己创建的,所以需要指定all
    mergeRequestFilter.setScope(Constants.MergeRequestScope.ALL);
    mergeRequestFilter.setSearch("模糊搜索key");
    List<MergeRequest> mergeRequests = gitLabApi.getMergeRequestApi().getMergeRequests(mergeRequestFilter, 1, 100);
    return mergeRequests;
} catch (GitLabApiException e) {
    log.error("查询MergeRequest失败", e);
}

MergeRequest 里面的字段很多,后续流程也都是基于MR来做的,这里说一下核心的参数,把 MergeRequest 转成我们需要的参数


buildGitlabMergeRequest

public static GitlabMergeRequest buildGitlabMergeRequest(MergeRequest mr) {
    if (mr == null) {
        return null;
    }
    GitlabMergeRequest gitlabMergeRequest = new GitlabMergeRequest();
    gitlabMergeRequest.setMergeRequestId(mr.getId().intValue());
    gitlabMergeRequest.setMergeRequestIid(mr.getIid().intValue());
    gitlabMergeRequest.setGitProjectId(mr.getProjectId().intValue());
    gitlabMergeRequest.setTitle(mr.getTitle());
    gitlabMergeRequest.setSourceBranch(mr.getSourceBranch());
    gitlabMergeRequest.setTargetBranch(mr.getTargetBranch());
    gitlabMergeRequest.setLabels(mr.getLabels());
    gitlabMergeRequest.setState(mr.getState());
    gitlabMergeRequest.setMergeStatus(mr.getMergeStatus());
    return gitlabMergeRequest;
}

GitlabMergeRequest 结构

public class GitlabMergeRequest {

    /**
     * git项目ID
     */
    private Integer gitProjectId;

    /**
     * merge request id
     */
    private Integer mergeRequestId;

    /**
     * merge request iid(项目内部ID,查询MR详情需要用这个ID)
     */
    private Integer mergeRequestIid;

    /**
     * merge request title
     */
    private String title;

    /**
     * source branch
     */
    private String sourceBranch;

    /**
     * target branch
     */
    private String targetBranch;

    /**
     * 标签
     */
    private List<String> labels;

    /**
     * 状态
     * opened=打开, closed=关闭, locked=锁定, merged=已合并
     */
    private String state;

    /**
     * 合并状态
     * unchecked=Git 还未测试是否可以进行有效合并。
     * checking=Git 正在测试是否可以进行有效合并。
     * can_be_merged=可以合并。
     * cannot_be_merged=不能合并。
     * cannot_be_merged_recheck=不能合并,需要重新检查。
     */
    private String mergeStatus;
}

2、获取单个MR详情


try(GitLabApi gitLabApi = new GitLabApi(rootUrl, token)) {
    MergeRequest mergeRequest = gitLabApi.getMergeRequestApi().getMergeRequest(gitlabMergeRequest.getGitProjectId().longValue(), gitlabMergeRequest.getMergeRequestIid().longValue());
    return GitlabFormatUtils.buildGitlabMergeRequest(mergeRequest);
} catch (GitLabApiException e) {
    log.error("查询MergeRequest失败", e);
}

GitlabMergeRequest 结构参考查询MR中的,自定义封装的参数


3、合并MR

try(GitLabApi gitLabApi = new GitLabApi(rootUrl, token)) {
    MergeRequest mergeRequest = gitLabApi.getMergeRequestApi().acceptMergeRequest(gitlabMergeRequest.getGitProjectId().longValue(), gitlabMergeRequest.getMergeRequestIid().longValue());
    return GitlabFormatUtils.buildGitlabMergeRequest(mergeRequest);
} catch (GitLabApiException e) {
    log.error("合并MergeRequest失败,gitlabMergeRequest:{}", gitlabMergeRequest, e);
}

  1. GitlabMergeRequest 结构参考查询MR中的,自定义封装的参数
  2. MR合并只能一个个来,没有批量的

4、创建MR


try(GitLabApi gitLabApi = new GitLabApi(rootUrl, token)) {
    MergeRequestParams mrParams = new MergeRequestParams()
            .withSourceBranch(param.getSourceBranch())
            .withTargetBranch(param.getTargetBranch())
            .withTitle(param.getTitle())
            .withDescription(param.getDescription())
            .withLabels(param.getLabels());
    MergeRequest  mergeRequest = gitLabApi.getMergeRequestApi().createMergeRequest(param.getGitProjectId().longValue(), mrParams);
    return GitlabFormatUtils.buildGitlabMergeRequest(mergeRequest);
} catch (GitLabApiException e) {
    log.error("创建MergeRequest失败", e);
}

5、分支对比


try (GitLabApi gitLabApi = new GitLabApi(rootUrl, token)) {
    CompareResults compareResults = gitLabApi.getRepositoryApi().compare(param.getGitProjectId().longValue(), param.getSourceBranch(), param.getTargetBranch(), true);
    return compareResults.getDiffs();
} catch (GitLabApiException e) {
    log.error("对比分支失败", e);
}

创建MR是为了代码合并,如果dev > master 并没有任何改变,创建一个无法合并的MR也是不好的,在创建MR之前可以获取Diff来判断是否有必要创建


6、获取MR的Diff


MR合并的时候一般不允许有 SNAPSHOT版本,可以通过Diff来判断字符串里面是否有 SNAPSHOT

当把 SNAPSHOT删掉的时候在Diff里面也会存在,但 dev/master里面存在 SNAPSHOT本身也是不合理的


try(GitLabApi gitLabApi = new GitLabApi(rootUrl, token)) {
    MergeRequest mergeRequest = gitLabApi.getMergeRequestApi().getMergeRequestChanges(gitlabMergeRequest.getGitProjectId().longValue(), gitlabMergeRequest.getMergeRequestIid().longValue());
    return mergeRequest.getChanges();
} catch (GitLabApiException e) {
    log.error("查询MergeRequest changes失败", e);
}

网站公告

今日签到

点亮在社区的每一天
去签到