Jenkins入门教程(八):Jenkins与Git集成

Git是目前最流行的版本控制系统,本文将详细介绍如何在Jenkins中集成Git进行自动化构建,包括完整的配置步骤和Pipeline示例。

安装Git插件

Jenkins默认安装了Git插件。如果没有,在插件管理中搜索"Git"并安装:

  • Git:Git SCM集成
  • Git client:Git客户端API
  • GitHub:GitHub特定功能
  • GitLab:GitLab特定功能

配置Git凭据

方式1:用户名密码/Token

# 在GitHub/GitLab生成Personal Access Token
# GitHub: Settings > Developer settings > Personal access tokens
# GitLab: Settings > Access Tokens

# 在Jenkins添加凭据
# 系统管理 > 凭据 > 系统 > 全局凭据 > 添加凭据

类型: Username with password
范围: Global
用户名: your-username
密码: ghp_xxxxxxxxxxxxxxxxxxxx  # GitHub Token
ID: github-token
描述: GitHub Personal Access Token

方式2:SSH密钥

# 生成SSH密钥对
ssh-keygen -t ed25519 -C "jenkins@example.com" -f ~/.ssh/jenkins_github -N ''

# 查看公钥(添加到GitHub/GitLab)
cat ~/.ssh/jenkins_github.pub
# ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIG... jenkins@example.com

# 查看私钥(添加到Jenkins)
cat ~/.ssh/jenkins_github
# -----BEGIN OPENSSH PRIVATE KEY-----
# b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW...
# -----END OPENSSH PRIVATE KEY-----

# 在GitHub添加公钥
# Settings > SSH and GPG keys > New SSH key

# 在Jenkins添加私钥凭据
类型: SSH Username with private key
范围: Global
ID: github-ssh
用户名: git
Private Key: Enter directly,粘贴私钥内容

在Pipeline中使用Git

基本用法

pipeline {
    agent any
    
    stages {
        stage('Checkout') {
            steps {
                // 方式1:使用git步骤(HTTPS)
                git branch: 'main',
                    url: 'https://github.com/example/repo.git',
                    credentialsId: 'github-token'
                
                // 方式2:使用git步骤(SSH)
                git branch: 'main',
                    url: 'git@github.com:example/repo.git',
                    credentialsId: 'github-ssh'
            }
        }
        
        stage('Show Git Info') {
            steps {
                sh '''
                    echo "=== Git Information ==="
                    echo "Commit: $(git rev-parse HEAD)"
                    echo "Short: $(git rev-parse --short HEAD)"
                    echo "Branch: $(git rev-parse --abbrev-ref HEAD)"
                    echo "Author: $(git log -1 --format='%an <%ae>')"
                    echo "Message: $(git log -1 --format='%s')"
                    echo "Date: $(git log -1 --format='%ci')"
                    echo ""
                    echo "=== Recent Commits ==="
                    git log --oneline -5
                '''
            }
        }
    }
}

// 执行结果
[Pipeline] git
Cloning the remote Git repository
Cloning repository https://github.com/example/repo.git
 > git init /var/lib/jenkins/workspace/my-job
 > git fetch --tags --force --progress -- https://github.com/example/repo.git +refs/heads/*:refs/remotes/origin/*
 > git checkout -b main origin/main
Commit message: "feat: add new feature"

[Pipeline] sh
=== Git Information ===
Commit: a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0
Short: a1b2c3d
Branch: main
Author: Developer 
Message: feat: add new feature
Date: 2026-02-08 12:00:00 +0800

=== Recent Commits ===
a1b2c3d feat: add new feature
b2c3d4e fix: resolve bug
c3d4e5f docs: update readme
d4e5f6g refactor: improve code
e5f6g7h test: add unit tests

使用checkout步骤

