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

Add support for GitHub app authentication #269

Merged
merged 19 commits into from
Mar 4, 2020

Conversation

timja
Copy link
Member

@timja timja commented Jan 25, 2020

  • JENKINS issue(s):
  • Description:
    • Adds support for authenticating as a GitHub app (see the jira for more information)
  • Documentation changes:
    • I've added a guide to this repo internally, can easily be ported elsewhere if needed
  • Users/aliases to notify:

@ojacques
Copy link
Contributor

Great! If we wanted to try - would generating a locally built github-api-plugin version 1.102 work?

@timja
Copy link
Member Author

timja commented Jan 26, 2020

You’ll need to compile locally:
GitHub-api
GitHub-api-plugin
This PR

It’s based off 1.101 but version shouldn’t matter too much as long as it’s recent

@oleg-nenashev oleg-nenashev self-requested a review January 27, 2020 16:46
@bitwiseman
Copy link
Contributor

@ojacques @timja You can now switch to just a local build of this PR. The other two items have been merged.

Copy link
Contributor

@bitwiseman bitwiseman left a comment

Choose a reason for hiding this comment

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

Looking good. A few questions. Probably a few more once you've added that test coverage you want to.

@timja
Copy link
Member Author

timja commented Jan 29, 2020

@bitwiseman I might need some guidance on the tests you would like to see here, I commented out the existing code around auth and all the tests passed so i don’t think there’s any existing coverage

