如何仅在标记的 Master 分支上运行 .gitlab-ci.yml 作业?
job:
script:
- echo "Do something"
only:
- master
- tags
如果存在任一条件,上述代码将运行:主分支或标记提交。
我的目标是让这个运行用于生产部署,但它需要它在 Master 分支上并被标记(带有版本)。否则,如果它缺少标签,我将有另一份工作将推进到分期。
此行为将在版本12中引入。
Open issue最近更新:
Jason Lenny @jlenny 将标题从 {-Update .gitlab-ci.yml 更改为 支持构建条件的连接逻辑-}到连接逻辑 对于构建条件 MVC · 2 天前
Jason Lenny @jlenny 将里程碑更改为 12.0 · 2 天前
(手指交叉)
一个解决方案是使用
except
关键字排除所有分支,结合 only
在标签上运行,这样你只在主分支中的标签上运行你的管道:
only:
- tags
except:
- branches
我正在使用版本
11.3.4
感谢像 Matt Alioto 这样的人,他发布了有关 open issue 的信息(标有
Product Vision 2019
所以希望他们今年能解决它)。
具体到 Carlson Cole 的问题,这会起作用:
job_for_master_no_tags:
stage: deploy
script:
- echo "Release to Staging"
only:
- master
job_for_master_tags_only:
stage: deploy
script:
- echo "Release to Production"
only:
- tags
except:
- /^(?!master).+@/ # Ruby RegEx for anything not starting with 'master'
- /^(?!master).+/
(没有 @
)它不起作用 - 学到了困难的方法 😕 我让它与这个工作代码片段一起工作,所有其他的都不适合我
only:
- tags # please mention the "s" compared to Sergio Tomasello's solution
except:
- branches
我用的是11.4.3
我有同样的问题。我想在 push 或 merge 上触发对我们的暂存环境的部署,并且仅当 applying a tag 将其部署到我们的生产环境时。
为此我们需要 2 个变量:
$CI_COMMIT_BRANCH
和 $CI_COMMIT_TAG
。使用这些变量,我们可以推断管道是由提交或标记触发的。不幸的是,第一个变量仅在分支上提交时设置,而第二个变量仅在应用标签时设置。所以这不是解决方案......
所以我通过仅在按指定约定和手动触发器设置标签时才执行生产发布来寻求次佳设置。 这是我的 .gitlab-ci.yml 文件:
stages:
- deploy:staging
- deploy:prod
deploy-to-staging:
stage: deploy:staging
rules:
- if: $CI_COMMIT_BRANCH == 'master'
script:
- echo "Deploying to Staging..."
deploy-to-production:
stage: deploy:prod
rules:
- if: $CI_COMMIT_TAG =~ /^v(?:\d+.){2}(?:\d+)$/
when: manual
script:
- echo "Deploying to Production..."
如果你真的想自动化这个,你必须做一些脚本来查明应用的标签是否真的属于主分支上的提交。查看关于 GitLab issuetracker 的评论以获取更多信息:https://gitlab.com/gitlab-org/gitlab-foss/-/issues/31305#note_28580169
多年后,仍在尝试在 master 分支上的标签上启动工作...
Gitlab 的问题已经关闭:https://gitlab.com/gitlab-org/gitlab-foss/-/issues/27818
不可能在主分支上发现标签,因为 Git 不以这种方式工作。分支和标签是单独的引用,每个都指向一个提交。因此,标签与分支无关。
我的解决方案是检查标签名称以检测它是否代表生产版本:
deploy-prod:
stage: deploy-manual
only:
variables:
- $CI_COMMIT_TAG =~ /^v\d+.\d+.\d+-?.*$/
when: manual
正则表达式匹配 semver 标签名称,如:
gitlab-ci 尚不支持此行为,尽管有一个 open issue 添加它。
与此同时,我也听到传闻说
only:
- master
only:
- tags
将完成工作(以及它不会完成的轶事报道)。
只有当 master 的 HEAD 上有标签时,我才需要启用管道,并找到了以下解决方案: 该条件仅检查最后一次提交是否在标签上。 在脚本中,我比较标签的提交哈希和主 HEAD 的提交哈希,如果它们不相等,则该步骤失败
rules:
- if: '$CI_COMMIT_TAG != null
when: always
...
script:
# verifying that the tag that triggered the pipeline is done on the head of master
- latest_commit=$(git rev-parse master)
- echo "CI_COMMIT_SHA - $CI_COMMIT_SHA"
- echo "latest_commit - $latest_commit"
- if [ $latest_commit != $CI_COMMIT_SHA ]; then echo "tagging and deploying a version is allowed only on the HEAD of master"; exit 1; fi
到目前为止,gitlab 中还没有针对此问题的适当内置解决方案。为了跟踪正确解决方案的开发并更新我创建的工作解决方法:Gitlab CI:仅针对受保护分支上存在的标记提交运行管道作业
我遇到了同样的问题,这就是我试图解决的方法
my_job:
stage: build
services:
- name: docker:dind
image: docker:latest
script:
- ...
rules:
- if: $CI_COMMIT_BRANCH == 'master' && $CI_COMMIT_TAG == null
cache: {}
此作业仅在主分支上有提交时运行(不包括个人/功能分支上的任何其他提交)。以与我触发基于标签的构建相同的方式:
script:
- ...
rules:
- if: $CI_COMMIT_BRANCH == 'master' && $CI_COMMIT_TAG != null
文档实际上说
only
和 except
没有被开发,用户应该使用 rules
代替。deploy-to-prod:
stage: deploy
rules:
- if: $CI_COMMIT_TAG
environment:
name: production
variables:
API_ENVIRONMENT: prod
when: manual
我已经找到了解决方法。
.gitlab-ci.yml
build-image-prod:
stage: image
only:
refs:
- tags
variables:
- $CI_COMMIT_TAG =~ /^v.*$/
script:
- ./scripts/not-on-main $CI_COMMIT_TAG && exit 0
- echo "Image building..."
脚本/非主:
#!/bin/sh
if [ -z "$1" ]; then
echo "Missing argument with commit ref."
exit 0
fi
git fetch origin main
if git branch -r --contains "$1" | grep -q main; then
echo "Ref $1 is on main branch."
exit 1
else
echo "Ref $1 is not on main branch - exiting."
exit 0
fi
如果标签名称以“v”开头,则作业针对存储库中的每个标签运行。帮助脚本获取 main 并检查标签是否在上面。如果标签不在主分支上,则作业不构建就退出。