{"id":227,"date":"2021-02-02T20:02:28","date_gmt":"2021-02-02T20:02:28","guid":{"rendered":"https:\/\/fde.cat\/?p=227"},"modified":"2021-02-02T20:02:29","modified_gmt":"2021-02-02T20:02:29","slug":"heroku-ci-and-github-checks-integration","status":"publish","type":"post","link":"https:\/\/fde.cat\/index.php\/2021\/02\/02\/heroku-ci-and-github-checks-integration\/","title":{"rendered":"Heroku CI and Github Checks Integration"},"content":{"rendered":"<h3>Heroku CI and GitHub Checks Integration<\/h3>\n<p>Before we dive into the crux of this article, let\u2019s first get an understanding of what GitHub Checks is and how it will be useful for you when you use any external Continuous Integration (CI) tool like <a href=\"https:\/\/circleci.com\/\">CircleCI<\/a>, <a href=\"https:\/\/devcenter.heroku.com\/articles\/heroku-ci\">Heroku CI<\/a>, or any local tool. The Checks functionality enables integrations to report more than just binary pass or fail to build statuses. Checks integrations can report rich statuses, annotate lines of code with detailed information, and kick off reruns. [Read more in the <a href=\"https:\/\/docs.github.com\/en\/free-pro-team@latest\/rest\/reference\/checks\">GitHub Checks Developer Guide<\/a>.]<\/p>\n<p>In this article, we\u2019ll talk specifically about GitHub Checks integration with Heroku CI, but the same method can be used with any CI tools that expose APIs to fetch CI logs. (Note that some well-known CI tools like <a href=\"https:\/\/circleci.com\/\">CircleCI<\/a>and <a href=\"https:\/\/www.jenkins.io\/\">Jenkins<\/a> have built-in or external plugins for integration, so for them you wouldn\u2019t have to follow this method unless you want to customize the Checks\u00a0output.)<\/p>\n<figure><img decoding=\"async\" alt=\"\" src=\"https:\/\/i0.wp.com\/cdn-images-1.medium.com\/max\/1024\/1*R_S7eG_5w5bzXyV059VtcA.png?w=750&#038;ssl=1\" data-recalc-dims=\"1\"><\/figure>\n<h3><strong>Introduction<\/strong><\/h3>\n<p>This article will help you to set up a <a href=\"https:\/\/probot.github.io\/docs\/\">Probot <\/a>app as an integration tool between Heroku CI and GitHub Checks using GitHub APIs. The first thing you might wonder is \u201c<strong>Why is this integration needed? Can\u2019t we just use Heroku App to see all the CI\u00a0logs?<\/strong>\u201d<\/p>\n<p>Well, you can use the Heroku app to see Heroku CI logs\u200a\u2014\u200abut consider a situation where people are contributing to your GitHub repo who don\u2019t have access to your Heroku Pipeline, such as in the case of an open source project with many contributors. In that case, if an automated test, lint, or other CI process fails for their commits, they will only see the boolean result, not the complete reason. With a GitHub Checks integration, they would be able to see the full result on the GitHub Checks tab, which would be very helpful for remediating the\u00a0issue.<\/p>\n<h3>Architecture<\/h3>\n<figure><img decoding=\"async\" alt=\"\" src=\"https:\/\/i0.wp.com\/cdn-images-1.medium.com\/max\/1024\/1*Tt1Y8LSMlcjK-E_Bt_D5Xw.png?w=750&#038;ssl=1\" data-recalc-dims=\"1\"><\/figure>\n<h3>How does it\u00a0work?<\/h3>\n<p><strong>GitHub Webhooks: <\/strong>As per <a href=\"https:\/\/docs.github.com\/en\/free-pro-team@latest\/developers\/webhooks-and-events\/about-webhooks\">GitHub Docs<\/a>, \u201cWebhooks allow you to build or set up integrations, such as <a href=\"https:\/\/developer.github.com\/apps\/building-github-apps\/\">GitHub Apps<\/a>or <a href=\"https:\/\/developer.github.com\/apps\/building-oauth-apps\/\">OAuth Apps<\/a>, which subscribe to certain events on GitHub.com. When one of those events is triggered, an HTTP POST payload is sent to the webhook\u2019s configured URL. Webhooks can be used to update an external issue tracker, trigger CI builds, update a backup mirror, or even deploy to your production server. You\u2019re only limited by your imagination.\u201d<\/p>\n<p><strong>Heroku CI<\/strong>: When a test or build gets triggered for a new git commit, it broadcasts the webhook events for Status. The event gets triggered for different stages like in_progress, success, failure, cancel, etc. GitHub catches those events and updates the pull request page build flag. For our scenario, we intercept statusin our integration app.<\/p>\n<pre>DEBUG probot: Webhook received<br>event: {<br>   \"event\": \"status\",<br>   \"id\": \"da6ec6b8-2250-11eb-8843-f0563e0c2987\",<br>   \"installation\": 12779415,<br>   \"repository\": \"&lt;Github-owner&gt;\/&lt;Repo-name&gt;\"<br>}<\/pre>\n<blockquote><p><em>Status (webhook event): When the status of a Git commit changes, the type of activity is specified in the <\/em><em>actionproperty of the payload\u00a0object.<\/em><\/p><\/blockquote>\n<p><strong>Probot Integration App: <\/strong>We created a Probot intermediate app that basically intercepts the GitHub webhook events and then executes specific logic as per our requirement. You can catch status events with the following code\u00a0snippet:<\/p>\n<pre>app.on('status', async (context) =&gt; {<br>    console.log('Status event update');<br>}<\/pre>\n<p>The \u201ccontext,\u201d in this case, is an object with details related to issues, pull request, repository, actions, etc. You will also find a related CI URL with context.payload.target_url. You can get the state of CI build \/ test using context.payload.state.<\/p>\n<p>Once you have the CI target URL, you can get logs directly from it or you can create a test log URL from it that will return a simple text log in response. For example, in Heroku CI, you will get a target URL from the context which will be in the format\u00a0of<\/p>\n<p><em>https:\/\/dashboard.heroku.com\/pipelines\/&lt;pipeline-id&gt;\/tests\/&lt;test-run-number&gt;<\/em><\/p>\n<p>The URL will look something like this, with your specifics:<\/p>\n<pre><a href=\"https:\/\/dashboard.heroku.com\/pipelines\/1fa8b9e6-1183-40f6-a66e-701b924b4d90\/tests\/259\">https:\/\/dashboard.heroku.com\/pipelines\/1fa8b9e6-1183-40f6-a66e-701b924b4d90\/tests\/259<\/a><\/pre>\n<p>And to get a plain text log, you can convert this URL to a different URL format which will be something like<em> https:\/\/api.heroku.com\/pipelines\/&lt;pipeline-id&gt;\/test-runs\/&lt;test-run-id&gt;<\/em>. Here\u2019s an\u00a0example:<\/p>\n<pre><a href=\"https:\/\/api.heroku.com\/pipelines\/1fa8b9e6-1183-40f6-a66e-701b924b4d90\/test-runs\/259\">https:\/\/api.heroku.com\/pipelines\/1fa8b9e6-1183-40f6-a66e-701b924b4d90\/test-runs\/259<\/a><\/pre>\n<p>If your Probot app receives a Statusevent with state in_progress, it will create a GitHub Checks run using <a href=\"https:\/\/developer.github.com\/v3\/checks\/runs\/\">Checks <\/a>API with the status \u201cIn Progress.\u201d You can do that with the following code:<\/p>\n<p><a href=\"https:\/\/medium.com\/media\/9318ca5aa3ddd934e38fa56fd8d3164a\/href\">https:\/\/medium.com\/media\/9318ca5aa3ddd934e38fa56fd8d3164a\/href<\/a><\/p>\n<p>Next, if your Probot app receives a Statusevent with the state failure, successor canceled, it will update the GitHub Checks run using the <a href=\"https:\/\/developer.github.com\/v3\/checks\/runs\/\">Checks <\/a>API with the status \u201cReceived.\u201d You will fetch all the checks run for a specific commit and then update the checks run (which has the status \u201cIn progress\u201d) with the latest\u00a0status.<\/p>\n<p><a href=\"https:\/\/medium.com\/media\/89c51a9ad8c120dc039e92c0aadbdcc4\/href\">https:\/\/medium.com\/media\/89c51a9ad8c120dc039e92c0aadbdcc4\/href<\/a><\/p>\n<p><strong>And we are all\u00a0set.<\/strong><\/p>\n<p>If you want to improve your user experience, there are a couple of additional things that can be tweaked in our integration implementation:<\/p>\n<ul>\n<li>Add the annotations object as part of the output in check run params to help to show errors and lint details for each commit file. (See this article for more details: <a href=\"https:\/\/developer.github.com\/changes\/2019-09-06-more-check-annotations-shown-in-files-changed-tab\/\">https:\/\/developer.github.com\/changes\/2019-09-06-more-check-annotations-shown-in-files-changed-tab\/<\/a>)<\/li>\n<li>Display a processed log for better presentation in Checks\u00a0Tab.<\/li>\n<\/ul>\n<h3>Conclusion<\/h3>\n<p>In order to keep all information related to pull requests and commits in one place, it\u2019s good to use various GitHub apps properly. That way, you don\u2019t have to worry whether external collaborators have access to all of your tooling or not, and you don\u2019t have to make your CI tool accessible to everyone. If you\u2019re not using GitHub Actions, but you are using Heroku CI or another CI tool, then this integration with GitHub Checks will prove very\u00a0useful.<\/p>\n<p>To see the complete code for the integration, visit this git repository: <a href=\"https:\/\/github.com\/SubratThakur\">SubratThakur<\/a>\/<a href=\"https:\/\/github.com\/SubratThakur\/Heroku-Github-Checks-Integration\">Heroku-Github-Checks-Integration<\/a>.<\/p>\n<h3>References:<\/h3>\n<ul>\n<li><a href=\"https:\/\/developer.github.com\/v3\/checks\/\">GitHub Checks<\/a><\/li>\n<li><a href=\"https:\/\/circleci.com\/docs\/2.0\/enable-checks\/\">Enabling GitHub Checks for\u00a0CircleCI<\/a><\/li>\n<li><a href=\"https:\/\/plugins.jenkins.io\/github-checks\/\">GitHub Checks plugin for\u00a0Jenkins<\/a><\/li>\n<li><a href=\"https:\/\/probot.github.io\/docs\/\">Probot App Dev\u00a0Docs<\/a><\/li>\n<li><a href=\"https:\/\/probot.github.io\/docs\/deployment\/\">Probot App Deployment Docs<\/a><\/li>\n<li>GitHub repo: <a href=\"https:\/\/github.com\/SubratThakur\">SubratThakur<\/a>\/<a href=\"https:\/\/github.com\/SubratThakur\/Heroku-Github-Checks-Integration\">Heroku-Github-Checks-Integration<\/a><\/li>\n<\/ul>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/medium.com\/_\/stat?event=post.clientViewed&amp;referrerSource=full_rss&amp;postId=a407d4c772a5\" width=\"1\" height=\"1\" alt=\"\"><\/p>\n<hr>\n<p><a href=\"https:\/\/engineering.salesforce.com\/heroku-ci-and-github-checks-integration-a407d4c772a5\">Heroku CI and Github Checks Integration<\/a> was originally published in <a href=\"https:\/\/engineering.salesforce.com\/\">Salesforce Engineering<\/a> on Medium, where people are continuing the conversation by highlighting and responding to this story.<\/p>\n<p><a href=\"https:\/\/engineering.salesforce.com\/heroku-ci-and-github-checks-integration-a407d4c772a5?source=rss----cfe1120185d3---4\" target=\"_blank\" rel=\"noopener\">Read More<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Heroku CI and GitHub Checks Integration Before we dive into the crux of this article, let\u2019s first get an understanding of what GitHub Checks is and how it will be useful for you when you use any external Continuous Integration (CI) tool like CircleCI, Heroku CI, or any local tool. The Checks functionality enables integrations&hellip; <a class=\"more-link\" href=\"https:\/\/fde.cat\/index.php\/2021\/02\/02\/heroku-ci-and-github-checks-integration\/\">Continue reading <span class=\"screen-reader-text\">Heroku CI and Github Checks Integration<\/span><\/a><\/p>\n","protected":false},"author":0,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"spay_email":"","footnotes":""},"categories":[7],"tags":[],"class_list":["post-227","post","type-post","status-publish","format-standard","hentry","category-technology","entry"],"jetpack_featured_media_url":"","jetpack-related-posts":[{"id":255,"url":"https:\/\/fde.cat\/index.php\/2021\/08\/31\/sre-weekly-issue-252\/","url_meta":{"origin":227,"position":0},"title":"SRE Weekly Issue #252","date":"August 31, 2021","format":false,"excerpt":"View on sreweekly.com A message from our sponsor, StackHawk: Interested in how you can automate application security testing with GitHub Actions? Check out this on demand webinar from StackHawk and Snyk and see how simple it is to get started. https:\/\/sthwk.com\/stackhawk-snyk Articles Building On-Call Culture at GitHub Their on-call started\u2026","rel":"","context":"In &quot;SRE&quot;","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":282,"url":"https:\/\/fde.cat\/index.php\/2021\/08\/31\/sre-weekly-issue-261\/","url_meta":{"origin":227,"position":1},"title":"SRE Weekly Issue #261","date":"August 31, 2021","format":false,"excerpt":"View on sreweekly.com A message from our sponsor, StackHawk: Join Snyk and StackHawk on March 18 as they walk through how to use Software Composition Analysis (SCA) and Dynamic Application Security Testing (DAST) in CI\/CD to ship more secure applications. http:\/\/sthwk.com\/snyk-stackhawk-webinar Articles What Do Fighter Pilots and Incident Management Have\u2026","rel":"","context":"In &quot;SRE&quot;","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":481,"url":"https:\/\/fde.cat\/index.php\/2021\/10\/04\/sre-weekly-issue-290\/","url_meta":{"origin":227,"position":2},"title":"SRE Weekly Issue #290","date":"October 4, 2021","format":false,"excerpt":"View on sreweekly.com A message from our sponsor, Rootly: Manage incidents directly from Slack with Rootly \ud83d\ude92. Automate manual admin tasks like creating incident channel, Jira and Zoom, paging the right team, postmortem timeline, setting up reminders, and more. Book a demo: https:\/\/rootly.io\/?utm_source=sreweekly Articles Postmortem: Partial RavenDB Cloud outage Despite\u2026","rel":"","context":"In &quot;SRE&quot;","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":825,"url":"https:\/\/fde.cat\/index.php\/2024\/02\/13\/inside-herokus-new-performance-analytics-tool-improving-user-experiences-and-developer-efficiency\/","url_meta":{"origin":227,"position":3},"title":"Inside Heroku\u2019s New Performance Analytics Tool: Improving User Experiences and Developer Efficiency","date":"February 13, 2024","format":false,"excerpt":"In our \u201cEngineering Energizers\u201d Q&A series, we delve into the remarkable journeys of engineering leaders who have made significant contributions in their respective fields. Today, we shine the spotlight on Zane Whitfield, a Member of the Technical Staff at Salesforce, supporting the Heroku Front-end Developer Tools (FDT) team. With a\u2026","rel":"","context":"In &quot;Technology&quot;","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":347,"url":"https:\/\/fde.cat\/index.php\/2021\/08\/31\/sre-weekly-issue-283\/","url_meta":{"origin":227,"position":4},"title":"SRE Weekly Issue #283","date":"August 31, 2021","format":false,"excerpt":"View on sreweekly.com I\u2019m on vacation enjoying the sunny beaches in Maine with my family, so I prepared this week\u2019s issue in advance.\u00a0 No outages section, save for\u00a0one big one I noticed due to direct personal experience.\u00a0 See you all next week! A message from our sponsor, StackHawk: StackHawk is\u2026","rel":"","context":"In &quot;SRE&quot;","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":625,"url":"https:\/\/fde.cat\/index.php\/2022\/08\/30\/hyperpacks-using-buildpacks-to-build-hyperforce\/","url_meta":{"origin":227,"position":5},"title":"Hyperpacks: Using Buildpacks to Build Hyperforce","date":"August 30, 2022","format":false,"excerpt":"At Salesforce we regularly use our products and services to scale our own business. One example is Buildpacks, which we created nearly a decade ago and is now a part of Hyperforce. Hyperpacks are an innovative new way of using Cloud Native Buildpacks (CNB) to manage our public cloud infrastructure.\u00a0\u2026","rel":"","context":"In &quot;Technology&quot;","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]}],"_links":{"self":[{"href":"https:\/\/fde.cat\/index.php\/wp-json\/wp\/v2\/posts\/227","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/fde.cat\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/fde.cat\/index.php\/wp-json\/wp\/v2\/types\/post"}],"replies":[{"embeddable":true,"href":"https:\/\/fde.cat\/index.php\/wp-json\/wp\/v2\/comments?post=227"}],"version-history":[{"count":1,"href":"https:\/\/fde.cat\/index.php\/wp-json\/wp\/v2\/posts\/227\/revisions"}],"predecessor-version":[{"id":241,"href":"https:\/\/fde.cat\/index.php\/wp-json\/wp\/v2\/posts\/227\/revisions\/241"}],"wp:attachment":[{"href":"https:\/\/fde.cat\/index.php\/wp-json\/wp\/v2\/media?parent=227"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/fde.cat\/index.php\/wp-json\/wp\/v2\/categories?post=227"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/fde.cat\/index.php\/wp-json\/wp\/v2\/tags?post=227"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}