如何使用 gitlab-ci 作业推送到 gitlab 存储库?

Posted

技术标签:

【中文标题】如何使用 gitlab-ci 作业推送到 gitlab 存储库?【英文标题】:How do you push to a gitlab repo using a gitlab-ci job? 【发布时间】:2018-12-30 03:24:44 【问题描述】:

我是 GitLab CI/CD 作业的新手,但我正在尝试设置一个 Python 脚本,该脚本在推送到 GitLab 时会触发 CI/CD 作业以运行它,并调用再次推送到 GitLab 的内部函数前提是满足某些标准。因此,例如,假设我有以下内容:

def hasFileInDirectory():
    # checks if the current directory has at least 1 other file in it
    if (1 or more files exist):
        print 'Great! You have enough files!';
    else:
        print 'Oh no! You need more files! Let me create one!';
        createFile('missingFile'+str(random.randint(0,1000000)+'.txt');
        os.system('git add -A');
        os.system('git commit -m "Automatically added new file..."');
        os.system('git push origin HEAD:master --force');

如果我自己从命令行运行此函数,它似乎运行得非常好,但是,它似乎无法在 GitLab CI/CD 作业中运行。我得到的输出是:

remote: You are not allowed to upload code.
fatal: unable to access 'https://gitlab-ci-token:xxxxx@gitlab.com/path_to/my_repository.git/': The requested URL returned error: 403

当我调用git push 时会发生此错误,所以我想知道我能做些什么来解决这个问题。非常感谢任何帮助!

【问题讨论】:

Cannot push from gitlab-ci.yml的可能重复 【参考方案1】:

GitLab CI 运行者还不能推送到 repo:有一个 proposal in progress here。

同时,您可以use an SSH URL,与:

通过 GitLab 中的 Settings > CI/CD Pipelines Web 界面将 SSH 私钥定义为秘密变量,并且 SSH 密钥的公共部分存储为同一 Web UI 的设置 > 存储库 > 部署密钥部分的部署密钥。

或者,作为mentioned here,您可以在个人资料的设置中使用“个人访问令牌”。

我使用范围 api 创建了一个令牌,并在我的管道中进行了配置。 在 gitlab 控制台中打开项目,转到设置 > CI/CD > 秘密变量,创建一个值为键的变量(在配置文件中生成)。 我将“$CI_JOB_TOKEN”替换为我的变量“$VAR01”。

使用 gitlab-ci.yml

script:
   - url_host=`git remote get-url origin | sed -e "s/https:\/\/gitlab-ci-token:.*@//g"`
   - git remote set-url origin "https://gitlab-ci-token:$CI_TAG_UPLOAD_TOKEN@$url_host"

CI_TAG_UPLOAD_TOKEN 是 Secret 变量

【讨论】:

两种解决方案都有缺点。 “ssh url”不能在某些环境中使用,只有 http 访问是可能的。而“个人访问令牌”是个人的 - 当 CI 工作想要更改存储库中的某些内容时 - 它不应该来自某个预定义的用户帐户,而应该来自开始工作的那个。 @Ezh 那么使用部署令牌(docs.gitlab.com/ce/user/project/deploy_tokens)而不是用户令牌?那应该行得通。并符合您的条件。 @VonC 部署令牌不能用于写入存储库。使用可以使用它们来读取存储库或读/写注册表。 @MartinŽid 好的,那么没有部署令牌。【参考方案2】:

我们最终使用的命令是:

git tag my-new-tag
git push --repo=git@YOUR_REPO_URL:YOUR_GROUP/YOUR_PROJECT.git --tags

默认情况下我们得到:

remote: You are not allowed to upload code.
fatal: unable to access 'https://gitlab-ci-token:xxxxxxxxxxxxxxxxxxxx@YOUR_REPO_URL:YOUR_FORK/YOUR_PROJECT.git/': The requested URL returned error: 403`

原因是因为 CI 运行程序使用 HTTPS 协议执行 git 命令,其令牌不支持 @VonC 所述的推送。

我们已将运行器配置为与/root/.ssh 目录共享一个卷。因此,使用git 协议和适当的ssh 配置,我们可以使用Gitlab CI 运行器推送git 命令。

编辑

gitlab runner 执行如下(为了清楚起见,我删除了无用的参数)

docker exec -it gitlab-runner.service gitlab-runner register \
  --non-interactive \
  --name `hostname` \
  --url "some-gitlab-url" \
  ...
  --executor "docker" \
  --limit "1" \
  --docker-image "debian" \
  --docker-volumes "/var/run/docker.sock:/var/run/docker.sock" \
  --docker-volumes "/fs1/runner/builds:/builds" \
  --docker-volumes "/fs1/runner/cache:/cache" \
  --docker-volumes "/fs1/runner/profile:/root" \

所以/root 目录在我们所有的跑步者之间共享。因此,一旦正确配置了 /root/.ssh/ 正确的密钥并且这些密钥有权 push 到 gitlab,它将按上述方式工作。

【讨论】:

您能否详细说明“配置我们的运行器以将卷共享到 /root/.ssh 目录”部分。那是在“.gitlab-ci.yml”中吗? 我已经编辑了我的回复以提供更多细节。希望这会有所帮助。 @jtheoof 你是说 /root 已经安装在跑步者身上,或者你必须改变docker exec 的启动方式(如果是,那么如何)?问题是在使用gitlab-machines时,实际上是在管道启动时根据需要生成了runner,那么我该如何配置/root/.ssh呢? 顺便说一句,尽管我的令牌拥有所有可能的权限,但我确实收到了 403 错误代码。绝对没有办法通过 https 推送?

以上是关于如何使用 gitlab-ci 作业推送到 gitlab 存储库?的主要内容,如果未能解决你的问题,请参考以下文章

如何从 gitlab CI 管道中推送到仓库?

Gitlab-CI 中存在已删除的标签

如何使用 gitlab-ci.yml 在 gitlab 中更新 JSON 文件的内容?

Unity如何使用Gitlab-CI做自动构建

gitlab-ci.yml 仅在 master 分支上

获取 Kue 作业的结果并通过开放连接将其推送到客户端