Подтвердить что ты не робот

Как установить статус фиксации github с помощью Jenkinsfile NOT с помощью построителя запросов pull

У нас есть Jenkins 2 для создания каждого нажатия на github, и мы не используем построитель запросов Pull (хотя фиксации, которые являются частью запроса на извлечение, также будут построены). GitHub Integration Plugin говорит, что он работает только с построителем запроса на тягу, поэтому это не сработает для нас.

Я также попробовал github-notify плагин, но, похоже, он не работает для нашего дела (возможно, потому что репо является приватным и/или принадлежит как часть Organizaiton, а не отдельному пользователю). Я попытался разрешить ему устанавливать параметры, а также вручную указывать аргументы credentialsId, account, repo и, конечно, status, все без везения.

Здесь сокращенная версия моего файла Jenkins в данный момент:

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 (в области "Конфигурация системы" ), так и вручную в браузере - правильное имя пользователя и пароль и доступ к чтению/записи для данного репо.

4b9b3361

Ответ 1

В соответствии с собственным примером плагина 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, вам даже не нужно делать вышеуказанное, это должно происходить автоматически. Мы также не используем конструктор запросов на извлечение, но вместо этого используем многоотраслевой конвейер Jenkins. Мы просто используем вышеупомянутый фрагмент для дополнительной детализации статуса в наших PR.

Ответ 2

Во-первых, убедитесь, что эти учетные данные являются глобальными, а не учетными данными папки.
Последний еще не поддерживается и JENKINS-42955 похожее сообщение об ошибке: см. JENKINS-42955 (все еще рассматривается)

Во-вторых, если эти учетные данные работают в браузере, но не через конфигурационный файл DSL, это может быть файл jenkinsfile, что может быть связано со специальными символами в имени или пароле: посмотрите, не нужно ли вам процентное кодирование зарезервированных символов.

Ответ 3

Мне не приходило в голову, что значение в параметре account не должно соответствовать пользователю в учетных данных. В account вы должны указать владельца репозитория. И в credentialsId вы можете использовать любого пользователя с push access в репозиторий:

credentialsId: идентификатор учетных данных github для использования должен иметь тип UsernameAndPassword. Убедитесь, что учетные данные имеют доступ на запись, а указанный в документе doc. Пользователи с push-доступом могут создавать статусы фиксации для данного ref

account: учетная запись, которой принадлежит репозиторий

Ответ 4

Лучший пример из документации:

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']
      ]
    ]
  ])
}

Ответ 5

Если вы не хотите беспокоиться о специализированных плагинах, вот альтернатива, использующая 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'
}

credentialsId может быть создан и получен из Jenkins -> Credentials