在 GitLab 中创建标签时查找源分支(使用 gitlab-ci.yml)

Posted

技术标签:

【中文标题】在 GitLab 中创建标签时查找源分支(使用 gitlab-ci.yml)【英文标题】:Find source branch when creating Tag in GitLab (using gitlab-ci.yml) 【发布时间】:2020-09-13 22:01:33 【问题描述】:

我目前正在尝试自动增加版本,将 SNAPSHOT 附加到它并提交到使用 GitLab 12.9.2 和 GitLab-Shell 12.0.0 创建给定标签的分支。

我知道,标签(尤其是发布标签)应该是从 master 创建的,但是由于我可能会得到一个开发或其他分支,我想在其上标记提交,所以我想保留能够标记给定的提交、构建、部署相应的工件(到 Nexus)、自动增加版本(例如从 0.1.30.1.4-SNAPSHOT)和提交到创建标签的分支。

虽然所有其他步骤都有效,但我在最后一步失败了,因为我找不到正确的环境变量,它指的是创建标签的提交(和分支)。

这是 CI 文件的摘录:

build-release:
  extends: .build-template

  only:
    - tags

  before_script:
# Setup git
    - git config http.sslVerify false
    - git config user.email "git-bot@base/gitlab"
    - git config user.name "$GIT_CI_USER"
    - git remote set-url origin https://$GIT_CI_USER:$GIT_CI_PASSWORD@base/gitlab/development/particles/particles-front.git
    - git fetch
#    - git config http.sslCAInfo /etc/gitlab-runner/certs/base.crt ?
#    - git config http.sslCert /etc/gitlab-runner/certs/base.crt ? 

    - cd $CI_BUILDS_DIR/$SUB_PATH
# Install node_modules
    - npm install
# Show versions
    - node --version
    - npm --version
    - npm run ng version
# Save version for artifact-name
    - echo -n $CI_COMMIT_TAG > $CI_BUILDS_DIR/$SUB_PATH/version
# Set version back via npm in order to display it possibly on the user interface
    - npm version $(cat $CI_BUILDS_DIR/$SUB_PATH/version)

  after_script:
# Auto-Increment (patch-)version, append SNAPSHOT, commit & push
    - git checkout $CI_COMMIT_REF_NAME
    - cd $CI_BUILDS_DIR/$SUB_PATH
    - cat $CI_BUILDS_DIR/$SUB_PATH/version
    - npm version patch | cut -c 2-30 | tr -d '\n' > $CI_BUILDS_DIR/$SUB_PATH/version
    - echo -n -SNAPSHOT >> $CI_BUILDS_DIR/$SUB_PATH/version
    - npm version $(cat $CI_BUILDS_DIR/$SUB_PATH/version)
    - npm run prestart
    - git add ./package*.json ./src/_versions.ts
    - git status -sb
    - git commit -m "New Snapshot ($(cat $CI_BUILDS_DIR/$SUB_PATH/version))"
    - git push

我得到的错误(在最后一个命令中,如作业的输出控制台中所示):

$ git push
fatal: You are not currently on a branch.
To push the history leading to the current (detached HEAD)
state now, use
    git push origin HEAD:<name-of-remote-branch>

注意:一切正常,除了提交$CI_COMMIT_REF_NAME 似乎是个坏主意,因为它只包含标签(在上述情况下),但不包含提交(因此分支)标签是从创建的。我在这里谈论这个特殊的价值: .

我已经阅读了各种其他与主题相关的 SO 问题(例如这个:How do I push to a repo from within a gitlab CI pipeline?),但它们似乎并没有解决我的问题。 使用--points-at 的另一个解决方案似乎很有趣,但我不知道如何以某种方式使用它,这将帮助我解决我的问题。

感谢任何帮助!

【问题讨论】:

【参考方案1】:

对于 gitlab 版本 14.1.7,作业的分支显示在变量 $CI_COMMIT_BRANCH 中,如果您在作业中调用 shell 脚本,该变量也可以作为环境变量访问

echo CI_COMMIT_BRANCH: $CI_COMMIT_BRANCH
echo CI_COMMIT_SHA   : $CI_COMMIT_SHA
echo CI_COMMIT_TAG   : $CI_COMMIT_TAG
# or like mentioned in the accepted answer to see all evnv vars something like
printenv #optionally followed by `|grep CI_`

【讨论】:

【参考方案2】:

一个提交标签可能在多个分支上,你可以这样处理所有分支:

deploy:
  - git fetch &> /dev/null
  - CI_COMMIT_BRANCHES=$(git for-each-ref | grep $CI_COMMIT_SHA | grep /remotes/origin/ | sed "s/.*\///")
  - 'echo Tag Branches: $CI_COMMIT_BRANCHES'  
  - >
    for CI_COMMIT_BRANCH in $CI_COMMIT_BRANCHES; do
      echo "Deploy branch $CI_COMMIT_BRANCH"    
    done

