云计算百科
云计算领域专业知识百科平台

GitLab CI 迁到内置流水线:YAML 怎么改写

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */
#content_views .toc,
/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */
#content_views.markdown_views > p:empty:has(+ .toc),
#content_views.markdown_views > .toc + p:empty,
/* 富文本旧版目录标记 */
#content_views.htmledit_views #main-toc,
#content_views.htmledit_views #hr-toc,
#content_views.htmledit_views p[id*=\”-toc\”] {
display: none !important;
}
/* 目录去掉后,紧跟的首个标题不再多出一块上边距 */
#content_views.markdown_views > .toc + h1,
#content_views.markdown_views > .toc + h2,
#content_views.markdown_views > .toc + h3,
#content_views.markdown_views > .toc + h4,
#content_views.markdown_views > .toc + p:empty + h1,
#content_views.markdown_views > .toc + p:empty + h2,
#content_views.markdown_views > .toc + p:empty + h3,
#content_views.markdown_views > .toc + p:empty + h4 {
margin-top: 0 !important;
}

这篇讲怎么把 .gitlab-ci.yml 用 导入 GitLab CI 转成 AngusGit 流水线,以及保存前要改什么。看完你可以对照未映射清单和注意清单,处理转不过去的 artifacts、rules 和 when,补上分支限制,避免部署在没人点击时就自动跑;导入不会替你新建凭证。

AngusGit 的流水线在团队版和企业版中提供,社区版没有 CI/CD 菜单。如果你还没写过 AngusGit 的流水线,建议先看文末参考里的 YAML 入门一文,了解 Job(流水线里的一组步骤)、运行器(Runner,真正执行任务的那台机器)这些基本概念。 导入 GitLab CI:转换之后先看清单,核对完再创建

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(输入框占位文字是「输入流水线名称」)。

  • 核对清单后再创建

    从流水线列表打开时,对话框右下角的按钮是 创建流水线;从空白创建页打开同一个对话框时,这个位置是 填入编辑器。如果清单里的问题还没改完,点 取消 即可,仓库里不会留下流水线。 导入 GitLab CI 的转换结果:未映射四条、注意三条,流水线名称是 imported-from-gitlab 转换完成后,对话框中间会滚到两份清单(更上方的粘贴框可能被滚出视野),标题、说明和右下角的 取消、创建流水线 仍在。清单内容如下,四条未映射是:

    • jobs.build.artifacts
    • jobs.test rules/only/except(仅用于推断触发器;完整条件未映射)
    • jobs.deploy rules/only/except(仅用于推断触发器;完整条件未映射)
    • jobs.deploy.when

    三条注意是:

    • jobs.deploy 无 image,映射为 NATIVE
    • CI_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 当成布尔值,导出时特意加了引号来避开。这是转换后的初稿,保存前还必须处理未映射项。 左边是原配置,右边是转换初稿:deploy 仍会自动跑

    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。

    参考文章

    • AngusGit 手册:流水线基础
    • AngusGit 手册:流水线进阶
    • 仓库能推之后:内置流水线 YAML 怎么写
    • 从 GitLab 迁到 AngusGit:迁移清单、双跑和回滚
    • 流水线跑到审批节点:谁点了才能继续
    • 运行器不接任务:标签、在线和并发对不上
    赞(0)
    未经允许不得转载:网硕互联帮助中心 » GitLab CI 迁到内置流水线:YAML 怎么改写
    分享到: 更多 (0)

    评论 抢沙发

    评论前必须登录!