如何从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
相关产品推荐
相关产品推荐

