1 year ago

#376393

test-img

Siraxis

Git Remote Push in Jenkins

This is my use-case, we are on a Jenkins Pipeline. This Pipeline has to ask for a Version input, prepare a Release (Version Bump) of the software, tag and push changes to our Git repo, then push again to client's Azure repo. The changes towards client, will always have to be delivered in a new branch that is created in this job named delivery-X.X.X. Finally the job issues a PR in client's repo through Azure CLI.

Every time this job runs, Jenkins clones our personal Git repo through its Git Plugin (4.10.2) and uses it as its workspace. In order to avoid Git conflicts and populating the script with extra Git commands (git pull etc.), I enabled Wipe out repository & force clone in Git Behaviors/Jenkins job configuration. In this way we ensure that there's no cache left from previous runs of the Job which would result in various Git-related issues.

So my main arguments here are:

  1. Are there any commands that I missed or I should not have used? Or simpler commands that will make the scripts smarter?

  2. Which of these 2 approaches wins when it comes to reliability and efficiency.

Approach 1: This approach pushes the same commit both in our repository and client's Azure repo. Upon pushing to client's Azure, it will create a new branch the same time. Seems simpler than #2, although upon testing I faced an issue. The PR that is created sometimes will fail due to Merge Conflicts, Azure will notify me that there are files "Edited in Both". I can't explain why this is happening. Did I miss something?