pipeline {
    agent any
    
    stages {
        stage('Checkout') {
            steps {
                // checkout scm - 自动使用Job配置的SCM
                checkout scm
                
                // 或使用详细配置
                checkout([
                    $class: 'GitSCM',
                    branches: [[name: '*/main']],
                    extensions: [
                        [$class: 'CloneOption', depth: 1, shallow: true],  // 浅克隆
                        [$class: 'CleanBeforeCheckout'],  // 清理工作区
                        [$class: 'CheckoutOption', timeout: 30]  // 超时
                    ],
                    userRemoteConfigs: [[
                        url: 'https://github.com/example/repo.git',
                        credentialsId: 'github-token'
                    ]]
                ])
            }
        }
    }
}

多仓库检出

pipeline {
    agent any
    
    stages {
        stage('Checkout Multiple Repos') {
            steps {
                // 主仓库
                dir('main-app') {
                    git branch: 'main',
                        url: 'https://github.com/example/main-app.git',
                        credentialsId: 'github-token'
                }
                
                // 配置仓库
                dir('config') {
                    git branch: 'main',
                        url: 'https://github.com/example/app-config.git',
                        credentialsId: 'github-token'
                }
                
                // 共享库
                dir('shared-lib') {
                    git branch: 'v2.0',
                        url: 'https://github.com/example/shared-lib.git',
                        credentialsId: 'github-token'
                }
                
                sh '''
                    echo "=== Workspace Structure ==="
                    ls -la
                    echo ""
                    echo "main-app: $(cd main-app && git rev-parse --short HEAD)"
                    echo "config: $(cd config && git rev-parse --short HEAD)"
                    echo "shared-lib: $(cd shared-lib && git rev-parse --short HEAD)"
                '''
            }
        }
    }
}

Git环境变量

pipeline {
    agent any
    
    stages {
        stage('Checkout') {
            steps {
                checkout scm
            }
        }
        
        stage('Git Environment Variables') {
            steps {
                sh '''
                    echo "=== Jenkins Git Environment Variables ==="
                    echo "GIT_COMMIT: ${GIT_COMMIT}"
                    echo "GIT_BRANCH: ${GIT_BRANCH}"
                    echo "GIT_URL: ${GIT_URL}"
                    echo "GIT_AUTHOR_NAME: ${GIT_AUTHOR_NAME:-not set}"
                    echo "GIT_AUTHOR_EMAIL: ${GIT_AUTHOR_EMAIL:-not set}"
                    echo "GIT_COMMITTER_NAME: ${GIT_COMMITTER_NAME:-not set}"
                    echo "GIT_COMMITTER_EMAIL: ${GIT_COMMITTER_EMAIL:-not set}"
                '''
            }
        }
    }
}

// 执行结果
=== Jenkins Git Environment Variables ===
GIT_COMMIT: a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0
GIT_BRANCH: origin/main
GIT_URL: https://github.com/example/repo.git
GIT_AUTHOR_NAME: Developer
GIT_AUTHOR_EMAIL: dev@example.com

Webhook自动触发

GitHub Webhook配置

# 1. 在Jenkins Job配置中启用Webhook触发
# 构建触发器 > GitHub hook trigger for GITScm polling

# 2. 在GitHub仓库配置Webhook
# Settings > Webhooks > Add webhook

Payload URL: https://jenkins.example.com/github-webhook/
Content type: application/json
Secret: your-webhook-secret(可选)
Events: Just the push event

# 3. Pipeline中使用triggers
pipeline {
    agent any
    
    triggers {
        githubPush()  // GitHub webhook触发
    }
    
    stages {
        stage('Build') {
            steps {
                checkout scm
                sh 'make build'
            }
        }
    }
}

GitLab Webhook配置

# 安装GitLab插件

# 1. 在GitLab配置Webhook
# Settings > Webhooks

URL: https://jenkins.example.com/project/my-job
Secret Token: your-secret-token
Trigger: Push events, Merge request events

# 2. Pipeline配置
pipeline {
    agent any
    
    triggers {
        gitlab(
            triggerOnPush: true,
            triggerOnMergeRequest: true,
            branchFilterType: 'All'
        )
    }
    
    stages {
        stage('Build') {
            steps {
                checkout scm
                sh 'make build'
            }
        }
    }
    
    post {
        success {
            updateGitlabCommitStatus name: 'build', state: 'success'
        }
        failure {
            updateGitlabCommitStatus name: 'build', state: 'failed'
        }
    }
}

