添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
相关文章推荐
玩足球的铅笔  ·  Empty CI Secret ...·  2 天前    · 
卖萌的马铃薯  ·  Command Line | ...·  4 天前    · 
绅士的土豆  ·  gitlab的token怎么生成 ...·  1 周前    · 
风流的松树  ·  Unity ...·  2 周前    · 
傻傻的熊猫  ·  出海易 - 出海资讯·  6 月前    · 
低调的饭盒  ·  AttributedString —— ...·  9 月前    · 
谦虚好学的茶叶  ·  How to fix ...·  1 年前    · 

It seems like something most people would want to do. You have something in your pipeline changing the project and then you want to push. However whenever I attempt to do a git push from my gitlab runner I get a 403 permission denied. Most things I find on the internet say it is because of it attempting to use the CI token. I have the SSH keys on the machine the runner is running on.

How do people do pushes from a gitlab runner?

Use a git credential helper to push to the repo. Take a look at the the “badge” stage of the following gitlab-ci.yaml for an example:

gitlab.com

ixilon/nukkit-docker/blob/master/.gitlab-ci.yml

# This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. stages: - build - publish - badge

We did this by adding a before_script task where we install SSH & Git and set the Git credentials.

The var SSH_PRIVATE_KEY_TOOLKIT in the example below is a Deploy Key generated in Gitlab by going to Settings > Repository > Deploy Keys , Make sure to enable write access by editing the deploy key after enabling it.

 before_script:
    - apt-get update -y && apt-get install -yqqf openssh-client git unzip sshpass rsync --fix-missing
    - 'which ssh-agent || ( apt-get update -y && apt-get install openssh-client git -y )'
    - eval $(ssh-agent -s)
    - echo "$SSH_PRIVATE_KEY_TOOLKIT" | tr -d '\r' | ssh-add - > /dev/null
    - mkdir -p ~/.ssh
    - chmod 700 ~/.ssh
    - ssh-keyscan $GITLAB_URL >> ~/.ssh/known_hosts
    - chmod 644 ~/.ssh/known_hosts
    - git config --global user.email "[email protected]"
    - git config --global user.name "Gitlab Runner"

Then in your script you can do this:

  script:
    # Pull repo
    - echo "Pulling external repo into build"
    - ssh git@$GITLAB_URL
    - git clone git@$GITLAB_URL:$EXTERNAL_REPO_URL filelocation/we/expect/the/files
    # Do something after pulling your repo
    # Push repo changes into current repo
    - git remote rm origin && git remote add origin "git@$GITLAB_URL:${CI_PROJECT_PATH}.git"
    - git add filelocation/we/expect/the/files another/location/can/be/defined
    - git commit -m "Commit message here :)" || echo "No changes, nothing to commit!"
    - git push origin HEAD:$CI_COMMIT_REF_NAME

Hope this helps you out.

My solution wasn’t as complicated, maybe because I am relying on the gitlab-runner machine always having the correct ssh keys set up. I have posted below for anyone else

 script:
- 'standard-version --releaseCommitMessageFormat "chore(release): {{currentTag}}"'
- git remote show origin
- git remote set-url --push origin git@gitlab:$CI_PROJECT_PATH
- git remote show origin
- git push --follow-tags origin HEAD:$CI_COMMIT_REF_NAME
- npm publish

This changes the remote taking out the whole CI token stuff

In case others are wondering, I found a nice guide to set this up with shared GitLab runners and compiled it into another answer here.

In short:

deploy:
  stage: deploy
  before_script:
    - 'which ssh-agent || ( apt-get update -qy && apt-get install openssh-client -qqy )'
    - eval `ssh-agent -s`
    - echo "${SSH_PRIVATE_KEY}" | tr -d '\r' | ssh-add - > /dev/null # add ssh ke
    - mkdir -p ~/.ssh
    - chmod 700 ~/.ssh
    - echo "$SSH_PUBLIC_KEY" >> ~/.ssh/id_rsa.pub
    - '[[ -f /.dockerenv ]] && echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config'
  script:
    - git config --global user.email "${CI_EMAIL}"
    - git config --global user.name "${CI_USERNAME}"
    - git add -f *.pdf # Force add PDF since we .gitignored it
    - git commit -m "Compiled PDF from $CI_COMMIT_SHORT_SHA [skip ci]" || echo "No changes, nothing to commit!"
    - git remote rm origin && git remote add origin [email protected]:$CI_PROJECT_PATH.git
    - git push origin HEAD:$CI_COMMIT_REF_NAME # Pushes to the same branch as the trigger
              

I’ve been searching for an easy solution for this for a long time and finally decided to build my own. As most of my projects use JavaScript, I wrote this small NPM package, push-to-repo, that allows you to push any changed file back to the repo with one command. For example (tweets-to-json fetches tweets and saves them in a json file):

updatetweets:
  only:
    - schedules
  script:
    - yarn --frozen-lockfile
    - yarn tweets-to-json --fail-when-zero && yarn push-to-repo -f tweets.json
  allow_failure: true

I use this with a scheduled pipeline that fetches my tweets as a JSON file to feed to a static site builder.

Only thing you need to configure this is a valid access token in your project CI settings. The package is open source and available here:

I have a question about the deploy key, and your solution is the nearest to mine. As I understand correctly, you use the variable SSH_PRIVATE_KEY_TOOLKIT as the private key to connect to the repository? From reading the manuals from gitlab I was thinking the deploy key needs to be the public key and I put the private key as variable inside my repo CI Variables.

So if I am wrong an the deploy key needs to be the private key, where do I save the public key? Do I need a additional Gitlab-Runner-User who has saved his public key in his settings?

Nope simply create a SSH Key pair, you can do this on your computer ( by using Putty for example ).
Then define the public key in the deploy key section within a project by visiting Settings > Repository > Deploy Keys, Make sure you hit “Write access allowed”.
Then define your Private key in the variable SSH_PRIVATE_KEY_TOOLKIT.

Note: Best would be to add this variable on group level so that you won’t need to redefine it for new projects you create. ( Only if this applies to you workflow, for us this made sense since we want to pull the repo to each repo in our project group )

Then make sure this deploy key is enabled in both the repositories and has “Write access allowed” for the repo where the files should be pushed to. “Note when enabling the deploy key in a new repo the Write access is unchecked by default, so enable it and then edit and allow write access”.

Hopefully this clear things up for you, if there is still anything unclear let me know maybe I can help out.

Thats makes everything a bit more clear. So regarding to you post I used it in our CI. My problem is, that my scripts runs fine until I hit the point, where I want to push something back to the repo.

I have an opend stackoverflow question with all the additional Informations. I tested it with a windows gitlab-runner and a linux gitlab-runner, both struggeling to push, based on restrictions. If you want to see the linux code feel free to ask.

I took a quick look at your stackoverflow question and was wondering if you created a SSH Key without a password ? Since the error thrown is also the error that will be thrown when your SSH Key is password protected but no password was supplied.

We’ve actually ran into this issue as well and fixed it by creating a new key that was not password protected.

I finally could figure out, that atleast some part for ssh and gitlab is working. I figured out that I have some problem to use my WSL to git clone (or something else git-server related) with just my openssh config. But at least the core.sshCommand get me working. Sadly the GIT_SSH_COMMAND env variable doesn’t do the job for the git-runner. At a last glimps from my side, could it be that the gitlabrunner-user isn’t allowed to access the repository because it is private?

I had to do something very similar, but the CI_EMAIL and CI_USERNAME did not exist (using gitlab.com SaaS) - I had to instead specify:

    - git config --global user.email "${GITLAB_USER_EMAIL}"
    - git config --global user.name "${GITLAB_USER_NAME}"
              

Hi @jrwang ,
I’m a bit of a newbie so apologize if the questions a basic.
I’m trying to apply your solution but running into some syntax errors.
Initially I got these errors:

At C:\Windows\TEMP\build_script039793081\script.ps1:285 char:17
+ which ssh-agent || ( apt-get update -qy && apt-get install openssh-cl ...
+                 ~~
The token '||' is not a valid statement separator in this version.

I figured it’s bc I’m using powershell so I should use -or and -and instead of || and && (is that correct?).

Now I’m getting error about the last line in the before_script, but I’m not sure how to adjust that line to powershell (I don’t really understand that line :thinking:)

At C:\Windows\TEMP\build_script991080655\script.ps1:309 char:2
+ [[ -f /.dockerenv ]] -and echo -e "Host *\n\tStrictHostKeyChecking no ...
Missing type name after '['.
    + CategoryInfo          : ParserError: (:) [], ParseException
    + FullyQualifiedErrorId : MissingTypename

Will appreciate any help…
Thanks