【讨论】:

【参考方案3】:

你可以试试这个:

git branch -a --contains tags/<TAG> | grep origin | sed 's/.*origin\///'

【讨论】:

【参考方案4】:

我喜欢使用的一个有用技巧是从管道作业运行printenv Linux 命令。这将打印所有环境变量,包括 GitLab 内置变量到标准输出。然后你可以浏览这些并选择你想要的。

据我所知,可能对您有所帮助的是提交 SHA 或提交消息。

使用提交 SHA

CI_COMMIT_SHA CI_COMMIT_SHORT_SHA = CI_COMMIT_SHA 的前 8 位

CI_COMMIT_SHA 指的是您创建标签的分支上的提交。获得提交 ID 后,您可以使用 GitLab REST API(例如使用 cURL、python 请求或 python-gitlab)来提取您需要的信息。请记住,一次提交可能属于多个分支,因此您需要确定要针对哪个分支。

curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/repository/commits/$CI_COMMIT_SHA/refs?type=all"
[
  "type": "branch", "name": "'test'",
  "type": "branch", "name": "add-balsamiq-file",
  "type": "branch", "name": "wip",
  "type": "tag", "name": "v1.1.0"
 ]

要详细了解您可以从提交 SHA 中获得的信息:

https://docs.gitlab.com/ee/api/commits.html#get-a-single-commit https://docs.gitlab.com/ee/api/commits.html#get-references-a-commit-is-pushed-to

使用提交消息

CI_COMMIT_MESSAGE = CI_COMMIT_TITLE + CI_COMMIT_DESCRIPTION CI_COMMIT_TITLE CI_COMMIT_DESCRIPTION

如果您遵循特定的 git 进程,提交消息可能会有所帮助。例如,这是当合并请求自动压缩提交并将功能分支合并到开发时自动生成的提交消息的格式。此消息来自的标签是从开发中创建的:

Merge branch 'feature-branch-name' into 'develop'
Merge request title
See merge request group/project!123

注意:第一行是CI_COMMIT_TITLE,后两行是CI_COMMIT_DESCRIPTIONCI_COMMIT_TITLE 为您提供源分支和目标分支,而CI_COMMIT_DESCRIPTION 为您提供合并请求标题和 ID。您可以使用 GitLab REST API 从 MR ID 获得几乎所有需要的信息。

要详细了解您可以从合并请求 ID 中获得哪些信息:

https://docs.gitlab.com/ee/api/merge_requests.html#get-single-mr

不幸的是,如果您从功能分支创建标签,那么COMMIT_MESSAGE 只会为您提供推送提交的用户编写的正常提交消息 - 可能不是很有趣。 COMMIT_DESCRIPTION 在这种情况下是空白的,所以也没有用。

【讨论】:

我实际上还没有考虑过卷曲我的 GitLab 以获取信息 - 谢谢!我敢打赌这会有用!另一方面:我似乎通过这样做实现了我的目标:CI_SOURCE_BRANCH=$(git for-each-ref | grep $(git show-ref --dereference $CI_COMMIT_TAG -s --abbrev=7 --tags) | grep origin | grep -v $CI_COMMIT_TAG | sed "s/.*\///"); git checkout $CI_SOURCE_BRANCH。它从标签中确定提交哈希并使用git for-each-ref 在分支中找到它。我也排除了带注释的提交分支本身(使用grep -v)。 你认为我的方法可能有问题 @igor 不,我不认为你的方法是错误的。你能用$CI_COMMIT_SHA替换$(git show-ref --dereference $CI_COMMIT_TAG -s --abbrev=7 --tags)吗?这将使它更具可读性。最后,它归结为偏好。我已经使用 GitLab REST API 很长时间了,所以我刚刚习惯了它并开发了许多可重用的 python/bash 脚本。你也可以用 git 命令做同样的事情。只要它能完成工作并且涵盖您的所有用例。 我实际上就是这样做的(在阅读您最近的评论之前的片刻),你猜怎么着?有效!这是我确定源分支的方式:CI_SOURCE_BRANCH=$(git for-each-ref | grep $CI_COMMIT_SHORT_SHA | grep origin | sed "s/.*\///")。现在我的构建发布,增加版本,附加 SNAPSHOT 并为新的 SNAPSHOT 版本发布管道!谢谢!您使用 CI_COMMIT_SHA 的建议很棒(虽然我使用了 CI_COMMIT_SHORT_SHA,但都一样)!谢谢!

以上是关于在 GitLab 中创建标签时查找源分支(使用 gitlab-ci.yml)的主要内容,如果未能解决你的问题,请参考以下文章

如何使用标签 API 在 Gitlab CI 中创建标签?

在 GitLab 中创建合并请求失败

如何在 GitLab 中创建发布?

gitlab怎么创建merge request

GitLab:孤儿分支的 GUI 选项

在gitlab中获取分支的创建者(分支列表)