这篇讲怎么把 .gitlab-ci.yml 用 导入 GitLab CI 转成 AngusGit 流水线,以及保存前要改什么。看完你可以对照未映射清单和注意清单,处理转不过去的 artifacts、rules 和 when,补上分支限制,避免部署在没人点击时就自动跑;导入不会替你新建凭证。
AngusGit 的流水线在团队版和企业版中提供,社区版没有 CI/CD 菜单。如果你还没写过 AngusGit 的流水线,建议先看文末参考里的 YAML 入门一文,了解 Job(流水线里的一组步骤)、运行器(Runner,真正执行任务的那台机器)这些基本概念。
1. 一份用来转换的 .gitlab-ci.yml
下面这份配置专门用来演示转换,并不是哪个线上仓库正在使用的文件。它分三个阶段:先构建,再测试,最后在 main 分支上手动触发部署。
stages:
- build
- test
- deploy
variables:
MAVEN_OPTS: "-Dmaven.repo.local=.m2"
build:
stage: build
image: maven:3.9-eclipse-temurin-21
tags: [docker]
script:
- mvn -B -DskipTests package
artifacts:
paths: [target/*.jar]
test:
stage: test
image: maven:3.9-eclipse-temurin-21
tags: [docker]
script:
- mvn -B test
rules:
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
- if: '$CI_COMMIT_BRANCH == "main"'
deploy:
stage: deploy
tags: [deploy]
script:
- ./deploy.sh $CI_COMMIT_SHORT_SHA
when: manual
only: [main]
2. 用控制台导入,先拿到初稿
打开导入对话框
进入 CI/CD → 流水线,点 新建流水线。菜单里有 空白创建、根据仓库生成、导入 GitHub Actions、导入 GitLab CI 四项,后两项下面都有一行小字「部分语法自动转换,导入后请校验」。这里选 导入 GitLab CI。
粘贴内容并转换
对话框标题是 导入 GitLab CI,说明文字是「子集映射为 AngusCICD YAML。include / 完整 rules / child pipeline 不会展开,请看未映射清单。」也就是说,只有一部分语法会被转换。默认页签是 粘贴 YAML(旁边还有 扫描仓库),输入框的名称是 GitLab CI,提示文字是「粘贴 .gitlab-ci.yml 内容」。把第 1 节的整段 YAML 贴进去,点 转换。
看两份清单
转换结果显示在输入框下方,从上到下依次是 未映射(需人工改)、注意、流水线名称,最后是 YAML 编辑器。流水线名称会自动填成
imported-from-gitlab(输入框占位文字是「输入流水线名称」)。核对清单后再创建
从流水线列表打开时,对话框右下角的按钮是 创建流水线;从空白创建页打开同一个对话框时,这个位置是 填入编辑器。如果清单里的问题还没改完,点 取消 即可,仓库里不会留下流水线。

转换完成后,对话框中间会滚到两份清单(更上方的粘贴框可能被滚出视野),标题、说明和右下角的 取消、创建流水线 仍在。清单内容如下,四条未映射是:
jobs.build.artifactsjobs.test rules/only/except(仅用于推断触发器;完整条件未映射)jobs.deploy rules/only/except(仅用于推断触发器;完整条件未映射)jobs.deploy.when
三条注意是:
jobs.deploy 无 image,映射为 NATIVECI_COMMIT_SHORT_SHA → commitSha(完整 SHA,不是短 SHA)GitLab CI_* 预定义变量已近似改写;其余 CI_* 运行时不会注入
第一条注意里的 NATIVE,和下面初稿里的 DOCKER,是 AngusGit 的两种执行模式:DOCKER 在指定镜像启动的容器里执行命令,NATIVE 直接在运行器所在的机器(宿主机)上执行。转换成功的项不会逐条列出,编辑器里生成的初稿如下:
version: '1'
name: imported-from-gitlab
triggers:
- 'on': push
- 'on': pull_request
env:
MAVEN_OPTS: -Dmaven.repo.local=.m2
pipeline:
build:
runner:
mode: DOCKER
image: maven:3.9-eclipse-temurin-21
labels:
- docker
steps:
- name: script
run: mvn -B -DskipTests package
test:
runner:
mode: DOCKER
image: maven:3.9-eclipse-temurin-21
labels:
- docker
steps:
- name: script
run: mvn -B test
needs:
- build
deploy:
runner:
mode: NATIVE
labels:
- deploy
steps:
- name: script
run: ./deploy.sh ${
{
commitSha }}
needs:
- test
初稿里的 'on' 带引号,是因为 YAML 会把不加引号的 on 当成布尔值,导出时特意加了引号来避开。这是转换后的初稿,保存前还必须处理未映射项。
3. 对照表:哪些转了,哪些没转
先看能自动转换的部分。其中最需要理解的是 stages:GitLab CI 用阶段来排先后,AngusGit 没有阶段,改为让后一个 Job 用 needs 声明它要等哪个 Job 完成。
导入会自动转过去的:
| GitLab CI | 初稿里的样子 | 说明 |
|---|---|---|
script |
步骤名 script,命令在 run |
单行脚本的步骤名就是 script |
image |
runner.mode: DOCKER 加 runner.image |
镜像名原样保留,仍是 maven:3.9-eclipse-temurin-21 |
没写 image |
runner.mode: NATIVE |
例如 deploy,注意里写了「jobs.deploy 无 image,映射为 NATIVE」 |
tags |
runner.labels |
docker、deploy 原样变成标签 |
variables |
流水线级 env |
MAVEN_OPTS 写在了顶层 env |
stages |
后一个阶段的 Job 写 needs |
test 依赖 build,deploy 依赖 test。stages 本身不保留 |
rules 里的合并请求 |
触发器多了一条 pull_request |
完整的 if 没有写进 Job |
allow_failure |
continue-on-error |
这份示例里没有 |
environment |
只保留环境名称 | 这份示例里没有。有的话,注意会写「只保留名称,无 GitLab environment 保护规则」 |
接下来是没转过去的部分。下表先列出要点,表后再逐条展开。
这份示例没转过去、保存前要处理的:
| 你在清单里看到的 | 初稿实际做了什么 | 保存前怎么改 |
|---|---|---|
jobs.build.artifacts |
target/*.jar 不会传给后面的 Job |
本例可先不改 |
jobs.test 和 jobs.deploy 的 rules / only |
只用来推断触发器,main 没变成 branches |
给触发器补上 branches: [main] |
jobs.deploy.when |
丢掉了 when: manual,deploy 仍在且 needs: [test] |
删掉 deploy 另建一条,或加 approval |
include、retry、timeout、dependencies、trigger |
本例没有,出现时会进未映射清单 | 见表后说明 |
artifacts(构建产物):这份示例的test自己会再跑一遍mvn test,不读那个 jar,所以两个 Job 可以先保持原样。如果下游脚本要读上一个 Job 生成的文件,就把相关步骤并进同一个 Job,或者先上传到制品库再下载。rules/only:初稿里的push和pull_request都没有branches: [main]。不改的话,其他分支也会触发这条流水线,而且deploy会跟着运行。when:when: manual被丢掉后,部署会在每次触发时自动执行。不想自动部署,就把deploy从这条流水线里删掉,另建一条用workflow_dispatch(只能手动运行)触发的流水线,或者给这个 Job 加approval(审批)。- 其他字段:用了
include的,要先把被引用的片段合并进一份 YAML 再导入;Job 级的retry、timeout要改写到步骤上,单位是秒;用trigger触发的下游流水线要拆开单独处理。
定时任务也能导入,但 cron 要自己补。 cron 是描述定时规则的表达式。GitLab 的定时规则配置在页面上,不写在 YAML 里。所以,YAML 里如果有 only: schedules,或者 rules 的条件里写了 schedule,导入会加上 on: schedule,同时在未映射里写明「schedule cron 未映射(GitLab 定时在 UI,不在 YAML)」。这时 cron 要你自己补上,格式是五段式,例如 0 2 * * *。第 1 节的示例没有定时,所以初稿里也没有 on: schedule。
4. CI_* 变量要特别检查
GitLab 运行时会自动提供一批以 CI_ 开头的预定义变量,AngusGit 不会注入它们。导入时只会把下表这几个改写成 ${
{ }} 表达式,并不会改成环境变量 GIT_COMMIT_SHA:
| GitLab 变量 | 导入后 | 这份示例 |
|---|---|---|
$CI_COMMIT_SHA |
${
{ commitSha }} |
示例脚本里没有 |
$CI_COMMIT_SHORT_SHA |
同样是 ${
{ commitSha }},完整 SHA |
deploy 命令变成 ./deploy.sh ${
{ commitSha }} |
$CI_COMMIT_BRANCH |
${
{ branch }} |
只在 test 的 rules 里,那条 if 没写进 Job |
$CI_PIPELINE_SOURCE |
${
{ event }} |
同样只用来推断出 pull_request |
$CI_COMMIT_TAG |
${
{ ref }} |
本例没有,出现时注意写「CI_COMMIT_TAG → ref(近似)」 |
其中 $CI_COMMIT_SHORT_SHA 最容易出错。注意原文是 CI_COMMIT_SHORT_SHA → commitSha(完整 SHA,不是短 SHA),也就是说,改写后拿到的是完整的提交号。如果你要 8 位短 SHA,就在 shell 里自己截取 $GIT_COMMIT_SHA,不要以为 ${
{ commitSha }} 已经是短的。
表外的其他 CI_ 变量,例如 CI_PROJECT_DIR、CI_PIPELINE_ID、CI_REGISTRY,运行时都不会注入。只要原文有变量被改写过、又还留着 CI_ 变量,注意里就会有这一句:「GitLab CI* 预定义变量已近似改写;其余 CI* 运行时不会注入」。自己写的脚本可以改用平台提供的环境变量 GIT_REPO_URL、GIT_BRANCH、GIT_COMMIT_SHA。
还有一类变量要留意:名字以 TOKEN、SECRET、PASSWORD、PASSWD、PRIVATE_KEY、ACCESS_KEY 或 API_KEY 结尾时,导入会把这个名字写进 Job 的 secrets 名单,并在注意里写「$名字 → env.名字,并写入 Job secrets 名单」。这时 AngusGit 里必须先有同名凭证,否则 Job 会失败并提示 Credential not visible or expired。导入不会替你创建凭证,要自己在 CI/CD → 配置 → 凭证 里新建。第 1 节没有这类变量,所以初稿里没有 secrets。
5. 保存前建议改成什么样
这份初稿不能直接保存,因为有两处和原配置的意思相反:一是 only: [main] 没有变成 branches: [main],其他分支也会触发;二是 when: manual 丢了,deploy 仍会在 test 之后自动运行。
建议把它拆成两条流水线。第一条保留构建和测试,并补上分支限制。镜像先沿用转换结果;如果内网拉不到 Docker Hub,再把 maven:3.9-eclipse-temurin-21 换成平台镜像 repo.anguskit.com/docker-public/angus-ci-maven:21。下面是手动改完后的写法,并非导入器直接给出的初稿:
version: "1"
name: imported-from-gitlab
triggers:
- "on": push
branches: [main]
- "on": pull_request
branches: [main]
env:
MAVEN_OPTS: "-Dmaven.repo.local=.m2"
pipeline:
build:
runner:
mode: DOCKER
image: maven:3.9-eclipse-temurin-21
labels: [docker]
steps:
- name: script
run: mvn -B -DskipTests package
test:
needs: [build]
runner:
mode: DOCKER
image: maven:3.9-eclipse-temurin-21
labels: [docker]
steps:
- name: script
run: mvn -B test
注意 needs 只决定先后顺序,不会把 target/*.jar 传给 test。这里之所以还能分成两个 Job,是因为 test 自己执行 mvn test,用不到那个 jar。如果部署脚本要读这个 jar,就把打包和部署写成同一个 Job 里的两个步骤。
第二条流水线只放部署,并且只允许手动运行。脚本参数里的 ${
{ commitSha }} 仍然是完整 SHA。建议写成:
version: "1"
name: deploy
triggers:
- "on": workflow_dispatch
pipeline:
deploy:
runner:
mode: NATIVE
labels: [deploy]
steps:
- name: script
run: ./deploy.sh "${
{
commitSha }}"
如果希望部署仍然跟在构建后面,但要由指定的人批准后才继续,就给这个 Job 加 approval;已经被丢掉的 when: manual 起不到这个作用。具体做法见文末参考里的流水线审批一文。
6. 真要保存时先验证一次
改完之后,按下面三步把流水线建起来并验证:
通过运行前检查
如果对话框是从列表打开的,点 创建流水线;如果是从空白创建页打开的,先点 填入编辑器,再在创建页保存。保存前平台会做运行前检查:通过时页面显示「检查通过,可以保存。」;提示「请先修复错误」时,按提示修改。最常见的原因是 YAML 里还留着
stages、variables这类 GitLab 字段。手动跑一次
在流水线详情页点 触发,分支 / 标签 填一个测试分支,然后确认 Job 被带
docker标签的运行器接走。要小心:如果deploy还留在同一条流水线里,这次运行就会真的执行部署命令。再看自动触发
手动运行通过后,再发起一个拉取请求,确认
pull_request能正常触发,并且结果写回了拉取请求页的状态检查(页面上标明流水线是否通过的那一项)。
迁移期间,.gitlab-ci.yml 可以先留在仓库里,AngusGit 不会执行它。等新的流水线稳定运行之后再删除。
常见问题
迁移后最常遇到的情况如下:
| 你看到的 | 原因 | 怎么处理 |
|---|---|---|
| Job 一直排队 | 没有在线的运行器同时满足 mode 和 labels |
运行器要带 docker 标签,并能跑对应的执行模式 |
| Job 没在容器里,直接跑在宿主机上 | 原 Job 没有写 image,变成了 NATIVE |
补上 runner.mode: DOCKER 和 runner.image |
后面的 Job 找不到 target/*.jar |
artifacts 在未映射里,needs 不传文件 |
合成一个 Job,或经制品库中转 |
| 部署在没人点击时就跑了 | when: manual 未映射,Job 仍在流水线里 |
删掉这个 Job,或改成 workflow_dispatch / approval |
非 main 的分支也跑了部署 |
only: [main] 没有写成 branches |
给 push 和 pull_request 加上 branches: [main] |
| 脚本里某个路径或编号是空的 | 用了没有注入的 CI_* 变量 |
按第 4 节替换,短 SHA 用 $GIT_COMMIT_SHA 自己截 |
合并进 main 后没有自动构建 |
拉取请求页的合并不会触发 on: push,只有 git push 会 |
用 pull_request 在合并前跑构建和测试 |
能不能一次导入多个文件?
不能,对话框一次只处理一份 YAML。如果项目用了 include(在一份 YAML 里引用其他 YAML 片段),要先把被引用的文件合并成一份再导入,否则未映射里会写「include(不拉取远程/本地片段,须先展开再导入)」。
转换结果能不能直接用?
这份示例的初稿不能直接用,因为 deploy 会自动运行,分支限制也丢了。先按第 5 节改好这两处,再保存。
小结
把 .gitlab-ci.yml 贴进 导入 GitLab CI 再点 转换,得到的是一份需要人工核对的初稿,本例名为 imported-from-gitlab,其中 script、image、tags、variables、stages 分别转成了步骤、DOCKER 模式、标签、env 和 needs。以第 1 节为例,未映射的是 jobs.build.artifacts、两处 rules/only/except 和 jobs.deploy.when;注意清单则提醒 deploy 变成了 NATIVE,$CI_COMMIT_SHORT_SHA 变成了完整的 ${
{ commitSha }}。最要紧的是,when: manual 不会变成手动 Job,only: [main] 也不会变成分支限制,不改的话部署会在其他分支上自动运行。所以要逐项核对、改完再创建流水线,并自己建好需要的凭证,因为导入不会新建凭证。
结论: 导入 GitLab CI 给出的只是转换后的初稿,保存前要处理未映射的
artifacts和when,把丢掉的only: [main]补成触发器上的branches: [main],并记住${ { commitSha }}拿到的是完整 SHA,不是短 SHA。