This demonstrates how to push a tag (or branch, etc) to a remote Git repository from within a Pipeline job. The authentication step may vary between projects. This example illustrates injected credentials and also username / password authentication.
Based on Stackoverflow answer at http://stackoverflow.com/questions/33570075/tag-a-repo-from-a-jenkins-workflow-script
Injected credentials gist at https://gist.github.com/blaisep/eb8aa720b06eff4f095e4b64326961b5#file-jenkins-pipeline-git-cred-md
The Git user name and email must be configured on the agent running the build to be able to commit changes / create a tag. If no user is configured in the agent environment, the following error would appear when committing / pushing changes:
*** Please tell me who you are.
shell> git config --global user.email "[email protected]"
shell> git config --global user.name "Your Name"
The user / email can be set in the pipeline like the following:
sh '''
git config user.name 'my-ci-user'
git config user.email '[email protected]'
'''
(Note: The git username and email can be configured via the SCM Trait (Pipeline Multibranch) or Git Advanced Behavior (Pipeline) “Custom user name/e-mail address”)
In most cases, the checkout step checkout the repository at a specific revision (in a detached HEAD). This is something to be aware of when committing and pushing changes. A good practice is to checkout to a local branch when making changes and ideally before making changes (i.e. right after the checkout) to avoid losing them when doing git operations:
git checkout -B $TARGET_BRANCH
(Note: Pipeline and Pipeline Multibranch respectively proposed the additional behavior “Check out to specific local branch” and trait “Check out to matching local branch” to checkout to a local branch right after the checkout)
Changes may be push via SSH or HTTPS. It is simpler and more consistent to push via the same protocol as the one used to do the checkout.
If for any particular reason, the push must be done using a different method the URL needs to be configured accordingly:
[email protected]/.insteadOf https://github.com/
if the checkout was done through HTTPS
but push must be done using SSHurl.https://github.com/.insteadOf [email protected]/
if the checkout was done through SSH
but push must be done using HTTPS** Push via HTTPS **
The Credentials Binding can be used to inject username/password
(or token) as environment variable. Those variables can be used to define a credentials helper.
In scripted pipeline, use the Credentials Binding plugin wrapper. Authentication is only possible within the withCredentials block:
withCredentials([usernamePassword(credentialsId: 'pzzqz-credentials-id', usernameVariable: 'GIT_USERNAME', passwordVariable: 'GIT_PASSWORD')]) {
sh '''
git config --local credential.helper "!f() { echo username=$GIT_USERNAME; echo password=$GIT_PASSWORD; }; f"
git push origin HEAD:$TARGET_BRANCH
'''
}
In Declarative Pipeline, the environment block can be used. Authentication is only possible within the stage that defines the environment variable:
stage('Push') {
environment {
GIT_AUTH = credentials('pzzqz-predefined-credentials-id')
}
steps {
sh '''
git config --local credential.helper "!f() { echo username=$GIT_AUTH_USR; echo password=$GIT_AUTH_PSW; }; f"
git push origin HEAD:$TARGET_BRANCH
'''
}
}
Push via SSH
A simple solution is to use the SSH Agent plugin to inject SSH credentials via ssh-agent. For both scripted and declarative, the solution is the same:
sshagent(['pzzqz-ssh-credentials-id']) {
sh '''
# If no host key verification is needed, use the option `-oStrictHostKeyChecking=no`
export GIT_SSH_COMMAND="ssh -oStrictHostKeyChecking=no"
git push origin HEAD:$TARGET_BRANCH
'''
}
Examples
The following scripts adds a file to the current branch of a Pipeline Multibranch build and push the changes via HTTPS:
pipeline {
agent any
stages {
stage("Build") {
steps {
// Create a dummy file in the repo
sh 'echo $BUILD_NUMBER > example-$BUILD_NUMBER.md'
}
}
stage("Commit") {
steps {
sh '''
git checkout -B $TARGET_BRANCH
git config user.name 'pzzqz-ci-user'
git config user.email '[email protected]'
git add . && git commit -am "[Jenkins CI] Add build file"
'''
}
}
stage("Push") {
environment {
GIT_AUTH = credentials('support-team-id')
}
steps {
sh '''
git config --local credential.helper "!f() { echo username=$GIT_AUTH_USR; echo password=$GIT_AUTH_PSW; }; f"
git push origin HEAD:$TARGET_BRANCH
'''
}
}
}
}
The following script creates a tag of the current branch of a Pipeline Multibranch build push it via SSH:
pipeline {
agent any
stages {
stage("Tag and Push") {
when { branch 'master' }
environment {
GIT_TAG = "jenkins-$BUILD_NUMBER"
}
steps {
sh '''
git config user.name 'pzzqz-ci-user'
git config user.email '[email protected]'
git tag -a ${GIT_TAG} -m "[Jenkins CI] New Tag"
'''
sshagent(['pzzqz-ssh-credentials-id']) {
sh '''
export GIT_SSH_COMMAND="ssh -oStrictHostKeyChecking=no"
git push origin ${GIT_TAG}
'''
}
}
}
}
}
Comments