How to set github commit status with Jenkinsfile N

2019-02-03 10:01发布

问题:

We have Jenkins 2 set to build every push to github, and we do not use the Pull Request builder (although commits that are part of a pull request obviously will get built, as well). The GitHub Integration Plugin says that it only works with the pull request builder, so this won't work for us.

I've also tried the github-notify plugin, but it seems not to work for our case (possibly because the repo is private and/or owned as part of an Organizaiton, rather than an individual user). I have tried letting it infer settings as well as manually specifying credentialsId, account, repo, and of course status arguments, all with no luck.

Here's an abbreviated version of my Jenkinsfile at the moment:

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"
        }
    }
}

When I run the build, I get the following:

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)

I've tested the credentials both through Jenkins (in the Configure System area) and manually in a browser -- the username and password are correct, and have read/write access to the repo in question.

回答1:

Per the Jenkins GitHub plugin's own example:

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");
    }
  }
}

No superfluous plugins necessary. So long as you have the GitHub plugin installed and correctly configured, you shouldn't even need to do the above, it should happen automatically. We aren't using the Pull Request builder either but are instead using the Jenkins Multibranch Pipeline. We're merely using the above snippet for additional status granularity in our PR's.



回答2:

First, make sure those credentials are global ones, not folder credentials.
The latter is not yet supported and would generate a similar error message: see JENKINS-42955 (still in review)

Second, if those credentials works in a browser but not through a DSL config file lie a jenkinsfile, that might be due to special characters in the name or password: see if you don't have to percent encode reserved characters.



回答3:

It didn't occur to me that value in account parameter must not match user in credentials. In account you must specify repository owner. And in credentialsId you may use any user with push access to the repository:

credentialsId: The id of the github's credentials to use, must be of type UsernameAndPassword. Make sure the credentials have write access, as stated by doc: Users with push access can create commit statuses for a given ref

account: The account that owns the repository