private static PrivateKey getPrivateKeyFromString(final String key) throws GeneralSecurityException {
if (key.contains("RSA")) {
throw new InvalidPrivateKeyException(
"Private key must be a PKCS#8 formatted string, to convert it from PKCS#1 use: "
Copy link
Member Author

Choose a reason for hiding this comment

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

we could add a dependency to bouncy castle then we could handle this? or ask users to convert it?

Copy link
Contributor

Choose a reason for hiding this comment

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

Let's start with asking user to do this. Smoothing can be a later release.

Copy link
Member

Choose a reason for hiding this comment

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

There is a Bouncy Castle API Plugin that was split from Jenkins core in the past and has a wide install base that you can depend on for this kind of thing, but I agree that it seems best to save that for later.

@timja timja marked this pull request as ready for review January 30, 2020 18:05
@timja
Copy link
Member Author

timja commented Feb 1, 2020

Great! If we wanted to try - would generating a locally built github-api-plugin version 1.102 work?

@ojacques did you get a chance to try this? I've just pushed documentation for it
https://github.com/timja/github-branch-source-plugin/blob/github-app-support/docs/github-app.adoc

@ojacques
Copy link
Contributor

ojacques commented Feb 2, 2020

@ojacques did you get a chance to try this? I've just pushed documentation for it
https://github.com/timja/github-branch-source-plugin/blob/github-app-support/docs/github-app.adoc

@timja, thanks for everything, and for the doc (I will suggest some modifications about it later).
Unfortunately, I was not able to get this going. Note that this is with a GitHub enterprise instance, but that should not matter.

I'm getting this:
image

It looks like this is failing in Connector.java, at GHApp app = gitHubApp.getApp();.

145 is my github app ID (which is not the installation id).
I "installed" the app in the github organization I want to get access to, but that did not make a difference.

My test environment is: github enterprise, the github-branch-source-plugin compiled fresh from this PR and Jenkins 2.219 running in a container.

Any idea?

@timja
Copy link
Member Author

timja commented Feb 2, 2020

Do you know what version of GHE you are on?

I've pushed more logging, which might help debug it

@ojacques
Copy link
Contributor

ojacques commented Feb 2, 2020

Do you know what version of GHE you are on?

2.19.6

@timja
Copy link
Member Author

timja commented Feb 2, 2020

Could you try re-build a fresh version, (or wait for CI which will give you one too if you just want to download it)

I've added additional logging to help debug it

@ojacques
Copy link
Contributor

ojacques commented Feb 2, 2020

It looks like it tries to talk to api.github.com, not the github enterprise URL that is configured:

Exception validating credentials 145
java.io.FileNotFoundException: https://api.github.com/app
	at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1896)
	at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1498)
	at java.net.HttpURLConnection.getResponseCode(HttpURLConnection.java:480)
	at sun.net.www.protocol.https.HttpsURLConnectionImpl.getResponseCode(HttpsURLConnectionImpl.java:352)
	at org.kohsuke.github.Requester._fetchOrRetry(Requester.java:523)
Caused: java.io.FileNotFoundException: https://api.github.com/app

The end point should be https://github.xyz.com/api/v3, which is the one that is selected as the API end point, just above "credentials" drop down.

@timja
Copy link
Member Author

timja commented Feb 2, 2020

Should be fixed now, please re test

@ojacques
Copy link
Contributor

ojacques commented Feb 3, 2020

Thanks @timja, update from my testing:

  • ✔ I can scan a github org (GitHub enterprise) with Jenkins as a GitHub app! 🎉 🎆
  • For the organization scan to fully work, I had to give the GitHub app more "repository" type permissions:
    • Contents: read-only (to read the Jenkinsfile, and I was expecting also to be able to get the code from the repo)
    • Metadata: Read-only (was set automatically)
    • Pull requests: read-only (without this one, the scan was not fully completing as it looks through PRs / branches to create all the jobs)
    • Commit status: read-write (this one is as per your doc)
  • ❌ Yet, the actual jobs are failing: they can't seem to get repo content from GitHub:
    image

For that git phase, the credential used seems to be an ssh key (using GIT_SSH to set credentials) - probably the one set for the GitHub app. Shouldn't this be a token instead (which is what we get from a GitHub app)?

Great progress in any case!

@timja
Copy link
Member Author

timja commented Feb 4, 2020

@ojacques I've pushed a temporary fix, not sure how this was working for me locally, but it's not anymore.

@ojacques
Copy link
Contributor

ojacques commented Feb 4, 2020

Fetching repo / running jobs still does not work:
image

I could be available on slack or gitter if needed.

After some discussions and more tests:

  • This PR does work "as is" with github.com and public repos
  • It needs more work to support private repos on github.com or GitHub enterprise in "private mode"

@timja
Copy link
Member Author

timja commented Feb 4, 2020

We've had a chat on gitter, the GHE issue can be re-produced on Github.com by trying to checkout a private repo, for some reason the creds aren't being used on checkout

@oleg-nenashev
Copy link
Member

I am fine. We can always generalize it later if needed

@oleg-nenashev
Copy link
Member

FYI @sladyn98 @uhafner, the functionality created here could be reused in the GitHub Checks API integration project. https://jenkins.io/projects/gsoc/2020/project-ideas/github-checks/

@bitwiseman bitwiseman merged commit b42dd6b into jenkinsci:master Mar 4, 2020
@sladyn98
Copy link

sladyn98 commented Mar 5, 2020

@oleg-nenashev Yes this is definitely reusable, I used a part of this code in my POC for the Github Checks API Plugin.https://github.com/sladyn98/JenkinsChecksPOC

@timja timja deleted the github-app-support branch March 5, 2020 15:17
@ojacques
Copy link
Contributor

ojacques commented Mar 5, 2020

FYI @sladyn98 @uhafner, the functionality created here could be reused in the GitHub Checks API integration project. https://jenkins.io/projects/gsoc/2020/project-ideas/github-checks/

Yes. Here is a PoC which posts a checks run using a valid authentication token issued from Jenkins as GitHub App, all with Jenkinsfile:
image

image

pipeline {
  agent any

  stages{
    stage('Check run PoC') { 
      steps {
        withCredentials([usernamePassword(credentialsId: 'githubapp-jenkins', usernameVariable: 'GITHUB_APP', passwordVariable: 'GITHUB_JWT_TOKEN')]) {
        sh '''
        curl -H "Content-Type: application/json" -H "Accept: application/vnd.github.antiope-preview+json" -H "authorization: Bearer ${GITHUB_JWT_TOKEN}" -d '{ "name": "check_run", "head_sha": "'${GIT_COMMIT}'", "status": "in_progress", "external_id": "42", "started_at": "2020-03-05T11:14:52Z", "output": { "title": "Check run from Jenkins!", "summary": "This is a check run which has been generated from Jenkins as GitHub App", "text": "...and that iss awesome"}}' https://github.xyz.com/api/v3/repos/ojacques/jenkins-with-githubapp/check-runs
        '''
        }
      }
    }
  }
}

@timja
Copy link
Member Author

timja commented Mar 5, 2020

FYI @sladyn98 @uhafner, the functionality created here could be reused in the GitHub Checks API integration project. jenkins.io/projects/gsoc/2020/project-ideas/github-checks

Yes. Here is a PoC which posts a checks run using a valid authentication token issued from Jenkins as GitHub App, all with Jenkinsfile:
image

image

pipeline {
  agent any

  stages{
    stage('Check run PoC') { 
      steps {
        withCredentials([usernamePassword(credentialsId: 'githubapp-jenkins', usernameVariable: 'GITHUB_APP', passwordVariable: 'GITHUB_JWT_TOKEN')]) {
        sh '''
        curl -H "Content-Type: application/json" -H "Accept: application/vnd.github.antiope-preview+json" -H "authorization: Bearer ${GITHUB_JWT_TOKEN}" -d '{ "name": "check_run", "head_sha": "cd2cf268e59fdf2e11fb677a4ca1a53f58826e0c", "status": "in_progress", "external_id": "42", "started_at": "2020-03-05T11:14:52Z", "output": { "title": "Check run from Jenkins!", "summary": "This is a check run which has been generated from Jenkins as GitHub App", "text": "...and that iss awesome"}}' https://github.xyz.com/api/v3/repos/ojacques/jenkins-with-githubapp/check-runs
        '''
        }
      }
    }
  }
}

Nice!

It'll be great once it's fully integrated,

tests showing up there
warnings on PR
lint results
ability to re-run

etc

@uhafner
Copy link
Member

uhafner commented Mar 5, 2020

Yes, that looks very promising!

@sladyn98
Copy link

sladyn98 commented Mar 6, 2020

@ojacques Has this (reporting to Checks API) already been implemented as a Pipeline step
cc @timja

@droidpl
Copy link

droidpl commented Mar 10, 2020

When do you plan to create a release with this?

@ojacques
Copy link
Contributor

@ojacques Has this (reporting to Checks API) already been implemented as a Pipeline step

We did not yet, but were looking to start.

@sladyn98
Copy link

@ojacques okay cool, i would love to contribute, since it is a part of my proposal for the github Checks API

@oleg-nenashev
Copy link
Member

@timja I will try to facilitate the release. Just in case, would you be interested to write a blogpost about this feature or to present it at one of the next Jenkins Online Meetups?

@timja
Copy link
Member Author

timja commented Mar 17, 2020

@timja I will try to facilitate the release. Just in case, would you be interested to write a blogpost about this feature or to present it at one of the next Jenkins Online Meetups?

yes, either / both.

@timja
Copy link
Member Author

timja commented Mar 20, 2020

@timja I will try to facilitate the release. Just in case, would you be interested to write a blogpost about this feature or to present it at one of the next Jenkins Online Meetups?

Draft blog post:
jenkins-infra/jenkins.io#2988

@jglick jglick mentioned this pull request Mar 20, 2020
@kad-kooija
Copy link

When will this be released?

@steve-norman-rft
Copy link

@bitwiseman
Copy link
Contributor

General release in the next week.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.