GitLab runner,推送时出错,而同样的事情在控制台上的gitbash或python上也能工作



上下文

我们正在尝试做一个GitLab runner工作,在某个标记上修改一个版本头文件,并向该变更集添加一个发布分支/标记。

GitLab runner服务器在我的机器上,由我的用户作为服务启动(已正确注册到我们的GitLab服务器(。

GitLab runner job基本上启动了一个使用gitpython来完成作业的python脚本,runner yml文件中只有一些更改(添加了before_script部分以获得上传权限,从那里获得:https://stackoverflow.com/a/55344804/11159476),这是完整的.gitlab-ci.yml文件:

variables:
GIT_SUBMODULE_STRATEGY: recursive
stages: [ build, publish, release ]
release_tag:
stage: build
before_script:
- git config --global user.name ${GITLAB_USER_NAME}
- git config --global user.email ${GITLAB_USER_EMAIL}
script:
- python .scriptsrelease_gitlab_runner.py
only:
# Trigger on specific regex...
- /^Src_V[0-9]+.[0-9]+.[0-9]+$/
except:
# .. only for tags then except branches, see doc (https://docs.gitlab.com/ee/ci/yaml/#regular-expressions): "Only the tag or branch name can be matched by a regular expression."
- branches

推送时还在python URL中添加了技巧(用user:personal_access_token@repo_URL推送,而不是默认的runner URL,从上面的相同答案中得到,令牌已经从公司gitlab=>user"Settings"=>"Access Tokens"=>"Add a personal Access token"生成,具有所有权限,永远不会过期(,这里是,不是实际的scriptsrelease_gitlab_runner.pypython脚本,而是一个简化为具有尽可能多的git流标准的脚本(获取所有,使用随机名称创建本地分支,使其不存在,修改文件,暂存,提交,最后推送(:

# -*-coding:utf-8 -*
import uuid
import git
import sys
import os
# Since we are in <git root path>/scripts folder, git root path is this file's path parent path
GIT_ROOT_PATH = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
try:
# Get user login and URL from GITLAB_USER_LOGIN and CI_REPOSITORY_URL gitlab environment variables
gitlabUserLogin = os.environ["GITLAB_USER_LOGIN"]
gitlabFullURL = os.environ["CI_REPOSITORY_URL"]
# Push at "https://${GITLAB_USER_NAME}:${PERSONAL_ACCESS_TOKEN}@gitlab.companyname.net/demo/demo.git")
# generatedPersonalAccessToken has been generated with full rights from https://gitlab.companyname.net/profile/personal_access_tokens and set in a variable not seen here
gitlabPushURL = "https://{}:{}@{}".format(gitlabUserLogin, generatedPersonalAccessToken, gitlabFullURL.split("@")[-1])
print("gitlabFullURL is [{}]".format(gitlabFullURL))
print("gitlabPushURL is [{}]".format(gitlabPushURL))
branchName = str(uuid.uuid1())
print("Build git.Repo object with [{}] root path".format(GIT_ROOT_PATH))
repo = git.Repo(GIT_ROOT_PATH)
print("Fetch all")
repo.git.fetch("-a")
print("Create new local branch [{}]".format(branchName))
repo.git.checkout("-b", branchName)
print("Modify file")
versionFile = os.path.join(GIT_ROOT_PATH, "public", "include" , "Version.h")
patchedVersionFileContent = ""
with open(versionFile, 'r') as versionFileContent:
patchedVersionFileContent = versionFileContent.read()
patchedVersionFileContent = re.sub("#define VERSION_MAJOR 0", "#define VERSION_MAJOR {}".format(75145), patchedVersionFileContent)
with open(versionFile, 'w') as versionFileContent:
versionFileContent.write(patchedVersionFileContent)
print("Stage file")
repo.git.add("-u")
print("Commit file")
repo.git.commit("-m", "New version file in new branch {}".format(branchName))
print("Push new branch [{}] remotely".format(branchName))
# The error is at below line:
repo.git.push(gitlabPushURL, "origin", branchName)
sys.exit(0)
except Exception as e:
print("Exception: {}".format(e))
sys.exit(-1)

问题

即使使用了拥有权限的技巧,当我们试图从GitLab runner推送时,也会出现以下错误:

Cmd('git') failed due to: exit code(1)
cmdline: git push https://user:token@gitlab.companyname.net/demo/repo.git origin 85a3fa6e-690a-11ea-a07d-e454e8696d31
stderr: 'error: src refspec origin does not match any
error: failed to push some refs to 'https://user:token@gitlab.companyname.net/demo/repo.git''

什么有效

如果我打开一个Git Bash,我成功地运行了手动命令:

git fetch -a
git checkout -b newBranch
vim public/include/Version.h
=> At this point file has been modified
git add -u
git commit -m "New version file in new branch"
git push origin newBranch

在这里,如果我们从其他地方获取所有信息,我们可以看到带有版本文件修改的newBranch

同样,如果我们从python命令行运行脚本内容(不修改URL((假设已经执行了脚本中的所有导入(:

GIT_ROOT_PATH = "E:\path\to\workspace\repo"
branchName = str(uuid.uuid1())
repo = git.Repo(GIT_ROOT_PATH)
repo.git.fetch("-a")
repo.git.checkout("-b", branchName)
versionFile = os.path.join(GIT_ROOT_PATH, "public", "include" , "Version.h")
patchedVersionFileContent = ""
with open(versionFile, 'r') as versionFileContent:
patchedVersionFileContent = versionFileContent.read()
patchedVersionFileContent = re.sub("#define VERSION_MAJOR 0", "#define VERSION_MAJOR {}".format(75145), patchedVersionFileContent)
with open(versionFile, 'w') as versionFileContent:
versionFileContent.write(patchedVersionFileContent)
repo.git.add("-u")
repo.git.commit("-m", "New version file in new branch {}".format(branchName))
repo.git.push("origin", branchName)

结论

在GitLab runner上运行时,我找不到我做错了什么,是不是遗漏了什么?

当我从GitLab runner运行时,我唯一能看到的不同之处是,在获取后,我可以看到我处于一个分离的头上(清单repo.git.branch('-a').split('n')给出了例如['*(head departed at 560976b(','branchName','remotes/origin/otherExistingBranch',…](,但这应该不是问题,因为我创建了一个新的分支来推送,对吧?

Git说您使用了错误的refspec。当你需要推送其他遥控器时,你必须先将其设为gitlab = repo.create_remote("gitlab", gitlabPushURL),然后像repo.push("gitlab", branchName)一样推送。

从@glutony编辑为在下一次git运行时不中断"远程已经存在":

remote_name = "gitlab"
if remote_name not in repo.remotes:
repo.create_remote(remote_name, gitlabPushURL)

最新更新