如何通过GitLab CI实现两个仓库间双向传递构建产物完成全流程
GitLab跨双仓库传递构建产物并联动CI的实现方案
前置准备
- 生成一个拥有两个仓库读写权限的个人访问令牌(PAT),权限勾选
read_repository和write_repository,将令牌存入两个仓库的CI/CD变量中,变量名设为CI_PUSH_TOKEN,同时勾选「保护变量」「掩码变量」避免凭证泄露。 - 将PAT对应的用户加入两个仓库的开发者角色,确保CI任务有代码推拉权限。
核心实现逻辑
整个流程分为3个核心阶段,通过CI管道联动、产物传递和状态轮询完成全流程闭环:
- 仓库A的CI生成原始XLF文件,推送到仓库B指定分支并触发B的CI管道
- 仓库B的CI处理XLF生成新文件,推送回仓库A对应分支
- 仓库A的CI轮询确认B处理完成后,拉取新XLF生成最终产物
仓库A .gitlab-ci.yml 配置
stages: - build - wait_process - final_build # 阶段1:编译Angular生成原始XLF文件 generate_origin_xlf: stage: build image: node:18-alpine script: # 替换为实际的Angular生成XLF命令 - npm install - ng xi18n --output-path locale/ # 推送XLF到仓库B的ci-input分支 - git config --global user.name "GitLab CI Bot" - git config --global user.email "ci-bot@example.com" - git clone https://oauth2:${CI_PUSH_TOKEN}@<你的GitLab域名>/<组名>/repo-b.git repo-b - cp locale/messages.xlf repo-b/input/ - cd repo-b - git add input/messages.xlf - git commit -m "CI: 接收仓库A ${CI_COMMIT_SHA} 生成的原始XLF" - git push origin ci-input # 触发仓库B的CI管道,记录管道ID - 'B_PIPELINE_ID=$(curl --header "PRIVATE-TOKEN: ${CI_PUSH_TOKEN}" --request POST "https://<你的GitLab域名>/api/v4/projects/<仓库B的项目ID>/pipeline?ref=ci-input&variables[A_COMMIT_SHA]=${CI_COMMIT_SHA}&variables[A_COMMIT_BRANCH]=${CI_COMMIT_BRANCH}" | jq -r ".id")' - echo ${B_PIPELINE_ID} > b_pipeline_id.txt artifacts: paths: - b_pipeline_id.txt # 阶段2:轮询等待仓库B处理完成 wait_b_process: stage: wait_process image: curlimages/curl:latest script: - B_PIPELINE_ID=$(cat b_pipeline_id.txt) # 轮询B的管道状态,超时可自行调整 - | while true; do STATUS=$(curl --header "PRIVATE-TOKEN: ${CI_PUSH_TOKEN}" "https://<你的GitLab域名>/api/v4/projects/<仓库B的项目ID>/pipelines/${B_PIPELINE_ID}" | jq -r ".status") if [ "${STATUS}" = "success" ]; then echo "仓库B处理完成" break elif [ "${STATUS}" = "failed" ] || [ "${STATUS}" = "canceled" ]; then echo "仓库B处理失败,终止当前管道" exit 1 fi echo "等待仓库B处理中,10秒后重试" sleep 10 done # 拉取B推送回来的已处理XLF - git pull origin ${CI_COMMIT_BRANCH} # 阶段3:生成最终输出文件 build_final_output: stage: final_build image: node:18-alpine script: # 替换为实际的最终编译命令 - npm install - ng build --localize artifacts: paths: - dist/ # 最终产物存储路径
仓库B .gitlab-ci.yml 配置
stages: - process_xlf process_xlf: stage: process_xlf only: - ci-input # 仅在接收输入的ci-input分支触发 script: # 替换为实际的XLF处理命令,处理后输出到指定路径 - your-xlf-process-command input/messages.xlf output/messages.xlf # 推送处理后的XLF回仓库A对应分支 - git config --global user.name "GitLab CI Bot" - git config --global user.email "ci-bot@example.com" - git clone https://oauth2:${CI_PUSH_TOKEN}@<你的GitLab域名>/<组名>/repo-a.git repo-a - cp output/messages.xlf repo-a/locale/processed/ - cd repo-a - git add locale/processed/messages.xlf - git commit -m "CI: 仓库B处理完成XLF,对应A的提交${A_COMMIT_SHA}" - git push origin ${A_COMMIT_BRANCH}
注意事项
- 配置中
<>包裹的内容(GitLab域名、项目ID、文件路径、业务命令等)需要替换为实际环境的对应值 - 若要节省CI资源,可去掉轮询等待阶段,改为仓库B处理完成后调用API直接触发仓库A的最终构建阶段
- 可根据业务需要调整轮询间隔和超时阈值,避免CI任务无限挂起
内容的提问来源于stack exchange,提问作者Sathish Kumar
相关产品推荐
相关产品推荐

