簡體   English   中英

如何使用Jenkinsfile設置github提交狀態不使用拉取請求構建器

[英]How to set github commit status with Jenkinsfile NOT using a pull request builder

我們有Jenkins 2設置構建每次推送到github,我們不使用Pull Request構建器(雖然提交是拉請求的一部分,顯然也會構建)。 GitHub集成插件說它只適用於pull請求構建器,所以這對我們不起作用。

我也嘗試了github-notify插件 ,但它似乎不適用於我們的情況(可能是因為repo是私有的和/或作為Organizaiton的一部分而不是個人用戶擁有)。 我試過讓它推斷設置以及手動指定credentialsIdaccountrepo ,當然還有status參數,都沒有運氣。

這是我Jenkinsfile的縮寫版本:

pipeline {
    agent { label "centos7" }

    stages {
        stage("github => pending") {
            steps {
                githubNotify status: "PENDING", credentialsId: "my-credentials-id", account: "my-account", repo: "my-repo"
            }
        }
        stage("build") {
            ...
        }
    }

    post {
        success {
            githubNotify status: "SUCCESS", credentialsId: "my-credentials-id", account: "my-account", repo: "my-repo"
        }
        failure {
            githubNotify status: "FAILURE", credentialsId: "my-credentials-id", account: "my-account", repo: "my-repo"
        }
    }
}

當我運行構建時,我得到以下內容:

java.lang.IllegalArgumentException: The suplied credentials are invalid to login
    at org.jenkinsci.plugins.pipeline.githubstatusnotification.GitHubStatusNotificationStep.getGitHubIfValid(GitHubStatusNotificationStep.java:234)
    at org.jenkinsci.plugins.pipeline.githubstatusnotification.GitHubStatusNotificationStep.getRepoIfValid(GitHubStatusNotificationStep.java:239)
    at org.jenkinsci.plugins.pipeline.githubstatusnotification.GitHubStatusNotificationStep.access$100(GitHubStatusNotificationStep.java:75)
    at org.jenkinsci.plugins.pipeline.githubstatusnotification.GitHubStatusNotificationStep$Execution.run(GitHubStatusNotificationStep.java:344)
    at org.jenkinsci.plugins.pipeline.githubstatusnotification.GitHubStatusNotificationStep$Execution.run(GitHubStatusNotificationStep.java:326)
    at org.jenkinsci.plugins.workflow.steps.AbstractSynchronousNonBlockingStepExecution$1$1.call(AbstractSynchronousNonBlockingStepExecution.java:47)
    at hudson.security.ACL.impersonate(ACL.java:221)
    at org.jenkinsci.plugins.workflow.steps.AbstractSynchronousNonBlockingStepExecution$1.run(AbstractSynchronousNonBlockingStepExecution.java:44)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)

我已經通過Jenkins(在配置系統區域中)和在瀏覽器中手動測試了憑據 - 用戶名和密碼是正確的,並且對相關的repo具有讀/寫訪問權限。

根據Jenkins GitHub插件自己的例子

void setBuildStatus(String message, String state) {
  step([
      $class: "GitHubCommitStatusSetter",
      reposSource: [$class: "ManuallyEnteredRepositorySource", url: "https://github.com/my-org/my-repo"],
      contextSource: [$class: "ManuallyEnteredCommitContextSource", context: "ci/jenkins/build-status"],
      errorHandlers: [[$class: "ChangingBuildStatusErrorHandler", result: "UNSTABLE"]],
      statusResultSource: [ $class: "ConditionalStatusResultSource", results: [[$class: "AnyBuildResult", message: message, state: state]] ]
  ]);
}

... 

pipeline {
  stages {
     ...
  }
  post {
    success {
        setBuildStatus("Build succeeded", "SUCCESS");
    }
    failure {
        setBuildStatus("Build failed", "FAILURE");
    }
  }
}

不需要多余的插件。 只要您安裝並正確配置了GitHub插件,您甚至不需要執行上述操作,它應該自動執行。 我們沒有使用Pull Request構建器,而是使用Jenkins Multibranch Pipeline。 我們只是在我們的PR中使用上面的代碼片段來獲得額外的狀態粒度。

首先,確保這些憑據是全局憑證,而不是文件夾憑據。
后者尚不支持,並會產生類似的錯誤消息:請參閱JENKINS-42955 (仍在審核中)

其次,如果這些憑證在瀏覽器中工作但不通過DSL配置文件,則可能是jenkins文件,這可能是由於名稱或密碼中的特殊字符造成的:查看您是否需要對保留字符進行百分比編碼

我沒想到account參數中的值必須與憑據中的用戶不匹配。 您必須在account指定存儲庫所有者。 credentialsId您可以使用任何具有對存儲庫的推送訪問權限的用戶:

credentialsId :要使用的github credentialsId的ID必須是UsernameAndPassword類型。 確保憑據具有寫訪問權限,如doc所述 :具有推送訪問權限的用戶可以為給定的ref創建提交狀態

account :擁有存儲庫的帳戶

來自文檔的更好示例:

def getRepoURL() {
  sh "git config --get remote.origin.url > .git/remote-url"
  return readFile(".git/remote-url").trim()
}

def getCommitSha() {
  sh "git rev-parse HEAD > .git/current-commit"
  return readFile(".git/current-commit").trim()
}

def updateGithubCommitStatus(build) {
  // workaround https://issues.jenkins-ci.org/browse/JENKINS-38674
  repoUrl = getRepoURL()
  commitSha = getCommitSha()

  step([
    $class: 'GitHubCommitStatusSetter',
    reposSource: [$class: "ManuallyEnteredRepositorySource", url: repoUrl],
    commitShaSource: [$class: "ManuallyEnteredShaSource", sha: commitSha],
    errorHandlers: [[$class: 'ShallowAnyErrorHandler']],
    statusResultSource: [
      $class: 'ConditionalStatusResultSource',
      results: [
        [$class: 'BetterThanOrEqualBuildResult', result: 'SUCCESS', state: 'SUCCESS', message: build.description],
        [$class: 'BetterThanOrEqualBuildResult', result: 'FAILURE', state: 'FAILURE', message: build.description],
        [$class: 'AnyBuildResult', state: 'FAILURE', message: 'Loophole']
      ]
    ]
  ])
}

如果你不想打擾專門的插件,這里有一個使用curl的替代方案:

post {
  success {
    withCredentials([usernamePassword(credentialsId: 'your_credentials_id', usernameVariable: 'USERNAME', passwordVariable: 'PASSWORD')]) {
      sh 'curl -X POST --user $USERNAME:$PASSWORD --data  "{\\"state\\": \\"success\\"}" --url $GITHUB_API_URL/statuses/$GIT_COMMIT'
    }
  }
  failure {
    withCredentials([usernamePassword(credentialsId: 'your_credentials_id', usernameVariable: 'USERNAME', passwordVariable: 'PASSWORD')]) {
      sh 'curl -X POST --user $USERNAME:$PASSWORD --data  "{\\"state\\": \\"failure\\"}" --url $GITHUB_API_URL/statuses/$GIT_COMMIT'
    }
  }
}

GITHUB_API_URL通常是這樣構造的,例如在environment指令中:

environment {
   GITHUB_API_URL='https://api.github.com/repos/organization_name/repo_name'
}

可以從Jenkins -> Credentials創建和獲取credentialsId

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM