Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support GitHubAppCredentials owner inference when specified on a pipeline using GitHub SCM #396

Merged
merged 3 commits into from
Aug 21, 2024

Conversation

jeromepochat
Copy link
Contributor

GitHub App installed in multiple organizations get:

java.lang.IllegalArgumentException: Found multiple installations for GitHub app ID X but none match credential owner "". Set the right owner in the credential advanced options to one of: Y, Z
        at PluginClassLoader for github-branch-source//org.jenkinsci.plugins.github_branch_source.GitHubAppCredentials.generateAppInstallationToken(GitHubAppCredentials.java:244)
        at PluginClassLoader for github-branch-source//org.jenkinsci.plugins.github_branch_source.GitHubAppCredentials.getToken(GitHubAppCredentials.java:295)
        at PluginClassLoader for github-branch-source//org.jenkinsci.plugins.github_branch_source.GitHubAppCredentials$CredentialsTokenProvider.getEncodedAuthorization(GitHubAppCredentials.java:199)
        at PluginClassLoader for github-api//org.kohsuke.github.GitHubClient.prepareConnectorRequest(GitHubClient.java:616)
        at PluginClassLoader for github-api//org.kohsuke.github.GitHubClient.sendRequest(GitHubClient.java:455)
        at PluginClassLoader for github-api//org.kohsuke.github.GitHubClient.fetch(GitHubClient.java:159)
        at PluginClassLoader for github-api//org.kohsuke.github.GitHubClient.checkApiUrlValidity(GitHubClient.java:390)
        at PluginClassLoader for github-api//org.kohsuke.github.GitHub.checkApiUrlValidity(GitHub.java:1321)
        at PluginClassLoader for github-branch-source//org.jenkinsci.plugins.github_branch_source.ApiRateLimitChecker.verifyConnection(ApiRateLimitChecker.java:194)
        at PluginClassLoader for github-branch-source//org.jenkinsci.plugins.github_branch_source.Connector$GitHubConnection.verifyConnection(Connector.java:723)
        at PluginClassLoader for github-branch-source//org.jenkinsci.plugins.github_branch_source.Connector.connect(Connector.java:420)
        at PluginClassLoader for github-checks//io.jenkins.plugins.checks.github.GitHubChecksPublisher.publish(GitHubChecksPublisher.java:89)
        at PluginClassLoader for checks-api//io.jenkins.plugins.checks.status.BuildStatusChecksPublisher.publish(BuildStatusChecksPublisher.java:64)
        at PluginClassLoader for checks-api//io.jenkins.plugins.checks.status.BuildStatusChecksPublisher$JobCompletedListener.lambda$onCompleted$0(BuildStatusChecksPublisher.java:188)
        at java.base/java.util.Optional.ifPresent(Optional.java:178)
        at PluginClassLoader for checks-api//io.jenkins.plugins.checks.status.BuildStatusChecksPublisher$JobCompletedListener.onCompleted(BuildStatusChecksPublisher.java:188)
        at hudson.model.listeners.RunListener.lambda$fireCompleted$0(RunListener.java:223)
        at jenkins.util.Listeners.lambda$notify$0(Listeners.java:59)
        at jenkins.util.Listeners.notify(Listeners.java:67)
        at hudson.model.listeners.RunListener.fireCompleted(RunListener.java:221)
        at PluginClassLoader for workflow-job//org.jenkinsci.plugins.workflow.job.WorkflowRun.finish(WorkflowRun.java:645)
        at PluginClassLoader for workflow-job//org.jenkinsci.plugins.workflow.job.WorkflowRun$GraphL.onNewHead(WorkflowRun.java:1068)
        at PluginClassLoader for workflow-cps//org.jenkinsci.plugins.workflow.cps.CpsFlowExecution.notifyListeners(CpsFlowExecution.java:1582)
        at PluginClassLoader for workflow-cps//org.jenkinsci.plugins.workflow.cps.CpsThreadGroup$3.run(CpsThreadGroup.java:512)
        at PluginClassLoader for workflow-cps//org.jenkinsci.plugins.workflow.cps.CpsVmExecutorService.lambda$wrap$2(CpsVmExecutorService.java:85)
        at hudson.remoting.SingleLaneExecutorService$1.run(SingleLaneExecutorService.java:139)
        at jenkins.util.ContextResettingExecutorService$1.run(ContextResettingExecutorService.java:28)
        at jenkins.security.ImpersonatingExecutorService$1.run(ImpersonatingExecutorService.java:68)
        at jenkins.util.ErrorLoggingExecutorService.lambda$wrap$0(ErrorLoggingExecutorService.java:51)
        at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539)
        at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
        at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
        at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
        at PluginClassLoader for workflow-cps//org.jenkinsci.plugins.workflow.cps.CpsVmExecutorService$1.call(CpsVmExecutorService.java:53)
        at PluginClassLoader for workflow-cps//org.jenkinsci.plugins.workflow.cps.CpsVmExecutorService$1.call(CpsVmExecutorService.java:50)
        at org.codehaus.groovy.runtime.GroovyCategorySupport$ThreadCategoryInfo.use(GroovyCategorySupport.java:136)
        at org.codehaus.groovy.runtime.GroovyCategorySupport.use(GroovyCategorySupport.java:275)
        at PluginClassLoader for workflow-cps//org.jenkinsci.plugins.workflow.cps.CpsVmExecutorService.lambda$categoryThreadFactory$0(CpsVmExecutorService.java:50)
        at java.base/java.lang.Thread.run(Thread.java:840)

Steps to reproduce:

  • install GitHub App in more than one organization
  • configure GitHub App Credentials with owner left blank to infer value
  • configure multi branch pipeline using GitHub branch source
  • trigger build

This fixes the issue by explicitly setting owner on contextualized credentials. This also needs jenkinsci/github-branch-source-plugin#803 to make it work. I manually tested this PR with github-branch-source-plugin snapshot. The owner is inferred as expected and the build runs without any exception.

Copy link

codecov bot commented Aug 20, 2024

Codecov Report

Attention: Patch coverage is 73.33333% with 4 lines in your changes missing coverage. Please review.

Project coverage is 71.77%. Comparing base (803edab) to head (1368851).
Report is 16 commits behind head on master.

Files Patch % Lines
...s/plugins/checks/github/GitHubChecksPublisher.java 71.42% 0 Missing and 4 partials ⚠️
Additional details and impacted files
@@             Coverage Diff              @@
##             master     #396      +/-   ##
============================================
- Coverage     71.80%   71.77%   -0.04%     
- Complexity      162      165       +3     
============================================
  Files            16       16              
  Lines           532      542      +10     
  Branches         51       52       +1     
============================================
+ Hits            382      389       +7     
- Misses          124      125       +1     
- Partials         26       28       +2     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

apiUri = gitHubAppCredentials.getApiUri();
if (context instanceof GitHubSCMSourceChecksContext) {
final var gitHubSCMSourceChecksContext = (GitHubSCMSourceChecksContext) context;
credentials = gitHubAppCredentials.withOwner(gitHubSCMSourceChecksContext.getOwner());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you could add a test to

which would verify the owner is passed along.

In the existing test the owner is set on the SCM context but not on the credentials

@@ -35,6 +36,9 @@ public class GitHubChecksPublisher extends ChecksPublisher {
private final PluginLogger buildLogger;
private final String gitHubUrl;

@Nullable
private StandardUsernameCredentials credentials;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

credentials where moved from method variable to class field. This helps GitHubChecksPublisherITest to check that owner is propagated from context to credentials.

@jeromepochat jeromepochat marked this pull request as ready for review August 21, 2024 12:32
@jeromepochat jeromepochat requested a review from a team as a code owner August 21, 2024 12:32
@timja timja added the enhancement New feature or request label Aug 21, 2024
@timja timja changed the title Fix GitHubAppCredentials owner inference Support GitHubAppCredentials owner inference when specified on a pipeline using GitHub SCM Aug 21, 2024
@timja timja merged commit 9c7da3c into jenkinsci:master Aug 21, 2024
18 of 19 checks passed
@jeromepochat jeromepochat deleted the fix-owner branch August 21, 2024 13:42
final var gitHubAppCredentials = (GitHubAppCredentials) credentials;
if (context instanceof GitHubSCMSourceChecksContext) {
final var gitHubSCMSourceChecksContext = (GitHubSCMSourceChecksContext) context;
credentials = gitHubAppCredentials.withOwner(gitHubSCMSourceChecksContext.getOwner());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FWIW, I think it is undesirable to have the withOwner method be considered a public API of the plugin. Is there a reason we cannot use Connector.lookupScanCredentials from github-branch-source instead to handle contextualization automatically? It looks like it would require some API changes to SCMFacade methods to have them accept an owner parameter, but would that be ok, or is there some fundamental problem with it?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds fine if someone wants to work on it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll create a follow-up PR ASAP.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants