通过 CI runner 将文件推送到 gitlab-ci
Posted
技术标签:
【中文标题】通过 CI runner 将文件推送到 gitlab-ci【英文标题】:Push files to gitlab-ci via CI runner 【发布时间】:2017-02-28 14:03:06 【问题描述】:我正在使用 gitlab CI runner 来测试我的代码并生成一些文件。我只想通过 CI runner 将生成的文件推送到 gitlab 存储库。有什么办法吗?
【问题讨论】:
thread 中涵盖了类似的问题 【参考方案1】:您正在寻找的功能称为工件。工件是在构建成功时附加到构建的文件。
要启用 Artifact,请将其放入您的 .gitlab-ci.yml:
artifacts:
paths:
- dir/
- singlefile
这会将dir
目录和文件singlefile
上传回GitLab。
【讨论】:
但我真的很想将文件作为源文件推送到存储库。 @VenkatGan 但是为什么呢?如果您使用 Runner 将任何内容推送到存储库,您将再次启动 runner。这将导致无限循环。 是的,它将开始一个无限循环。但是当我通过 runner 提交时,我使用[skip ci]
关键字。通过这种方式,我可以消除无限循环。
@Fairy 基于docs.gitlab.com/ee/user/project/… 除了[skip ci],推送时可以使用git选项跳过ci:git push -o ci.skip
遗憾的是,这个答案根本没有帮助:(。需要注意的一点:如果您需要安装 git 并且您正在使用 docker,您可能必须实际安装和配置它。我可能会进入这个,因为我想在构建时增加构建版本并将其提交/推送回原始存储库。【参考方案2】:
在 gitlab 中生成 SSH 密钥
--> 配置文件设置--> SSH 密钥--> 生成它
在 gitlab variables 中生成名为 SSH
的 SSH 密钥库后--> 项目设置--> 变量--> 添加变量
在 .gitlab-ci.yml 中添加以下行。
before_script:
- mkdir -p ~/.ssh
- echo "$SSH" | tr -d '\r' > ~/.ssh/id_rsa
- chmod 600 ~/.ssh/id_rsa
- ssh-keyscan -H 'Git_Domain' >> ~/.ssh/known_hosts
然后使用下面的 js 代码将文件推送到存储库。
var child_process = require("child_process");
child_process.execSync("git checkout -B 'Your_Branch'");
child_process.execSync("git remote set-url origin Your_Repository_Git_Url");
child_process.execSync("git config --global user.email 'Your_Email_ID'");
child_process.execSync("git config --global user.name 'Your_User_Name'");
for (var i=0;i<filesToBeAdded.length;i++)
child_process.execSync("git add "+filesToBeAdded[i]);
var ciLog = child_process.execSync("git commit -m '[skip ci]Automated commit for CI'");
var pushLog = child_process.execSync("git push origin Your_Branch");
[skip ci] 在提交信息中是最重要的。否则会开始无限循环的CI流程。
【讨论】:
【参考方案3】:我已经通过这样做解决了这个问题:
注意:如果你想 git push 到一个非受保护的分支,不要将 runner 变量设置为受保护
-
使用 api 范围生成新的 gitlab 访问令牌:
User Settings > Access Tokens
使用新令牌将受保护的 CI 变量添加到您的项目设置中:Your project > Settings > Secret variable
使用变量名称 CI_PUSH_TOKEN
使用变量名CI_USERNAME
使用您的用户名添加另一个受保护的 CI 变量
然后您可以在 gitlab-ci 脚本中使用此令牌而不是默认令牌。例如:
before_script:
- git remote set-url origin https://$CI_USERNAME:$CI_PUSH_TOKEN@gitlab.com/$CI_PROJECT_NAME.git
- git config --global user.email '$GITLAB_USER_EMAIL'
- git config --global user.name '$GITLAB_USER_ID'
...
- git checkout -B branch
- # do the file changes here
- git commit -m '[skip ci] commit from CI runner'
- git push --follow-tags origin branch
【讨论】:
我已经尝试过了,它抛出:fatal: Authentication failed for 'https://[secure]@example.com/dka/duma.git/'
,我是回购的所有者,令牌是我的。
我拒绝了你的答案,因为它似乎是错误的,我已经测试过了,我们一直在努力寻找证据
我们在许多项目中使用此设置而没有身份验证问题。您的设置中缺少某些内容,您可以为跑步者生成一个新令牌并尝试使用它吗?
* 我忘了说,如果你想为非受保护的分支运行 git push,你必须禁用 ci runner 令牌变量上的受保护标签
1.请使用$CI_PROJECT_NAME
代替your-project
、$GITLAB_USER_EMAIL
代替your@email.com
和$GITLAB_USER_ID
代替yourname
。 2.请注意CI_PUSH_TOKEN
是变量,必须包含API Token。 3. 也许 Gitlab 用户界面在您回答后发生了变化,现在是:Your project > Settings > CI / CD > Environment Variables
,您必须在其中设置CI_PUSH_TOKEN
。如果你设置了protected
属性,那么这个变量只会暴露给protected
分支上的gitlab 运行器(比如master branch
,默认情况下是受保护的)。【参考方案4】:
您当然可以使用 SSH 密钥,但您也可以提供用户和密码(具有写入权限的用户)作为秘密变量并使用它们。
例子:
before_script:
- git remote set-url origin https://$GIT_CI_USER:$GIT_CI_PASS@gitlab.com/$CI_PROJECT_PATH.git
- git config --global user.email 'myuser@mydomain.com'
- git config --global user.name 'MyUser'
您必须将GIT_CI_USER
和GIT_CI_PASS
定义为秘密变量(您始终可以为此创建专用用户)。
通过此配置,您通常可以使用 git。我正在使用这种方法在发布后推送标签(使用 Axion Release Gradle Pluing - http://axion-release-plugin.readthedocs.io/en/latest/index.html)
发布工作示例:
release:
stage: release
script:
- git branch
- gradle release -Prelease.disableChecks -Prelease.pushTagsOnly
- git push --tags
only:
- master
【讨论】:
嗨,你没有使用任何令牌?直接你的用户名和密码?这样维护是不是有点危险? 好吧,首先在我看来,Gitlab 应该提供在 CI 阶段提交到 repo 的选项 :) 因此,作为解决方法,您可以使用 SSH 密钥或密码(由 Gitlab 机密提供)。从我的角度来看,这与所有 Gitlab 机密的风险级别相同。 请考虑支持这些问题:gitlab.com/gitlab-org/gitlab-ce/issues/41084 和 gitlab.com/gitlab-org/gitlab-ce/issues/18106,以便我们以安全的方式执行此操作。【参考方案5】:另一种解决方案使用 Gitlab API 在 $CI_COMMIT_BRANCH
上的 terraform/
目录中用 [skip ci]
提交文件 .terraform.lock.hcl
:
script:
- 'STATUS=$(curl -Ss --head --header "JOB-TOKEN: $CI_JOB_TOKEN" "$CI_API_V4_URL/projects/$CI_PROJECT_ID/repository/files/terraform%2F%2Eterraform%2Elock%2Ehcl?ref=$CI_COMMIT_BRANCH" | grep "HTTP/1.1" | cut -d " " -f2)'
- if [[ $STATUS == "404" ]]; then ACTION="create"; else ACTION="update"; fi
- 'curl --request POST --form "branch=$CI_COMMIT_BRANCH" --form "commit_message=[skip ci] terraform.lock.hcl from pipeline" --form "actions[][action]=$ACTION" --form "actions[][file_path]=terraform/.terraform.lock.hcl" --form "actions[][content]=<.terraform.lock.hcl" --header "JOB-TOKEN: $CI_JOB_TOKEN" "$CI_API_V4_URL/projects/$CI_PROJECT_ID/repository/commits"'
【讨论】:
对于那些试图使用这个答案的人,请参阅gitlab.com/gitlab-org/gitlab-foss/-/issues/40326。努力获得这个很好的工作答案,但不断收到“404:找不到项目”。简而言之(截至 2021 年 4 月),CI_JOB_TOKEN 的使用似乎仅适用于公共存储库,或者如果您拥有 GitLab EE 版本,则该令牌将适用于私有存储库。 根据我之前的说明,最终能够通过创建并传递api
范围的项目令牌作为 CI/CD 变量(我将其命名为 CI_PROJECT_TOKEN
)并更改JOB-TOKEN: $CI_JOB_TOKEN
到 PRIVATE-TOKEN: $CI_PROJECT_TOKEN
的实例。不如 Job Token 最佳,但易于管理。以上是关于通过 CI runner 将文件推送到 gitlab-ci的主要内容,如果未能解决你的问题,请参考以下文章
将标签推送到外部 git 不会触发 Azure Pipelines CI
Gitlab CI/CD 到 Digital Ocean 使用 docker-compose 进行多个 repos