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