Venkat
Venkat

Reputation: 603

Push files to gitlab-ci via CI runner

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 ?

Upvotes: 31

Views: 29121

Answers (5)

jmuhire
jmuhire

Reputation: 2221

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

  1. Generate new gitlab access token with api scope: User Settings > Access Tokens
  2. Add a protected CI variable into your project settings with the new token: Your project > Settings > Secret variable using variable name CI_PUSH_TOKEN
  3. 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

Upvotes: 39

Nicolas Pepinster
Nicolas Pepinster

Reputation: 6269

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"'

Upvotes: 1

Przemek Nowak
Przemek Nowak

Reputation: 7713

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:[email protected]/$CI_PROJECT_PATH.git
 - git config --global user.email '[email protected]'
 - 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

Upvotes: 5

Venkat
Venkat

Reputation: 603

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.

Upvotes: 11

Fairy
Fairy

Reputation: 3780

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.

Upvotes: -1

Related Questions