pipeline {
   agent {
         docker {
            image 'randomimage/ubuntu-with-git-and-stuff:1.0.0'
            args '--privileged'
        }
    }
   options {
        disableConcurrentBuilds()
    }
    stages {
        stage ('Prompt for Input') {
            steps {
                script {
                    env.RELEASE_VERSION = input message: 'Release version:',
                                     parameters: [string(defaultValue: '',
                                                  description: '',
                                                  name: 'Release version')]
                }
            }
        }
        stage('Set to release version & Build') {
            parallel {
                stage('Set to release version & Build server') {
                    steps{
                        sh '''
                            mvn versions:set -DnewVersion=$RELEASE_VERSION
                            mvn versions:commit
                        '''
                    }
                }
            }       
        stage ('Push changes to our Repo') {
            steps{
                withCredentials([usernamePassword(credentialsId: 'our_git',
                usernameVariable: 'Username',
                passwordVariable: 'Password')]){
                    sh '''
                        git remote set-url origin https://$Username:$Password@git.ourgit.com/r/our-repo.git
                        git config --global user.email "devops@ourgit.com"
                        git config --global user.name "$Username"
                    
                        git commit -a -m "Release: $RELEASE_VERSION"
                        git tag -a $RELEASE_VERSION -m "$RELEASE_VERSION"
                        git push https://$Username:$Password@git.ourgit.com/r/our-repo.git HEAD:master --tags
 
                    '''
                }
            }
        }
        stage ('Push changes to Client and issue PR') {
            environment {
                AZURE_CREDS=credentials('azure_creds')
            }
            steps{
                
                withCredentials([usernamePassword(credentialsId: 'client_git',
                usernameVariable: 'Username',
                passwordVariable: 'Password')]){
                    sh '''
                        git remote set-url origin https://$Username:$Password@azure.client-git.com/r/client-repo.git
                        git push https://$Username:$Password@azure.client-git.com/r/client-repo.git HEAD:refs/heads/delivery-$RELEASE_VERSION
                        az login -u devops@ourgit.com -p $AZURE_CREDS_PSW --allow-no-subscriptions
                        az repos pr create --organization https://dev.azure.com/client-repo --project client-repo --repository client-repo --source-branch delivery-$RELEASE_VERSION --target-branch main --description "This will merge the code for version $RELEASE_VERSION to the master branch of client-repo."
                    '''
                }
            }
        }        
    }
}

Approach 2: This approach pushes the changes to our repo. Then clones again our repo in a nested directory within our workspace to ensure that everything is clean, and checkouts to the newly pushed tag. Copies the contents to a temp folder except the .git folder. Afterwards, it clones the client's repo, checkouts to a new branch (we want to maintain git history), and finally it copies the contents of temp in there. This approach is definitely noisy and heavier due to cloning the repositories. The time it takes will be increased over time. On the other hand, I have experienced zero issues, neither in pushing nor in merging the PR.

pipeline {
   agent {
         docker {
            image 'randomimage/ubuntu-with-git-and-stuff:1.0.0'
            args '--privileged'
        }
   }
   options {
        disableConcurrentBuilds()
   }
    stages {
        stage ('Prompt for Input') {
            steps {
                script {
                    env.RELEASE_VERSION = input message: 'Release version:',
                                     parameters: [string(defaultValue: '',
                                                  description: '',
                                                  name: 'Release version')]
                }
            }
        }
        stage('Set to release version & Build') {
            parallel {
                stage('Set to release version & Build server') {
                    steps{
                        sh '''
                            mvn versions:set -DnewVersion=$RELEASE_VERSION
                            mvn versions:commit
                        '''
                    }
                }
            }       
         stage ('Push changes to our Repo') {
            steps{
                withCredentials([usernamePassword(credentialsId: 'our_git',
                usernameVariable: 'Username',
                passwordVariable: 'Password')]){
                    sh '''
                        git remote set-url origin https://$Username:$Password@git.ourgit.com/r/our-repo.git
                        git config --global user.email "devops@ourgit.com"
                        git config --global user.name "$Username"
                    
                        git commit -a -m "Prepared release $RELEASE_VERSION"
                        git tag -a $RELEASE_VERSION -m "$RELEASE_VERSION"
                        git push -u https://$Username:$Password@git.ourgit.com/r/our-repo.git HEAD:master --tags
 
                    '''
                }
            }
        }
        stage ('Clone our Repo Again')
        {
            steps{
                withCredentials([usernamePassword(credentialsId: 'our_git',
                usernameVariable: 'Username',
                passwordVariable: 'Password')]){
                    sh '''
                        mkdir our-updated-repo
                        cd our-updated-repo
                        git clone https://$Username:$Password@git.ourgit.com/r/our-repo.git
                    '''
                }
            }
        }
        stage ('Push changes to Client and issue PR') {
            environment {
                AZURE_CREDS=credentials('azure_creds')
            }
            steps{
                withCredentials([usernamePassword(credentialsId: 'client_git',
                usernameVariable: 'Username',
                passwordVariable: 'Password')]){
                    sh '''
                        git clone https://$Username:$Password@azure.client-git.com/r/client-repo.git 
                        cd client-repo
                        git checkout -b delivery-$RELEASE_VERSION
                        rm -rf $(ls -A | grep -v .git)
                        cd ..
 
                        mkdir temp
 
                        cd our-updated-repo/our-repo
                        git checkout $RELEASE_VERSION
                        cd ../..
 
                        cp -R our-updated-repo/our-repo/. temp/
                        rm -rf temp/.git
                        cp -R temp/. client-repo/
                          
                        cd client-repo
                        
                        git remote set-url origin https://$Username:$Password@azure.client-git.com/r/client-repo.git
 
                        git add .
                        git commit -m "Release: $RELEASE_VERSION"
                        git push -u https://$Username:$Password@azure.client-git.com/r/client-repo.git HEAD:delivery-$RELEASE_VERSION
 
                        az login -u devops@ourgit.com -p $AZURE_CREDS_PSW --allow-no-subscriptions
                        az repos pr create --organization https://dev.azure.com/client-repo --project client-repo --repository client-repo --source-branch delivery-$RELEASE_VERSION --target-branch main --description "This will merge the code for version $RELEASE_VERSION to the master branch of client-repo."
                    '''
                }
            }
        }        
    }
}

git

jenkins

azure-devops

git-remote

jenkins-git-plugin

0 Answers

Your Answer

Accepted video resources