如何通过gitlab-ci.yml更新GitLab仓库中的JSON文件内容?
问题解决方案
问题根因
- Shell语法不兼容:你使用的
amazon/aws-cli:2.2.38镜像默认使用sh作为shell,你脚本中用的[[ ]]是bash专属语法,在sh环境下执行会报错,导致更新STATUS的分支无法触发,看起来就像命令被跳过。 - 修改未同步回仓库:CI的运行环境是临时分配的容器,你修改了
firefox-versions.json后没有执行git提交、推送操作,修改仅保留在当前CI的临时环境中,任务跑完就销毁了,自然不会更新到GitLab仓库。 - jq更新逻辑错误:你当前的jq命令会把JSON里所有条目的STATUS都修改为
deployed,而非仅更新刚推送成功的对应浏览器版本的状态,且多余传入了未使用的$a参数。 - 子shell问题:你用
jq -c '.[]' firefox-versions.json | while read i的写法,while循环会在子shell中执行,部分场景下会出现变量异常、执行逻辑中断的问题。
修复步骤
1. 调整CI配置
首先在before_script段新增git安装命令,因为基础镜像默认没有git工具:
before_script: - amazon-linux-extras install -y docker - aws --version - docker --version - yum install jq git -y
然后替换script段为以下内容,同时你需要提前在GitLab项目设置中给默认CI令牌开通仓库读写权限,或者配置具有推送权限的个人访问令牌作为CI变量:
script: - cd /builds/firefox-dockerfile # 配置git提交身份信息 - git config user.name "GitLab CI Runner" - git config user.email "ci@example.com" # 拉取最新代码避免提交冲突 - git pull origin $CI_COMMIT_BRANCH - aws ecr get-login-password | docker login --username AWS --password-stdin $DOCKER_REGISTRY_DEV # 显式指定bash执行,改用for循环避免子shell问题 - > bash -c ' for i in $(jq -c ".[]" firefox-versions.json); do STATUS=$(echo $i | jq -r ".STATUS") FIREFOX_VERSION=$(echo $i | jq -r ".FIREFOX_VERSION") GECKODRIVER_VERSION=$(echo $i | jq -r ".GECKODRIVER_VERSION") # 改用sh兼容的[]条件判断 if [ "$STATUS" != "deployed" ]; then docker build -t $DOCKER_REGISTRY_DEV/$APP_NAME:"$FIREFOX_VERSION" --build-arg FIREFOX_VERSION="$FIREFOX_VERSION" --build-arg GECKODRIVER_VERSION="$GECKODRIVER_VERSION" . docker push $DOCKER_REGISTRY_DEV/$APP_NAME:"$FIREFOX_VERSION" tmp=$(mktemp) # 仅修改当前推送成功的版本的STATUS字段 jq --arg ver "$FIREFOX_VERSION" "map(if .FIREFOX_VERSION == \$ver then .STATUS = \"deployed\" else . end)" firefox-versions.json > "$tmp" && mv "$tmp" firefox-versions.json else echo "Firefox-$FIREFOX_VERSION is already created and pushed to ECR" fi done ' # 提交修改并推回GitLab仓库,加[ci skip]避免触发重复流水线 - git add firefox-versions.json - git commit -m "chore: update firefox version status [ci skip]" || echo "No status changes to commit" - git push origin $CI_COMMIT_BRANCH
2. 权限配置
进入GitLab项目的「设置」->「CI/CD」->「令牌权限」,开启CI_JOB_TOKEN的写入权限,否则推送代码会失败。如果你使用个人访问令牌,需要把令牌存为CI变量,推送时替换为https://<令牌名称>:<令牌值>@gitlab.com/你的项目路径.git格式的仓库地址即可。
内容的提问来源于stack exchange,提问作者Dinesh
相关产品推荐
相关产品推荐

