You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从Jenkins任务创建Github Release并包含上次版本后的所有提交

当然可以搞定!我给你准备了两种方案——Gradle任务和Jenkins Pipeline,都能实现自动创建带完整提交历史的GitHub Release,完全满足你的需求。

一、Gradle 任务实现

我们可以直接在Gradle里编写任务,通过Git命令获取上一版本到当前版本的提交历史,再调用GitHub API创建Release并附上这些记录。

示例Gradle任务代码

plugins {
    id 'java'
}

task createGitHubRelease {
    doLast {
        // 1. 基础配置(建议从环境变量/构建参数传入,避免硬编码)
        def repoOwner = "你的GitHub用户名/组织名"
        def repoName = "目标仓库名"
        def githubToken = System.getenv("GITHUB_TOKEN") // 从环境变量读取token
        def currentTag = System.getenv("BUILD_TAG") ?: "v1.0.0" // 可直接用Jenkins的BUILD_TAG变量
        def releaseName = "Release ${currentTag}"

        // 2. 获取上一个版本的标签(按创建时间倒序取第二个)
        def previousTag = ""
        try {
            def tagsOutput = exec {
                commandLine 'git', 'tag', '--sort=-creatordate'
                standardOutput = new ByteArrayOutputStream()
            }.standardOutput.toString().trim().split("\n")
            if (tagsOutput.size() >= 2) {
                previousTag = tagsOutput[1]
            }
        } catch (Exception e) {
            println "获取上一标签失败,将使用默认发布说明: ${e.message}"
        }

        // 3. 生成提交历史(上一标签到当前标签的所有提交)
        def releaseNotes = "## 版本更新记录\n"
        if (previousTag) {
            def commitsOutput = exec {
                commandLine 'git', 'log', "--pretty=format:- %s (%h)", "${previousTag}..${currentTag}"
                standardOutput = new ByteArrayOutputStream()
            }.standardOutput.toString().trim()
            releaseNotes += commitsOutput ?: "无新提交"
        } else {
            releaseNotes += "首次发布,无历史版本对比"
        }

        // 4. 构造GitHub API请求体
        def json = new groovy.json.JsonBuilder()
        json {
            tag_name currentTag
            name releaseName
            body releaseNotes
            draft false // 设为true可创建草稿,后续手动编辑
            prerelease false
        }

        // 5. 调用GitHub API创建Release
        def url = "https://api.github.com/repos/${repoOwner}/${repoName}/releases"
        def connection = new URL(url).openConnection() as HttpURLConnection
        connection.setRequestMethod("POST")
        connection.setRequestProperty("Authorization", "token ${githubToken}")
        connection.setRequestProperty("Content-Type", "application/json")
        connection.doOutput = true

        def writer = new OutputStreamWriter(connection.outputStream)
        writer.write(json.toString())
        writer.flush()
        writer.close()

        // 检查创建结果
        def responseCode = connection.responseCode
        def response = new InputStreamReader(connection.inputStream).text
        if (responseCode == 201) {
            println "GitHub Release 创建成功!"
            println "Release 详情: ${response}"
        } else {
            println "创建Release失败,响应码: ${responseCode}"
            println "响应内容: ${response}"
            throw new GradleException("GitHub Release 创建失败")
        }
    }
}

注意事项

  • 需在Jenkins环境中设置GITHUB_TOKEN环境变量,这个令牌需要拥有repo权限
  • 确保Jenkins服务器已安装Git,且能正常执行git命令
  • 如果是首次发布(无历史标签),会自动生成“首次发布”的说明文本

二、Jenkins Pipeline(Jenkinsfile)实现

用Jenkins Pipeline更灵活,能直接整合到你的构建流程中,同样可以获取提交历史并调用GitHub API。

示例Jenkinsfile代码

pipeline {
    agent any
    environment {
        GITHUB_TOKEN = credentials('github-token') // 从Jenkins凭据管理读取令牌
        REPO_OWNER = '你的GitHub用户名/组织名'
        REPO_NAME = '目标仓库名'
        CURRENT_TAG = "${env.BUILD_TAG}" // 直接使用Jenkins自动生成的构建标签
    }
    stages {
        stage('生成发布说明') {
            steps {
                script {
                    // 获取所有标签,按创建时间倒序排列
                    def tags = sh(script: 'git tag --sort=-creatordate', returnStdout: true).trim().split('\n')
                    def previousTag = tags.size() >= 2 ? tags[1] : ''
                    env.PREVIOUS_TAG = previousTag

                    // 生成上一版本到当前版本的提交记录
                    if (previousTag) {
                        def releaseNotes = sh(script: "git log --pretty=format:'- %s (%h)' ${previousTag}..${CURRENT_TAG}", returnStdout: true).trim()
                        // 转义双引号避免JSON格式错误
                        env.RELEASE_NOTES = "## 自${previousTag}以来的更新\n${releaseNotes}".replaceAll('"', '\\"')
                    } else {
                        env.RELEASE_NOTES = "## 首次发布\n这是项目的第一个正式版本!".replaceAll('"', '\\"')
                    }
                }
            }
        }
        stage('创建GitHub Release') {
            steps {
                script {
                    def requestBody = """
                    {
                        "tag_name": "${CURRENT_TAG}",
                        "name": "Release ${CURRENT_TAG}",
                        "body": "${env.RELEASE_NOTES}",
                        "draft": false,
                        "prerelease": false
                    }
                    """.trim()

                    // 使用Jenkins的http_request插件发送请求
                    def response = httpRequest(
                        url: "https://api.github.com/repos/${REPO_OWNER}/${REPO_NAME}/releases",
                        httpMode: 'POST',
                        requestBody: requestBody,
                        authentication: 'github-token', // 对应Jenkins凭据ID
                        contentType: 'APPLICATION_JSON',
                        consoleLogResponseBody: true
                    )

                    if (response.status == 201) {
                        echo "GitHub Release 创建成功!"
                    } else {
                        error "创建Release失败,响应码: ${response.status}, 响应内容: ${response.content}"
                    }
                }
            }
        }
    }
}

注意事项

  • 需要安装Jenkins的http_request插件来发送HTTP请求
  • 在Jenkins凭据管理中添加Secret Text类型的凭据,ID设为github-token,值为你的GitHub个人访问令牌(需有repo权限)
  • 可以将draft设为true,创建草稿Release,之后手动编辑完善后再发布

额外小建议

  • 想要更美观的发布说明,可以自定义git log的格式,比如加上作者信息:--pretty=format:- %s (%h) by %an
  • 如果项目有多个分支,要确保在正确的分支上执行标签和提交历史的获取操作
  • Gradle任务可以封装成独立插件,方便多个项目复用

内容的提问来源于stack exchange,提问作者Alexander Shevkunenko

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 09:50:51