问题描述
想要在共享的CI runner上运行一个定时的流水线,能够在他的仓库上开启一个合并请求。他想要运行一个脚本,检查是否存在他固定包的更新,如果有更新,应该更新这些包并在一个新的分支上开启一个合并请求。他使用的是https://gitlab.com而不是自托管的GitLab实例。
然而,推送到他的仓库失败,无论是使用ssh还是https,都提示身份验证被拒绝。
remote: You are not allowed to upload code.
fatal: unable to access 'https://gitlab-ci-token:[MASKED]@gitlab.com/<username>/example.git/': The requested URL returned error: 403
或者
remote: HTTP Basic: Access denied
fatal: Authentication failed for 'https://<username>:@gitlab.com/<username>/example.git/'
他的gitlab-ci.yml文件大致如下:
doSth:
image: image
script:
- chmod 700 doSth.sh
- chmod 700 autoUpgrade.sh
- ./doSth.sh
- ./autoUpgrade.sh
他的autoUpgrade.sh文件大致如下:
#!/bin/bash
if [[ `git status --porcelain` ]]; then
git config --global user.email "email@example.com"
git config --global user.name "example"
export BRANCH_NAME=change-sth-`date +"%s"`
git checkout -b ${BRANCH_NAME}
git add -u
git commit -m 'change sth.'
# I tried using ssh and https
# chmod 0400 $CI_DEPLOY_KEY
# GIT_SSH_COMMAND="ssh -i ${CI_USER_TOKEN}" git push --set-upstream origin ${BRANCH_NAME}
git push https://${CI_USER}:${CI_USER_TOKEN}@gitlab.com/${CI_PROJECT_PATH}.git ${BRANCH_NAME}
else
echo "Nothing changed"
fi
解决方案
请注意以下操作注意版本差异及修改前做好备份。
方案1
在GitLab中,使用共享CI runner进行提交并推送到仓库是可能的。但是,你需要使用一个具有写入仓库权限的有效凭据。
以下是解决方案的步骤:
1. 生成一个新的个人访问令牌。你可以在项目的“设置”->“访问令牌”中创建一个具有读写仓库权限的访问令牌。
2. 将访问令牌添加到GitLab CI/CD的secrets中。你可以在项目的“设置”->“CI/CD”->“Variables”中添加一个名为API_TOKEN
的变量,并将访问令牌的值作为变量的值。
3. 在你的CI/CD配置文件中,使用访问令牌进行身份验证。你可以在autoUpgrade.sh
脚本中使用以下命令:
git push https://${CI_REGISTRY_USER}:${API_TOKEN}@${CI_REPOSITORY_URL#*@} ${BRANCH_NAME}
在上面的命令中,${CI_REGISTRY_USER}
是预定义的变量,${API_TOKEN}
是你在步骤2中创建的访问令牌,${CI_REPOSITORY_URL}
是GitLab仓库的URL。
请注意,${CI_REPOSITORY_URL#*@}
是一个bash字符串操作,用于删除URL中的用户名部分。
方案2
请注意以下操作注意版本差异及修改前做好备份。
另一种解决方案是使用预定义的变量${CI_REGISTRY_USER}
和${CI_REPOSITORY_URL}
来进行身份验证,并重置现有origin的URL。
以下是解决方案的步骤:
1. 在你的CI/CD配置文件的before_script
部分,使用以下命令将origin的URL重置为使用${CI_REGISTRY_USER}
和${API_TOKEN}
进行身份验证:
before_script:
- git remote set-url origin https://${CI_REGISTRY_USER}:${API_TOKEN}@${CI_REPOSITORY_URL#*@}
在上面的命令中,${CI_REGISTRY_USER}
是预定义的变量,${API_TOKEN}
是你在步骤1中创建的访问令牌,${CI_REPOSITORY_URL}
是GitLab仓库的URL。
请注意,${CI_REPOSITORY_URL#*@}
是一个bash字符串操作,用于删除URL中的用户名部分。
我建议你使用项目的访问令牌而不是用户的访问令牌。你可以在项目的“设置”->“访问令牌”中创建一个具有读写仓库权限的访问令牌。
请注意,这些解决方案中的命令和变量可能需要根据你的具体情况进行调整。
以上是两种解决方案,你可以根据自己的需求选择其中之一来解决问题。希望对你有所帮助!