Pro Yearly is on sale from $80 to $50! »

Improving your workflow with the GitHub API

B47b288784fda77a94aeb234ca743c24?s=47 Keavy McMinn
October 11, 2017
420

Improving your workflow with the GitHub API

B47b288784fda77a94aeb234ca743c24?s=128

Keavy McMinn

October 11, 2017
Tweet

Transcript

  1. Improving your workflow With GitHub’s API keavy

  2. 533 endpoints

  3. Hello world.

  4. Unauthenticated requests curl https://api.github.com/zen Practicality beats purity.

  5. Unauthenticated requests curl -i https://api.github.com/users/keavy

  6. Unauthenticated requests

  7. Authenticated requests curl -i -u keavy:passw0rd https://api.github.com/keavy

  8. GraphQL API https://developer.github.com/v4/

  9. REST API https://developer.github.com/v3/

  10. Then what?

  11. Options for authentication • Personal Access Token • OAuth Application

    • GitHub Application
  12. Personal Access Token • It’s a String (“f3e4b0c62a15dc2e5c…”) • Like

    a password • Functions like an OAuth token - broad permissions.
  13. Personal Access Token: Good Ideas! • Acting just as yourself

    • Authenticating over the API as yourself • One off cURL commands • Personal scripts
  14. Personal Access Token: Bad Ideas! • Setting up something for

    your whole team/company to use • Pretending to be a bot
  15. None
  16. OAuth Application • It’s an application. • It needs to

    be hosted somewhere. • You grant it broad permissions, e.g. to your repositories.
  17. OAuth Application: Good Ideas! • Act as a GitHub user,

    across all of GitHub • Just identity - “login with GitHub”
  18. OAuth Application: Bad Ideas! • Doing stuff on a specific

    repository (but not the rest!) • Doing stuff that should be acting as the Application itself
  19. None
  20. GitHub App • It’s an application. • It needs to

    be hosted somewhere. • You install it on specific repositories. • You grant it narrow permissions, e.g. to write issues
  21. GitHub App: Good Ideas! • The app needs to take

    actions, independently of a user • You only want to do stuff on specific repos • You want a direct connection to an Organization • You don't need to know and do everything the user can
  22. GitHub App: Bad Ideas! • Identity provider: "login with GitHub”

    • Only want to act as the GitHub user, in everything they can do.
  23. None
  24. Which is right? For you.

  25. None
  26. For you

  27. API calls export GITHUB_TOKEN=47244ff0d0464521969 curl -u keavy:$GITHUB_TOKEN https://api.github.com/user/issues

  28. Script to fetch your contributions : ${GITHUB_TOKEN:=`git config github.token`} :

    ${GH_LOGIN:=`git config github.user`} # e.g. for PRs I opened that were merged query = "author:$GH_LOGIN+is:merged+is:pr" url="https://api.github.com/search/issues? access_token=$GITHUB_TOKEN&q=$query"
  29. For your team

  30. Script GitHub App

  31. GitHub App Slack App Email In-house App Another API GitHub

  32. Improving your workflow With GitHub’s API keavy

  33. Some examples

  34. Contributions for <username>

  35. PRs labeled with <label_name>

  36. PRs awaiting your team’s response

  37. Create an issue for your Team’s activity

  38. Create an issue for your Team’s activity

  39. How to build them

  40. 1. Register a GitHub App 2. Configure your app 3.

    Host it somewhere 4. Install it on the desired repos on GitHub 5. Steps to building a GitHub App
  41. Step 1: Register a GitHub App

  42. Step 1: Register a GitHub App

  43. Step 1: Register a GitHub App

  44. Step 1: Register a GitHub App

  45. Step 1: Register a GitHub App https://developer.github.com/webhooks/securing/

  46. Protip

  47. Protip

  48. Step 1: Register a GitHub App https://developer.github.com/v3/apps/permissions/

  49. None
  50. Step 2: Configure your GitHub App

  51. None
  52. What installations do I have? Who am I? What installations

    can I show this user? Give me a token for this installation.
  53. What installations do I have? Who am I? What installations

    can I show this user? Give me a token for this installation. Authenticate as the App
  54. def self.private_key pem = ENV["GITHUB_APP_PRIVATE_KEY"] @private_key ||= OpenSSL::PKey::RSA.new(pem) end Configure

    your GitHub App App credentials
  55. payload = { iat: Time.now, exp: 10.minute.from_now, iss: ENV["GITHUB_APP_IDENTIFIER"] }

    JWT.encode payload, Config.private_key, "RS256" Configure your GitHub App App credentials
  56. @app_client = Octokit::Client.new( bearer_token: Demo::Config.jwt_assertion) Configure your GitHub App To

    make high-level API requests as the App
  57. @app_client.get "/app" Configure your GitHub App To make high-level API

    requests as the App https://developer.github.com/v3/apps/
  58. What repositories can I work with? What repositories can I

    show this user? What are the latest PRs in this repo? What members are in this team? What issues have mentioned this team lately?
  59. What repositories can I work with? What repositories can I

    show this user? What are the latest PRs in this repo? What members are in this team? What issues have mentioned this team lately? Authenticate as the installation
  60. client.create_integration_installation_access_token( installation_github_identifier ) Configure your GitHub App To make API

    requests for a specific installation
  61. @installation_client = Octokit::Client.new( :access_token => @installation.current_token ) Configure your GitHub

    App To make API requests for a specific installation
  62. @installation_client.get "/installation/repositories" Configure your GitHub App To make API requests

    for a specific installation https://developer.github.com/v3/apps/installations/
  63. Watch out for

  64. 401 But whyyyyy?

  65. 401 But I’m doing everything right. Right?!

  66. 401 Clearly the API just hates me.

  67. 401 &&& Oh. It was that.

  68. It’s good to talk. ''' https://platform.github.community/

  69. Step 3: Host it somewhere

  70. None
  71. Step 4: Install it

  72. None
  73. None
  74. post "/webhook" do case request.env['HTTP_X_GITHUB_EVENT'] when "installation" Demo::Installation.create_from_webhook( parsed_post_params["installation"] )

    end halt 200 end Configure your GitHub App https://developer.github.com/v3/activity/events/types/#installationevent
  75. Step 5: Use it!

  76. GitHub App Slack App Email In-house App Another API GitHub

  77. Connect it to a Slack App

  78. Create or change content on GitHub

  79. Send an email

  80. API details

  81. Contributions for <username>

  82. Process the request POST http://my-app.com/contributions text=keavy

  83. Process the request POST http://my-app.com/contributions text=keavy login

  84. # PRs the user opened @installation.client.search_issues( “created:>#{started_at_string} @#{@account} author:#{login} type:pr

    state:open") Search for the data
  85. # PRs the user opened @installation.client.search_issues( “created:>#{started_at_string} @#{@account} author:#{login} type:pr

    state:open") Search for the data
  86. # PRs the user opened @installation.client.search_issues( “created:>#{started_at_string} @#{@account} author:#{login} type:pr

    state:open") Search for the data
  87. # PRs the user opened @installation.client.search_issues( “created:>#{started_at_string} @#{@account} author:#{login} type:pr

    state:open") Search for the data
  88. # PRs the user commented on @installation.client.search_issues( “created:>#{started_at_string} @#{@account} commenter:#{login}

    type:pr state:open") Search for the data
  89. https://developer.github.com/v3/libraries/ client.search_issues

  90. None
  91. # PRs the user opened @installation.client.search_issues( “created:>#{started_at_string} @#{@account} author:#{login} type:pr

    state:open") Search for the data
  92. https://developer.github.com/v3/search/#search-issues { "total_count": 280, "incomplete_results": false, "items": [ { "html_url":

    "https://github.com/batterseapower/pinyin-toolkit/issues/132", "number": 132, "title": "Line Number Indexes Beyond 20 Not Displayed", "user": { "login": "Nick3C", }, "labels": [ { "url": "https://api.github.com/repos/batterseapower/pinyin-toolkit/labels/bug", "name": "bug", "color": "ff0000" } ], "state": "open" } ] }
  93. https://developer.github.com/v3/search/#search-issues { "total_count": 280, "incomplete_results": false, "items": [ { "html_url":

    "https://github.com/batterseapower/pinyin-toolkit/issues/132", "number": 132, "title": "Line Number Indexes Beyond 20 Not Displayed", "user": { "login": "Nick3C", }, "labels": [ { "url": "https://api.github.com/repos/batterseapower/pinyin-toolkit/labels/bug", "name": "bug", "color": "ff0000" } ], "state": "open" } ] }
  94. def formatted_results(category, items) "\n### #{category} (#{items.count})\n" + # format each

    item end def formatted_result(item) # get the repo name for that item " * [x] [#{repo}##{item.number}](#{item.html_url}) #{item.title}" end Format the results
  95. def deliver!(content) status = 200 content_type :json { :response_type =>

    'in_channel', :text => content }.to_json end Send the results to a Slack App
  96. Contributions for <username>

  97. PRs labeled with <label_name>

  98. Process the request POST http://my-app.com/labeled text=reviewable,bug

  99. Process the request POST http://my-app.com/labeled text=reviewable,bug labels

  100. is:open is:pr repo:org/repo_a repo:org/repo_b label:reviewable label:bug -label:blocked Build up a

    query
  101. https://github.com/search/advanced Protip

  102. # Search issues via the API @installation.client.search_issues(query.join(" ")).items Request the

    data from the API
  103. PRs labeled with <label_name>

  104. PRs awaiting your team’s response

  105. Build the query is:open is:pr org:api-playground team:api-playground/test-team -commenter:keavy -commenter:tarebyte updated:>2017-09-13

  106. @installation.client.search_issues(query.join(" ")).items Request the data from the API

  107. None
  108. PRs awaiting your team’s response

  109. Create an issue for your Team’s activity

  110. Process the request POST http://my-app.com/radar text=@api-playground/test-team api-sandbox

  111. Process the request POST http://my-app.com/radar text=@api-playground/test-team api-sandbox team_name repo_name

  112. Prepare the content # Check for data from other tools,

    e.g. who’s on call via PagerDuty # Check for checkbox items from the previous week’s radar # Prepare the text bits: @title ||= "Radar: Week of #{Date.today}” @body << "What's up, #{team_name}? What happened? " + "What's about to happen? What's going on in your head? "
  113. Deliver output @installation.client.create_issue(@repo_name, @title, @body)

  114. Deliver output @installation.client.create_issue(@repo_name, @title, @body)

  115. Create an issue for your Team’s activity

  116. Possibilities

  117. Onboard new team member https://developer.github.com/v3/orgs/teams/ https://developer.github.com/v3/repos/collaborators/ • Add someone as

    a collaborator to certain repositories • Add them to certain teams (and/or the organization itself)
  118. PR approval process https://developer.github.com/v3/orgs/teams/ • At least 2 people have

    reviewed a PR • The PR has been reviewed by someone who didn’t write the code • Separate approval for the code AND deployment • A manager has approved it, on the 2nd Wednesday of the month
  119. PR approval process https://developer.github.com/v3/orgs/teams/ • At least 2 people have

    reviewed a PR • The PR has been reviewed by someone who didn’t write the code • Separate approval for the code AND deployment • A manager has approved it, on the 2nd Wednesday of the month
  120. We’re hiring

  121. PR approval process https://developer.github.com/v3/orgs/teams/ • At least 2 people have

    reviewed a PR • The PR has been reviewed by someone who didn’t write the code • Separate approval for the code AND deployment • A manager has approved it, on the 2nd Wednesday of the month
  122. List commits on a PR https://developer.github.com/v3/pulls/#list-commits-on-a-pull-request

  123. List commits on a PR https://developer.github.com/v3/pulls/#list-commits-on-a-pull-request [ { "sha": "6dcb09b5b57875f334f61aebed695e2e4193db5e",

    "commit": { "url": "https://api.github.com/repos/octocat/Hello-World/git/commits/6dcb09b5", "message": "Fix all the bugs", }, "author": { "login": "octocat", "id": 1 } } ]
  124. List commits on a PR https://developer.github.com/v3/pulls/#list-commits-on-a-pull-request [ { "sha": "6dcb09b5b57875f334f61aebed695e2e4193db5e",

    "commit": { "url": "https://api.github.com/repos/octocat/Hello-World/git/commits/6dcb09b5", "message": "Fix all the bugs", }, "author": { "login": "octocat", "id": 1 } } ]
  125. List reviews on a PR https://developer.github.com/v3/pulls/reviews/#list-reviews-on-a-pull-request

  126. List reviews on a PR https://developer.github.com/v3/pulls/reviews/#list-reviews-on-a-pull-request [ { "id": 80,

    "user": { "login": "octocat", "id": 1 }, "body": "Here is the body for the review." } ]
  127. List reviews on a PR https://developer.github.com/v3/pulls/reviews/#list-reviews-on-a-pull-request [ { "id": 80,

    "user": { "login": "octocat", "id": 1 }, "body": "Here is the body for the review." } ]
  128. Create a status https://developer.github.com/v3/repos/statuses/#create-a-status POST /repos/:owner/:repo/statuses/:sha { "state": "success", "description":

    "Approved by the wider crew", "context": "Review Process" }
  129. Create a status https://developer.github.com/v3/repos/statuses/#create-a-status

  130. Improving your workflow With GitHub’s API keavy

  131. Work back from the problem • I want an ‘at

    a glance’ view of current bugs. • I want to check what PRs my team should look into. • I want to know what my team is up to.
  132. Then from what you want to get

  133. Then from what you want to get

  134. Then from what you want to get

  135. Reference

  136. It’s good to talk. ''' https://platform.github.community/

  137. 401 Clearly the API just hates me.

  138. 200 I made that.

  139. Thank you. keavy