我的 Jenkins 管道目前通過curl在 shell 中呼叫成功呼叫了 Bitbucket REST API ,如下面的代碼所示:
// Jenkinsfile
@Library('my-sandbox-libs@dev') my_lib
pipeline {
agent any
stages {
stage( "1" ) { steps { script { echo "hello" } } }
stage( "2" ) {
steps {
script {
log = new org.log.Log()
def cred_id = "bitbucket_cred_id"
def url_base = "https://bitbucket.company.com"
def commit = "76136485c45df256a62cbc2c3c5f1f3efcc86258"
def status =
//"INPROGRESS",
//"SUCCESSFUL",
"FAILED"
def viz_url = "https://path/to/nowhere"
try {
my_lib.notifyBitbucketBuildStatus(cred_id,
url_base,
commit,
status,
"foo",
42,
viz_url,
log)
}
}
}
}
stage( "3" ) { steps { script { echo "world" } } }
}
post { always { script { echo log.asJsonString() } } }
}
import groovy.json.JsonOutput
def notifyBitbucketBuildStatus(cred_id,
url_base,
commit,
build_state,
build_info_name,
build_info_number,
viz_url,
log) {
def rest_path = "rest/build-status/1.0/commits"
def dict = [:]
dict.state = build_state
dict.key = "${build_info_name}_${build_info_number}"
dict.url = viz_url
withCredentials([string(credentialsId: cred_id,
variable: 'auth_token')]) {
def cmd = "curl -f -L "
"-H \"Authorization: Bearer ${auth_token}\" "
"-H \"Content-Type:application/json\" "
"-X POST ${url_base}/${rest_path}/${commit} "
"-d \'${JsonOutput.toJson(dict)}\'"
if ( 0 != sh(script: cmd, returnStatus: true) ) {
log.warn("Failed updating build status with Bitbucket")
}
}
}
我想重構函式notifyBitbucketBuildStatus()以使用“本機”Groovy 語言解決方案,而不是curl在 shell 中呼叫。我閱讀了有關此主題的以下內容:
- https://www.baeldung.com/groovy-web-services
- Groovy 內置 REST/HTTP 客戶端?
...基于此,我認為重構后的函式將如下所示:
def notifyBitbucketBuildStatus(cred_id,
url_base,
commit,
build_state,
build_info_name,
build_info_number,
viz_url,
log) {
def rest_path = "rest/build-status/1.0/commits"
def dict = [:]
dict.state = build_state
dict.key = "${build_info_name}_${build_info_number}"
dict.url = viz_url
def req = new URL("${url_base}/${rest_path}/${commit}").openConnection()
req.setRequestMethod("POST")
req.setDoOutput(true)
req.setRequestProperty("Content-Type", "application/json")
withCredentials([string(credentialsId: cred_id,
variable: 'auth_token')]) {
req.setRequestProperty("Authorization", "Bearer ${auth_token}")
}
def msg = JsonOutput.toJson(dict)
req.getOutputStream().write(msg.getBytes("UTF-8"));
if ( 200 != req.getResponseCode() ) {
log.warn("Failed updating build status with Bitbucket")
}
}
...但這會產生例外 java.io.NotSerializableException: sun.net.www.protocol.https.HttpsURLConnectionImpl
“不可序列化”讓我認為該錯誤與無法將某些內容轉換為字串有關,因此我也嘗試了此操作,但它并沒有改變錯誤:
def msg = JsonOutput.toJson(dict).toString()
使用 class 的重構代碼有URL什么問題,使用它來呼叫 REST API 的正確方法是什么?
對于我的生活,我看不出上面和鏈接的 Stack Overflow Q&A 之間有什么不同,而且我對語言的缺乏經驗使得我在很大程度上依賴于調整現有示例。
uj5u.com熱心網友回復:
解決方案
我強烈建議您為此使用HTTP Request和Pipeline Steps Utility 插件。然后,您可以在 Groovy 腳本中使用這些步驟,如下所示
node('master') {
withCredentials([string(credentialsId: cred_id, variable: 'auth_token')]) {
def response = httpRequest url: "https://jsonplaceholder.typicode.com/todos", customHeaders: [[name: 'Authorization', value: "Bearer ${auth_token}"]]
}
if( response.status != 200 ) {
error("Service returned a ${response.status}")
}
def json = readJSON text: response.content
println "The User ID is ${json[0]['userId']}"
println "The follow json obj is ${json}"
}
顯然,如果要構建方法,可以修改代碼,并且需要使用適當的 URL 進行更新。
uj5u.com熱心網友回復:
我找到了一個糟糕且不令人滿意的答案 - 但仍然是一個答案 - 我在這里發布:https : //stackoverflow.com/a/69486890/5437543
我討厭這個解決方案,因為它似乎表明 Jenkins/Groovy 語言本身對我如何組織我的代碼強加了人為的設計。實際上,我被阻止做
// Jenkinsfile
@Library('my-sandbox-libs@dev') my_lib
pipeline {
agent any
stages {
stage( "1" ) { steps { script { my_lib.func() } } }
}
}
// vars/my_lib.groovy
def func() {
def post = new URL("https://whatever").openConnection();
...
withCredentials([string(credentialsId: cred_id,
variable: 'auth_token')]) {
req.setRequestProperty("Authorization", "Bearer ${auth_token}")
}
...
}
......我被迫做
// Jenkinsfile
@Library('my-sandbox-libs@dev') my_lib
pipeline {
agent any
stages {
stage( "1" ) { steps { script { my_lib.func(my_lib.getCred()) } } }
}
}
// vars/my_lib.groovy
def getCred() {
withCredentials([string(credentialsId: cred_id,
variable: 'auth_token')]) {
return auth_token
}
}
def func(auth_token) {
def post = new URL("https://whatever").openConnection();
...
req.setRequestProperty("Authorization", "Bearer ${auth_token}")
...
}
非常不滿意的結論。我希望另一位回答者可以指出一個不依賴于這種人為代碼組織的解決方案。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/314036.html
