【问题标题】:GitLab CI: Get source branch after merge-request has been acceptedGitLab CI:合并请求被接受后获取源分支
【发布时间】:2020-05-09 15:27:06
【问题描述】:

我有一个 master 分支,它应该只能通过将“release/xxxxx”分支合并到其中或将“hotfix/xxxxx”分支合并到其中来获得提交。

发布分支的管道构建一个 docker 镜像并使用标签“beta”发布它。
发布分支的管道构建一个 docker 镜像并使用标签“hotfix”发布它。

master 的管道只需将“beta”重新标记为“stable”(当发布分支已合并到 master 中时)或“hotfix”到“stable”(当 hotfix 分支已合并到掌握)。然后它还会为该版本创建一个新的 git 标签并在 gitlab 中发布。最终部署 docker 镜像。

目前发生以下情况:

  • 创建合并请求以将“release/xxxxx”合并到“master”。
  • 管道自动启动(在合并请求被接受和合并之前)。
  • docker 作业解析CI_MERGE_REQUEST_SOURCE_BRANCH_NAME 变量以确定合并请求的源分支是发布分支。
  • 然后 docker 作业将“beta”重新标记为“latest”。
  • git tag 作业为项目添加版本标签和gitlab release。
  • 部署作业部署 docker 映像。

当最终接受合并请求时,会发生以下情况:

  • 管道再次启动。
  • docker 作业解析 CI_MERGE_REQUEST_SOURCE_BRANCH_NAME 现在为空,因此无法确定此合并的源分支。
  • docker 作业失败。

我认为很明显我不想在合并请求被接受之前运行所有这些作业(尤其是部署作业)。

但我想不出一个好方法,只在接受合并请求后在主服务器上运行管道,然后仍然能够确定源分支。

【问题讨论】:

  • 你能分享你的gitlab-ci.yml文件吗?
  • 我的实际.gitlab-ci.yml 是一个大杂烩,每个分支最多处理 13 个工作,而且我的问题中提到的 3 个分支要多得多。更不用说它包含来自其他非公共项目的一堆文件,使用自定义非公共 docker 图像并严重依赖于组和项目级别设置的环境变量的事实。我无法分享所有这些,单独的 .gitlab-ci.yml 对任何人都无济于事。
  • 我了解您的情况,但我们很难假设您的配置为管道和部署都高度依赖 yml 文件。
  • 你找到解决办法了吗?

标签: git merge gitlab gitlab-ci branching-and-merging


【解决方案1】:

仅使用存储在 git 中的信息:

在合并请求被接受后运行时,HEAD 提交应该是合并的结果,所以HEAD^2 应该是被合并分支的头部提交。

您可以获得以下信息:

  • 直接指向这个提交的标签:

    git tag --points-at HEAD^2
    
  • 直接指向此提交的分支:

    git branch --points-at HEAD^2    # for local branches
    git branch -r --points-at HEAD^2 # for remote branches
    
  • 包含此提交的分支:

    git branch --contains HEAD^2    # for local branches
    git branch -r --contains HEAD^2 # for remote branches
    

使用 gitlab 设置的环境变量:

在阅读了predefined variables doc page 之后,我很惊讶没有找到表明在接受合并请求后触发作业的变量。

你可以查看 gitlab 的 webhooks : Merge requests events ;这些应该提供足够的信息来确定合并请求被接受后涉及哪些分支。

【讨论】:

  • 当我尝试你的命令时,我有一个“错误:错误的对象名称'HEAD^2'”
  • @BastienSander :这意味着您当前的活动提交不是合并提交(HEAD^2 表示“HEAD 的第二个父级”,仅当 HEAD 是合并提交时才有效)
  • 这对我不起作用,所以我改为git log --skip=1 -1
【解决方案2】:

看来你可以通过gitlab的API来实现。

这是一个 curl 示例。

  - MR_BRANCH_LAST_COMMIT_SHA=$(
      curl -s \
        --header "PRIVATE-TOKEN: $CI_PRIVATE_TOKEN" \
        "$CI_API_V4_URL/projects/$CI_PROJECT_ID/repository/commits/$CI_COMMIT_SHA" |\
        jq -r '.parent_ids | del(.[] | select(. == "'$CI_COMMIT_BEFORE_SHA'")) | .[-1]'
    )
  - MR_BRANCH_NAME=$(
      curl -s \
        --header "PRIVATE-TOKEN: $CI_PRIVATE_TOKEN" \
        "$CI_API_V4_URL/projects/$CI_PROJECT_ID/repository/commits/$MR_BRANCH_LAST_COMMIT_SHA/merge_requests" |\
        jq -r '.[0].source_branch'
    )

我在这里找到了解决方法: https://forum.gitlab.com/t/run-job-in-ci-pipeline-only-on-merge-branch-into-the-master-and-get-merged-branch-name/24195/5

【讨论】:

猜你喜欢
  • 2023-01-21
  • 2021-05-21
  • 1970-01-01
  • 2019-05-17
  • 2019-03-15
  • 2021-12-24
  • 2020-02-17
  • 2016-02-27
  • 1970-01-01
相关资源
最近更新 更多