Skip to main content

gitlab-ci.yml

tip
  • 使用 extends 复用现有逻辑
  • 使用 !reference [.setup, before_script] 复用部分逻辑 - 例如合并多个 before_script
  • 可以使用 YAML 引用逻辑
# 自定义默认配置
default:
# 基础镜像
image: wener/node:docker
cache:
# 缓存仓库里所有 untracked 文件
untracked: true
# 缓存按分支划分 - 如果有 tag 这个会是 tag 名字
key: '$CI_COMMIT_REF_NAME'
# 常见的缓存目录
paths:
- node_modules/
- .yarn/
- .cache/
- .next/
- packages/server/.next/cache/

环境变量

enve.gdesc
CItrue表示在运行 CI
GITLAB_CItrue
CI_REGISTRYgitlab registry
CI_REGISTRY_USERgitlab registry user
CI_REGISTRY_PASSWORDgitlab registry password
CI_REGISTRY_IMAGE项目容器镜像
CI_DEFAULT_BRANCHmain默认 branch 名字
CI_COMMIT_REF_NAMEmainbranch or tag
CI_COMMIT_REF_SLUGmainCI_COMMIT_REF_NAME 用于 url 或名字时,63 位,替代[^0-9a-z]-
CI_COMMIT_REF_PROTECTEDtrue保护分支
CI_COMMIT_BRANCHmain
CI_COMMIT_SHA
CI_COMMIT_SHORT_SHA
CI_COMMIT_TAG
CI_COMMIT_TIMESTAMPISO 8601
CI_COMMIT_TITLE第一行 commit 信息
CI_ENVIRONMENT_NAME
CI_ENVIRONMENT_SLUG
CI_ENVIRONMENT_URL
CI_ENVIRONMENT_ACTIONstart, prepare, stop
CI_ENVIRONMENT_TIERproduction,staging,testing,development,other
CI_KUBERNETES_ACTIVEtrue关联了 k8s 部署集群
CI_PROJECT_ID
CI_PROJECT_NAME
CI_PROJECT_NAMESPACE用户名 或 组名
CI_PROJECT_ROOT_NAMESPACE
CI_PROJECT_PATH_SLUG
CI_PROJECT_PATH
docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" $CI_REGISTRY
# 常用 $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG
docker build --pull -t "$CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG" ./build
docker push "$CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG"

job:only/except

caution
  • 开发不活跃,推荐,使用 rules
build:
script: npm run build
only:
# 简单配置 - refs
# 完整匹配 - master 分支运行
- master
# 支持正则 匹配 tag 或 branch - 如果 排除了 branches 则是匹配 tag
- /^issue-.*$/i

# 高级配置
# 不指定默认则是 refs 匹配
refs:
- master
- schedules
# 变量匹配
variables:
- $CI_COMMIT_MESSAGE =~ /run-end-to-end-tests/ # 匹配变量
- $RELEASE == "staging" # 变量满足
- $STAGING # 有变量
# 复杂条件变量
- ($CI_COMMIT_BRANCH == "master" || $CI_COMMIT_BRANCH == "develop") && $MY_VARIABLE
# 匹配变化文件
# 只有在 branches external_pull_requests merge_requests 有效
changes:
- README.md
- "*.md" # 例如 从新生成文档
- base/Dockerfile # 例如 重构基础镜像
- "**/*.sql" # 例如 数据库迁移
# 要求开启了 k8s 服务
kubernetes: active
except:
# 支持使用关键词 - 分支不触发
- branches
# 可包含仓库信息匹配 - 用于 fork 场景
- /^release/.*$/@gitlab-org/gitlab
valuedesc
apiPipline API 触发
branchesref 是分支
chatChatOps 创建的 Pipeline
external外部 CI 服务
external_pull_requests外部仓库 PR,例如 Github
merge_requests仓库收到 pr
pipelines流水线中创建的多项目 pipeline
pushesgit push 触发
schedules调度触发
tagsref 是 tag
triggerstrigger token 触发
webWeb 触发/运行流水线

job:rules

  • 限定 job 是否运行
  • 基础语句
    • if
      • 类似 only:variables 配置
      • &&, ||, ==, !=, =~, !~
      • CI_PIPELINE_SOURCE 用于支持类似 rules 的关键字
    • changes
      • 类似 only:changes 配置
    • exists
      • 包含指定文件
  • 语句属性
    • when - 限定运行条件
      • on_success, delayed, always
      • never - 不触发 - 等同于 rules:except
      • manual - 手动触发时
    • allow_failure - 是否允许运行错误
    • changes 文件变化
    • variables 定义额外变量
build:
script: npm run build
rules:
- if: '$CI_COMMIT_BRANCH == "master"'
when: delayed
start_in: '3 hours'
allow_failure: true
# 要求有变化文件
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
changes:
- Dockerfile
when: manual
allow_failure: true
build:
script: npm run build
rules:
# 前两个条件不满足才运行
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
when: never
- if: '$CI_PIPELINE_SOURCE == "schedule"'
when: never
- when: on_success

build:
script: npm run build
rules:
# 常见
- if: $CI_COMMIT_TAG # 有 tag
- if: $CI_COMMIT_BRANCH # 分支推送
- if: '$CI_COMMIT_BRANCH == "main"' # 主分支
- if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH' # 默认分支
- if: '$CI_COMMIT_BRANCH =~ /regex-expression/' # 分支匹配

if CI_PIPELINE_SOURCEdesc
apiPipline API 触发
chatChatOps 创建的 Pipeline
external外部 CI 服务
external_pull_request_event外部仓库 PR,例如 Github
merge_request_event仓库收到 pr
parent_pipeline
pipeline流水线中创建的多项目 pipeline
pushgit push 触发
schedule调度触发
tagsref 是 tag
triggertrigger token 触发
webWeb 触发/运行流水线
webideWebIDE

