我有一个 monorepo,每个包都应该构建为 docker。当所有更改的包都进行了 dockerized 后,我想使用 helmfile 进行部署
我为每个触发子管道的包创建了一个触发器作业。
我正在寻找一种方法来获取子管道中生成的值,例如父管道中的 docker 标签或图表版本。
我需要将这些值用于所有子管道完成后发生的部署阶段。
.gitlab-ci.yml
---
trigger-package-a:
stage: build
trigger:
include: .gitlab/ci/packages/package-gitlab-ci.yml
strategy: depend
rules:
- changes:
- "packages/package-a/**/*"
variables:
PACKAGE: package-a
trigger-package-b:
stage: build
trigger:
include: .gitlab/ci/packages/package-gitlab-ci.yml
strategy: depend
rules:
- changes:
- "packages/package-b/**/*"
variables:
PACKAGE: package-b
done_job:
stage: deploy
script:
- "echo DONE"
- "cat config.json"
stages:
- build
- deploy
package-gitlab-ci.yml
stages:
- bootstrap
- validate
cache:
key: "${PACKAGE}_${CI_COMMIT_REF_SLUG}"
paths:
- packages/${PACKAGE}/node_modules/
policy: pull
install-package:
stage: bootstrap
script:
- echo ${PACKAGE}}
- echo '{"package":${PACKAGE}}' > config.json
- "cd packages/${PACKAGE}/"
- yarn install --frozen-lockfile
artifacts:
paths:
- config.json
cache:
key: "${PACKAGE}_${CI_COMMIT_REF_SLUG}"
paths:
- packages/${PACKAGE}/node_modules/
policy: pull-push
lint-package:
script:
- yarn lint
stage: validate
needs: [install-package]
before_script:
- "cd packages/${PACKAGE}/"
我只能通过 GitLab CI API 获取工件来获取值和文件
上一篇 - 为您的用户 Gitlab 创建令牌并 创建变量 GITLAB_USER_TOKEN
done_job:
image: nexus/docker-images/ansible:2.9.24-9
stage: done_job
script:
- yum install -y unzip
- >
export CI_CHILD_PIPELINE_ID=$(curl --header "PRIVATE-TOKEN: $GITLAB_USER_TOKEN" "$CI_API_V4_URL/projects/$CI_PROJECT_ID/pipelines/$CI_PIPELINE_ID/bridges" | jq ".[].downstream_pipeline.id")
- echo $CI_CHILD_PIPELINE_ID
- >
export CI_CHILD_JOB_ID=$(curl --header "PRIVATE-TOKEN: $GITLAB_USER_TOKEN" "$CI_API_V4_URL/projects/$CI_PROJECT_ID/pipelines/$CI_CHILD_PIPELINE_ID/jobs" | jq '.[].id')
- echo $CI_CHILD_JOB_ID
- 'curl --output artifacts.zip --header "PRIVATE-TOKEN: $GITLAB_USER_TOKEN" "$CI_API_V4_URL/projects/$CI_PROJECT_ID/jobs/$CI_CHILD_JOB_ID/artifacts"'
- unzip artifacts.zip
- "echo DONE"
- "cat config.json"
- rm -rf artifacts.tar
我在这里插话,因为我找到了一种轻松做到这一点的方法。
使用公共密钥(如 $CI_COMMIT_SHA)创建一个缓存并将其置于默认值,以便管道中的所有作业都使用它。然后将环境目录添加到缓存中。 这将缓存添加到 env/ 目录的所有文件
cache:
key: ${CI_COMMIT_SHA}
paths:
- .env/*.env
要使用缓存,您需要使用键值条目写入 .env/ 目录中的 .env 文件,然后稍后读取它
example.write.to.cache:
script:
- echo "EXAMPLE_VAR="EXAMPLE_VALUE" >> .env/${CI_COMMIT_SHA}-${CI_JOB_NAME}.env
接下来,您希望有一个作业将获取 .env/ 目录中的所有文件并将它们组合成一个键值文件。以及将新创建的文件添加为 dotenv 工件。
source.env.vars.from.cache:
stage: build
script:
- cat .env/*.env >> ${CI_PIPELINE_ID}.env
- cat ${CI_PIPELINE_ID}.env
artifacts:
reports:
dotenv: ${CI_PIPELINE_ID}.env
这将为所有作业和管道(父级->子级和子级->父级)创建一个 .env 缓存,其中一个操作顺序很重要。
注意:如果 2 个作业打开了缓存并对其进行写入,则最后一个写入的作业将覆盖另一个作业。
要使用缓存中定义的变量,您必须有一个“需要”语句来指向存档缓存的作业。
print.cache.varible:
script:
- echo "EXAMPLE_VAR=${EXAMPLE_VAR}"
needs:
- job: source.env.vars.from.cache
完整示例: 在此示例中,我们创建 2 个子管道,将变量写入第一个子管道的缓存中,然后从第二个子管道中读取它。如果您要在第一个服务运行之后且使用作业之前运行 source.env.vars.from.cache 作业,您还可以从父级读取变量。
注意:工件变量将覆盖默认变量和作业级别变量。
.gitlab-ci.yml
service_1:
stage: build
trigger:
include:
- local: ".service_1.yml"
strategy: depend
service_2:
stage: build
needs:
- job: service_1 # This will force service_2 to wait for service_1 to complete
trigger:
include:
- local: ".service_2.yml"
strategy: depend
.service_1.yml
cache:
key: ${CI_COMMIT_SHA}
paths:
- .env/*.env
write.to.cache:
script:
- echo "SERVICE_1_VAR="ABCD-1234" >> .env/${CI_COMMIT_SHA}-${CI_JOB_NAME}.env
.service_2.yml
cache:
key: ${CI_COMMIT_SHA}
paths:
- .env/*.env
source.env.vars.from.cache:
stage: .pre
script:
- cat .env/*.env >> ${CI_PIPELINE_ID}.env
- cat ${CI_PIPELINE_ID}.env
artifacts:
reports:
dotenv: ${CI_PIPELINE_ID}.env
print.cache.varible:
stage: build
script:
- echo "SERVICE_1_VAR=${SERVICE_1_VAR}"
needs:
- job: source.env.vars.from.cache
这花了我比我愿意承认的时间更长的时间,因为我没有在任何地方看到这个解决方案,所以我想我会发布它。