I am using gitlab CI runner to test my code and generating some files. I just want to push the generated files to gitlab repository via CI runner. Is there any way to do that ?
-
A similar issue is covered in this [thread](https://stackoverflow.com/a/63780337/2060245) – ddsultan Sep 07 '20 at 15:45
5 Answers
I have resolved this issue by doing this:
Note: If you want to git push to a non protected branch do not set the runner variable as protected
- Generate new gitlab access token with api scope:
User Settings > Access Tokens
- Add a protected CI variable into your project settings with the new token:
Your project > Settings > Secret variable
using variable nameCI_PUSH_TOKEN
- Add another protected CI variable with your username using variable name
CI_USERNAME
Then you can use this token instead of the default in you gitlab-ci script. for example:
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

- 1,150
- 2
- 13
- 31

- 2,091
- 21
- 19
-
2I have tried this and it throw : `fatal: Authentication failed for 'https://[secure]@example.com/dka/duma.git/'`, I am the owner of the repo and the token is mine. – Dimitri Kopriwa May 24 '18 at 21:21
-
1I have voted down your answer because it seems to be wrong, I have tested it and we keep trying to look for prooth – Dimitri Kopriwa May 27 '18 at 14:24
-
We are using this setup in many projects without auth issues. You are missing something in your setup, can you generate a new token just for the runner and try with it ? – jmuhire Jun 01 '18 at 22:52
-
* I forgot to say that If you want to run the git push for a non protected branch you have to disable the protected tag on the ci runner token variable – jmuhire Jun 01 '18 at 23:10
-
we did generate a token using the root account and we weren't able to git push with it. Could you share an example public repo project on your instance? – Dimitri Kopriwa Jun 02 '18 at 09:09
-
Is it possible to use ${CI_PROJECT_NAME} instead "your-project", ${GITLAB_USER_EMAIL} instead of "your@email.com" and ${GITLAB_USER_ID} instead of "yourname"? – tangoal Jan 12 '19 at 14:18
-
51. Please use `${CI_PROJECT_NAME}` instead `your-project`, `${GITLAB_USER_EMAIL}` instead of `your@email.com` and `${GITLAB_USER_ID}` instead of `yourname`. 2. Please mention that `CI_PUSH_TOKEN` is the variable, which must contain the API Token. 3. Maybe Gitlab user interface has changed since your answer, now it is: `Your project > Settings > CI / CD > Environment Variables` where you must set the `CI_PUSH_TOKEN`. If you set the `protected` property, then this variable is only exposed to gitlab runners on `protected` branches (like the `master branch`, which is protected by default). – tangoal Jan 12 '19 at 15:27
-
Hi, I got a next error: `gitlab-token-client: No such file or directory`. Do you know what it means, any ideas? – Ales Mar 05 '19 at 17:40
-
I can't even clone repo using this method. I tried 'gitlab-ci-token' and 'oauth2' as username in the origin link but it always redirects to sign in page. Are there any alternatives? – Mike Nov 12 '19 at 11:35
-
-
Note that after a build, running `git remote -v` in the build folder would expose your token. It may be a good idea to change the origin to something safe before the end of the deploy. – drskullster Feb 22 '22 at 13:38
-
`variables: ORIGIN: https://$GITLAB_GROUP_TOKEN_USERNAME:$GITLAB_GROUP_ACCESS_TOKEN@$CI_SERVER_HOST/$CI_PROJECT_PATH.git before_script: - git remote set-url origin $ORIGIN ` Works without an issue, You can use normal user credentials even. Where $GITLAB_GROUP_TOKEN_USERNAME is username or token name, $GITLAB_GROUP_ACCESS_TOKEN is password or token. – Gazeciarz May 31 '22 at 14:05
Generated a SSH Key in gitlab
--> Profile Settings --> SSH Keys --> Generate It
After generating the SSH Key store that in the gitlab variables named SSH
--> Project Settings --> Variables --> Add Variable
In the .gitlab-ci.yml add the below lines.
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
After that pushed the files to the repository using this below js code.
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] is most important in commit message. Otherwise it will start a infinity loop of CI process.

- 603
- 1
- 8
- 17
You could use of course SSH keys but you could also provide user and password (user with write access) as secret variables and use them.
Example:
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'
You have to define GIT_CI_USER
and GIT_CI_PASS
as secret variables (you could always create dedicated user for this purpose).
With this configuration you could normally work with git. I'm using this approach to push the tags after the release (with Axion Release Gradle Pluing - http://axion-release-plugin.readthedocs.io/en/latest/index.html)
Example release job:
release:
stage: release
script:
- git branch
- gradle release -Prelease.disableChecks -Prelease.pushTagsOnly
- git push --tags
only:
- master

- 7,173
- 3
- 53
- 57
-
Hi, so you are not using any token? Directly your username and password ? Isn't that a bit dangerous to maintain ? – Dimitri Kopriwa May 27 '18 at 14:24
-
1Well, first of all in my opinion Gitlab should provide the options to commit to repo during CI phase :) So as workaround you could use SSH key or password (provided by Gitlab secrets). From my perspective this is the same risk level as for all Gitlab secrets. – Przemek Nowak May 27 '18 at 17:36
-
Please consider to upvote these issues: https://gitlab.com/gitlab-org/gitlab-ce/issues/41084 and https://gitlab.com/gitlab-org/gitlab-ce/issues/18106 so we can do this in a safe way. – Danny Sep 18 '18 at 10:05
Another solution using Gitlab API to commit back a file .terraform.lock.hcl
in terraform/
directory on $CI_COMMIT_BRANCH
with [skip ci]
:
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"'

- 5,413
- 2
- 30
- 48
-
For those attempting to use this answer, see https://gitlab.com/gitlab-org/gitlab-foss/-/issues/40326. Struggled to get this great answer to work, but kept getting "404: Project Not Found". In short (as of Apr 2021) it appears that use of the CI_JOB_TOKEN only works on public repos or if you have the GitLab EE edition the token will work on private repos. – Trentium Apr 15 '21 at 14:27
-
Per my previous note, was finally able to get this answer to work by creating and passing an `api` scoped Project Token as a CI/CD variable (which I named `CI_PROJECT_TOKEN`), and changing instances of `JOB-TOKEN: $CI_JOB_TOKEN` to `PRIVATE-TOKEN: $CI_PROJECT_TOKEN`. Not as optimal as the Job Token, but manageable. – Trentium Apr 15 '21 at 18:56
The Feature you are looking for is called Artifacts. Artifacts are files which are attached to a build when they are successful.
To enable an Artifact put this in your .gitlab-ci.yml:
artifacts:
paths:
- dir/
- singlefile
This will upload the dir
directory and the file singlefile
back to GitLab.

- 3,592
- 2
- 27
- 36
-
3
-
2@VenkatGan But why? If you push anything with the Runner to the Repository, you will just startup the runner again. This would result in an infinite loop. – Fairy Oct 19 '16 at 13:37
-
11Yes it will start a infinite loop. But when i commit via runner i use `[skip ci]` keyword. By this way i can eliminate infinite looping. – Venkat Oct 20 '16 at 07:02
-
1@Fairy based on https://docs.gitlab.com/ee/user/project/push_options.html#push-options-for-gitlab-cicd in addition to [skip ci], when pushing you can use git options to skip ci: `git push -o ci.skip` – Pezhvak Dec 23 '19 at 16:22
-
Sadly this answer does not help at all :(. One thing to note: if you need git installed and you are using docker, you might have to actually install and configure it. I might get into this, because I want to increase build-version upon build and commit / push it back to the original repository. – Igor May 20 '20 at 00:10