多分支Pipeline

# 创建多分支Pipeline Job
# 新建任务 > 多分支流水线

# 配置分支源
# Branch Sources > Add source > GitHub / GitLab / Git

# 自动发现分支并为每个分支创建Pipeline
# 需要仓库根目录有Jenkinsfile

# Jenkinsfile示例
pipeline {
    agent any
    
    stages {
        stage('Build') {
            steps {
                echo "Building branch: ${env.BRANCH_NAME}"
                sh 'make build'
            }
        }
        
        stage('Deploy to Dev') {
            when {
                branch 'develop'
            }
            steps {
                sh './deploy.sh dev'
            }
        }
        
        stage('Deploy to Staging') {
            when {
                branch pattern: 'release/.*', comparator: 'REGEXP'
            }
            steps {
                sh './deploy.sh staging'
            }
        }
        
        stage('Deploy to Production') {
            when {
                branch 'main'
            }
            steps {
                input 'Deploy to production?'
                sh './deploy.sh prod'
            }
        }
    }
}

// Jenkins会自动为每个分支创建独立的Pipeline:
// - main
// - develop  
// - feature/new-feature
// - release/v1.0.0

Pull Request构建

# 多分支Pipeline自动发现PR
# 在Branch Sources配置中:
# Behaviors > Discover pull requests from origin

pipeline {
    agent any
    
    stages {
        stage('Build') {
            steps {
                checkout scm
                sh 'make build'
            }
        }
        
        stage('Test') {
            steps {
                sh 'make test'
            }
        }
        
        stage('PR Comment') {
            when {
                changeRequest()  // 仅在PR时执行
            }
            steps {
                script {
                    // 获取PR信息
                    echo "PR #${env.CHANGE_ID}: ${env.CHANGE_TITLE}"
                    echo "Author: ${env.CHANGE_AUTHOR}"
                    echo "Target: ${env.CHANGE_TARGET}"
                }
            }
        }
    }
}

// PR相关环境变量
// CHANGE_ID: PR编号
// CHANGE_TITLE: PR标题
// CHANGE_AUTHOR: PR作者
// CHANGE_TARGET: 目标分支
// CHANGE_URL: PR链接

Git操作示例

pipeline {
    agent any
    
    stages {
        stage('Checkout') {
            steps {
                checkout scm
            }
        }
        
        stage('Git Operations') {
            steps {
                // 配置Git用户
                sh '''
                    git config user.name "Jenkins CI"
                    git config user.email "jenkins@example.com"
                '''
                
                // 创建Tag
                sh '''
                    VERSION="1.0.${BUILD_NUMBER}"
                    git tag -a "v${VERSION}" -m "Release ${VERSION}"
                '''
                
                // 推送Tag(需要凭据)
                withCredentials([usernamePassword(
                    credentialsId: 'github-token',
                    usernameVariable: 'GIT_USER',
                    passwordVariable: 'GIT_PASS'
                )]) {
                    sh '''
                        git remote set-url origin https://${GIT_USER}:${GIT_PASS}@github.com/example/repo.git
                        git push origin --tags
                    '''
                }
            }
        }
    }
}

常见问题排查

# 问题1:SSH连接失败
# 检查SSH密钥配置
sudo -u jenkins ssh -T git@github.com
# Hi username! You've successfully authenticated...

# 问题2:SSL证书问题
git config --global http.sslVerify false  # 不推荐生产使用

# 问题3:克隆超时
# 使用浅克隆减少数据量
checkout([
    $class: 'GitSCM',
    extensions: [[$class: 'CloneOption', depth: 1, shallow: true]],
    ...
])

# 问题4:大型仓库
# 使用Git LFS
git lfs install
git lfs pull

# 问题5:权限问题
sudo chown -R jenkins:jenkins /var/lib/jenkins/workspace/

总结

本文详细介绍了Jenkins与Git的集成方法,包括凭据配置、Pipeline用法、Webhook自动触发、多分支Pipeline和PR构建。Git集成是CI/CD的基础。

下一篇我们将学习Jenkins与Docker的集成。

发表回复

后才能评论