cache

位置

  • cache
    • 全局 - 不推荐,建议使用 default
  • defaul:cache
    • job 默认缓存
  • job:cache
    • job 维度缓存配置

属性

  • cache:
    • 可配置为数组 - 多个缓存
    • key:
      • 默认 default - 全局共用
      • 可设置为 $CI_COMMIT_REF_SLUG - 分支独立缓存
      • files:
        • prefix:
          • ${CI_JOB_NAME}
    • untracked:
      • 缓存仓库里所有 untracked 文件
    • paths:
      • 缓存的目录
    • when:
      • on_success - 默认 成功时保存缓存
      • on_failure
      • always
    • policy:
      • pull-push - 默认 - 启动前拉,完成后推
      • pull 只拉 - 用于已知不会修改缓存场景
      • push 只推
cache:
paths:
- my/files

rspec:
script: test
cache:
key: rspec
paths:
- binaries/

workflow

  • 限定 pipeline 是否运行/创建
  • 运行时运行覆盖变量
workflow:
rules:
- if: $CI_COMMIT_MESSAGE =~ /-draft$/
when: never
- if: $CI_COMMIT_REF_NAME =~ /feature/
variables:
IS_A_FEATURE: 'true' # 覆盖变量
- when: always #

release

# AlpineLinux
apk add gitlab-release-cli -X https://mirrors.aliyun.com/alpine/edge/testing

# shell executor 需要安装命令行根据
curl --location --output /usr/local/bin/release-cli "https://release-cli-downloads.s3.amazonaws.com/latest/release-cli-linux-amd64"
chmod +x /usr/local/bin/release-cli

# 确保可用
release-cli -v
# 基于 tag release
job:
release:
tag_name: $CI_COMMIT_TAG
description: 'Release description'
# name - 默认为 tag_name
# ref - 如果没有 tag_name 可以通过 ref 创建
# milestones - 关联里程碑
# released_at: '2021-03-15T08:00:00Z' # 不指定会自动生成

---
# 直接调用命令行 - 可以添加 assets-link
# gitlab 内置 artifact https://gitlab.com/org/proj/-/jobs/<JOB_ID>/artifacts/browse
release:
stage: release
image: registry.gitlab.com/gitlab-org/release-cli:v0.4.0
# 手动触发
when: manual
rules:
- if: $CI_COMMIT_TAG
when: never

script:
- >
release-cli create --name release-branch-$CI_JOB_ID --description release-branch-$CI_COMMIT_REF_NAME-$CI_JOB_ID
--tag-name job-$CI_JOB_ID --ref $CI_COMMIT_SHA
--assets-link '{"name":"Asset1","url":"https://<domain>/some/location/1","link_type":"other","filepath":"xzy"}'
--assets-link '{"name":"Asset2","url":"https://<domain>/some/location/2"}'
--milestone "v1.0.0" --milestone "v1.0.0-rc"
--released-at "2020-06-30T07:00:00Z"

---
release_job:
stage: release
image: registry.gitlab.com/gitlab-org/release-cli:latest
rules:
- if: $CI_COMMIT_TAG # Run this job when a tag is created manually
script:
- echo 'running release_job'
release:
name: 'Release $CI_COMMIT_TAG'
description: 'Created using the release-cli $EXTRA_DESCRIPTION' # $EXTRA_DESCRIPTION must be defined
tag_name: '$CI_COMMIT_TAG' # elsewhere in the pipeline.
ref: '$CI_COMMIT_TAG'
milestones:
- 'm1'
- 'm2'
- 'm3'
released_at: '2020-07-15T08:00:00Z' # Optional, is auto generated if not defined, or can use a variable.
---
prepare_job:
stage: prepare # This stage must run before the release stage
rules:
- if: $CI_COMMIT_TAG
when: never # Do not run this job when a tag is created manually
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH # Run this job when commits are pushed or merged to the default branch
script:
- echo "EXTRA_DESCRIPTION=some message" >> variables.env # Generate the EXTRA_DESCRIPTION and TAG environment variables
- echo "TAG=v$(cat VERSION)" >> variables.env # and append to the variables.env file
artifacts:
reports:
dotenv: variables.env # Use artifacts:reports:dotenv to expose the variables to other jobs

release_job:
stage: release
image: registry.gitlab.com/gitlab-org/release-cli:latest
needs:
- job: prepare_job
artifacts: true
rules:
- if: $CI_COMMIT_TAG
when: never # Do not run this job when a tag is created manually
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH # Run this job when commits are pushed or merged to the default branch
script:
- echo 'running release_job for $TAG'
release:
name: 'Release $TAG'
description: 'Created using the release-cli $EXTRA_DESCRIPTION' # $EXTRA_DESCRIPTION and the $TAG
tag_name: '$TAG' # variables must be defined elsewhere
ref: '$CI_COMMIT_SHA' # in the pipeline. For example, in the
milestones: # prepare_job
- 'm1'
- 'm2'
- 'm3'
released_at: '2020-07-15T08:00:00Z' # Optional, is auto generated if not defined, or can use a variable.

FAQ

部署 pages

pages:
script:
- yarn
- yarn build:public
artifacts:
# 必须是 public 目录
paths:
- public
only:
- master

有 Tag 的时候才执行

build-tag:
only:
# 指定分支
- master
# 必须有 tag
- tags

或者

rules:
# 没有 tag 的时候才执行
- if: $CI_COMMIT_TAG != ""
when: on_success
- when: never

默认分支

  • master 或 main 或 自定义的默认分支
only:
variables:
- $CI_DEFAULT_BRANCH == $CI_COMMIT_REF_NAME