Automating the GitHub *Nudge*
Tags: github, intelligentautomation, runbook
Published: 2023-04-13 22:39:28

---
title: Automating the GitHub *Nudge*
published: true
date: 2023-04-04 16:46:28 UTC
tags: Github,IntelligentAutomation, runbook
canonical_url: https://unskript.com/automating-the-github-nudge/
---

Git is a tool of Actions.  Millions of times a day, users checkout, push, pull and merge submissions to their repositories.  The scale is staggering:over 3.5 billion <a href="https://octoverse.github.com/2022/developer-community">contributions were made on GitHub in 2022</a>.  That’s 227 million Pull Requests merged, and over 31 million issues closed.  However, What about the PRs and the issues that fall through the cracks and are forgotten?  Should they be just left, forgotten (like the Island of Misfit toys in Rudolf the RedNosed Reindeer?)

<p>In this post, we introduce an automated RunBook that introduces the “Github nudge.” Merriam-Webster’s <a href="https://www.merriam-webster.com/dictionary/nudge">definition</a> for a nudge is “to prod lightly <strong>: </strong>urge into action.”  The GitHub nudge identifies issues and PRs that have been sitting a while, and “nudges” the assignee to take a look.  By not letting the team forget that the issues exist – they are more likely to be acted upon!</p>
<p>We’ve defined a few Actions in unSkript’s RunBook architecture to help us along this path:</p>
<h2>Stale Issues</h2>
<p>When issues have been assigned to a team member, but no work is being done on them, the issue has probably “gotten lost.”  Everyone has a lot to work on, and sometimes these issues just lose priority – or get superseded by other tasks.  That does not mean that they should just be ignored – resolving the issue will improve the project.</p>
<p>In unSkript, there is an Action to find “stale” issues: that is issues that are over a certain age.</p>
<p><img decoding="async" src="https://i0.wp.com/unskript.com/wp-content/uploads/2023/04/Screenshot-2023-04-02-at-21.27.45.jpg?resize=840%2C166&amp;ssl=1" alt="GitHub Stale issues" width="840" height="166" srcset="https://i0.wp.com/unskript.com/wp-content/uploads/2023/04/Screenshot-2023-04-02-at-21.27.45.jpg?w=840&amp;ssl=1 840w, https://i0.wp.com/unskript.com/wp-content/uploads/2023/04/Screenshot-2023-04-02-at-21.27.45.jpg?resize=300%2C59&amp;ssl=1 300w, https://i0.wp.com/unskript.com/wp-content/uploads/2023/04/Screenshot-2023-04-02-at-21.27.45.jpg?resize=768%2C152&amp;ssl=1 768w, https://i0.wp.com/unskript.com/wp-content/uploads/2023/04/Screenshot-2023-04-02-at-21.27.45.jpg?resize=806%2C159&amp;ssl=1 806w, https://i0.wp.com/unskript.com/wp-content/uploads/2023/04/Screenshot-2023-04-02-at-21.27.45.jpg?resize=558%2C110&amp;ssl=1 558w, https://i0.wp.com/unskript.com/wp-content/uploads/2023/04/Screenshot-2023-04-02-at-21.27.45.jpg?resize=655%2C129&amp;ssl=1 655w, https://i0.wp.com/unskript.com/wp-content/uploads/2023/04/Screenshot-2023-04-02-at-21.27.45.jpg?resize=24%2C5&amp;ssl=1 24w" sizes="(max-width: 840px) 100vw, 840px" data-recalc-dims="1"></p>
<p>This Action takes 3 input parameters – the Github owner and repository and the threshold (in days) upon which you define an issue as stale.  In the case of our repository <a href="https://github.com/unskript/Awesome-CloudOps-Automation">https://github.com/unskript/Awesome-CloudOps-Automation</a>, the owner is unskript, the repo is Awesome-CloudOps-Automation, and we set the stale threshold at 14 days.  There’s no real science around that day -it felt like a good number for our team.</p>
<p>The response is an array of issues that surpass that threshold. With this data, we can do some quick examinations:</p>
<h3>Issues without an assignee</h3>
<p>Issues that have not been assigned to a resource are not going to be worked on – we all have a lot on our plate already!  In the case of Awesome-CloudOps-Automation – these are all “good first issues” for those interested in contributing.  I like to scan this list once a week for changes – and to ensure that issues that <strong>do</strong> need work are properly assigned.</p>
<h3>Issues with an assignee</h3>
<p>If an issue has been around for 2 weeks, and is not yet resolved – its good to check on them to see the status – and that action is being made:</p>
<p>For example – it appears that issue 346 is assigned to me, and I am overdue with an update (oops!):</p>
<pre>{'assignee': NamedUser(login="dougsillars"),
   'issue_number': 346,
   'title': '[Action]: GitHub Comment on an issue'}

</pre>
<p>In this case, the PR was already merged, but not connected to the issue, so it could be closed (whew!).</p>
<p> </p>
<h2>Stale Pull Requests</h2>
<p>We can do the same thing for Pull Requests:</p>
<p><img decoding="async" loading="lazy" src="https://i0.wp.com/unskript.com/wp-content/uploads/2023/04/Screenshot-2023-04-04-at-12.14.30.jpg?resize=578%2C168&amp;ssl=1" alt="Stale PR Action in unSkript" width="578" height="168" srcset="https://i0.wp.com/unskript.com/wp-content/uploads/2023/04/Screenshot-2023-04-04-at-12.14.30.jpg?w=578&amp;ssl=1 578w, https://i0.wp.com/unskript.com/wp-content/uploads/2023/04/Screenshot-2023-04-04-at-12.14.30.jpg?resize=300%2C87&amp;ssl=1 300w, https://i0.wp.com/unskript.com/wp-content/uploads/2023/04/Screenshot-2023-04-04-at-12.14.30.jpg?resize=558%2C162&amp;ssl=1 558w, https://i0.wp.com/unskript.com/wp-content/uploads/2023/04/Screenshot-2023-04-04-at-12.14.30.jpg?resize=24%2C7&amp;ssl=1 24w" sizes="(max-width: 578px) 100vw, 578px" data-recalc-dims="1"></p>
<p>A stale PR almost feels <em>worse</em> than a stale Issue.  When the work is completed, and ready (perhaps nearly ready) to be integrated into the codebase – there is a immediate improvement to the software.  When. PR just languishes, the code does not improve, and sometimes further improvements are blocked   The Action above gives a list of all PRs that are over a threshold (again we use 14 days) for a given GitHub repository. For example:</p>
<pre>{331: '3 cost optimization runbooks'}</pre>
<p> </p>
<p>This output does not provide anyone that I can ‘nudge’, but we have another Action that we can use:</p>
<p><img decoding="async" loading="lazy" src="https://i0.wp.com/unskript.com/wp-content/uploads/2023/04/Screenshot-2023-04-04-at-12.21.47.jpg?resize=638%2C156&amp;ssl=1" alt="Github PR reviewer action" width="638" height="156" srcset="https://i0.wp.com/unskript.com/wp-content/uploads/2023/04/Screenshot-2023-04-04-at-12.21.47.jpg?w=638&amp;ssl=1 638w, https://i0.wp.com/unskript.com/wp-content/uploads/2023/04/Screenshot-2023-04-04-at-12.21.47.jpg?resize=300%2C73&amp;ssl=1 300w, https://i0.wp.com/unskript.com/wp-content/uploads/2023/04/Screenshot-2023-04-04-at-12.21.47.jpg?resize=558%2C136&amp;ssl=1 558w, https://i0.wp.com/unskript.com/wp-content/uploads/2023/04/Screenshot-2023-04-04-at-12.21.47.jpg?resize=24%2C6&amp;ssl=1 24w" sizes="(max-width: 638px) 100vw, 638px" data-recalc-dims="1"></p>
<p>To generate all of the reviewers to nudge, I first create a list of the PR numbers that I obtained from the first Action (the output was named “stalePull”:</p>
<p>oldPRs = []<br>
for pr in stalePull[1]:<br>
oldPRs.append(list(pr.keys())[0])<br>
print(oldPRs)</p>
<p>The Get Pull Request Reviewer Action takes 3 inputs – owner, repository and PR number.</p>
<p>Using the iteration command in unSkript, we can apply the list of pull requests (oldPRs) to the <em>pull_request_number</em> variable:</p>
<p><img decoding="async" loading="lazy" src="https://i0.wp.com/unskript.com/wp-content/uploads/2023/04/Screenshot-2023-04-04-at-12.24.50.jpg?resize=300%2C236&amp;ssl=1" alt="iterating through all the pull requests" width="300" height="236" srcset="https://i0.wp.com/unskript.com/wp-content/uploads/2023/04/Screenshot-2023-04-04-at-12.24.50.jpg?resize=300%2C236&amp;ssl=1 300w, https://i0.wp.com/unskript.com/wp-content/uploads/2023/04/Screenshot-2023-04-04-at-12.24.50.jpg?resize=558%2C439&amp;ssl=1 558w, https://i0.wp.com/unskript.com/wp-content/uploads/2023/04/Screenshot-2023-04-04-at-12.24.50.jpg?resize=655%2C515&amp;ssl=1 655w, https://i0.wp.com/unskript.com/wp-content/uploads/2023/04/Screenshot-2023-04-04-at-12.24.50.jpg?resize=24%2C19&amp;ssl=1 24w, https://i0.wp.com/unskript.com/wp-content/uploads/2023/04/Screenshot-2023-04-04-at-12.24.50.jpg?w=760&amp;ssl=1 760w" sizes="(max-width: 300px) 100vw, 300px" data-recalc-dims="1"></p>
<p>This will call the Action once per pull request – giving a full output of each PR, and who is left to review.</p>
<pre>331: ['jayasimha-raghavan-unskript', 'shloka-bhalgat-unskript']</pre>
<p>With a little Python, we can turn this around to list every user, and the PRs they should look at.</p>
<pre>U03QU1K184X': [267, 153]</pre>
<p>You may notice that the username is different.  This is in anticipation of the next step:</p>
<h2>The actual “nudge”</h2>
<p>Ok, so we know whose issues and PR reviews are overdue.  How do we alert them?  At unSkript, the internal team uses Slack.  I have created a table that compares each Github username with their Slack ID (that’s the weird variable above).</p>
<p>With the slack ID, I can now send a message to the team channel:</p>
<pre>If you are listed below, can you please review the Pull requests next to your name? They have been open for 14 days.

&lt;@U01UG9DRR7D&gt;, please review pull requests [267, 153].
&lt;@U03QU1K184X&gt;, please review pull requests [267, 153].

</pre>
<p>Adding the @ in front of the username creates an “at” in Slack, so these two users have just been effectively nudged to look at their PRs. They have now been nudged in Slack to go into GitHub and take a look at the work that is being forgotten.</p>
<h2>Automating the Nudge!</h2>
<p>Using the Enterprise version (or the <a href="https://us.app.unskript.io/">free trial)</a> of unSkript, you can schedule each RunBook.  The RUnBook I created for Awesome-CloudOps-Automation runs every Wednesday morning – alerting the team that there are some issues and pull requests that have been left behind and should be resolved.</p>
<p><img decoding="async" loading="lazy" src="https://i0.wp.com/unskript.com/wp-content/uploads/2023/04/Screenshot-2023-04-04-at-12.40.41.jpg?resize=945%2C142&amp;ssl=1" alt="Slack Message" width="945" height="142" srcset="https://i0.wp.com/unskript.com/wp-content/uploads/2023/04/Screenshot-2023-04-04-at-12.40.41.jpg?w=1170&amp;ssl=1 1170w, https://i0.wp.com/unskript.com/wp-content/uploads/2023/04/Screenshot-2023-04-04-at-12.40.41.jpg?resize=300%2C45&amp;ssl=1 300w, https://i0.wp.com/unskript.com/wp-content/uploads/2023/04/Screenshot-2023-04-04-at-12.40.41.jpg?resize=1024%2C154&amp;ssl=1 1024w, https://i0.wp.com/unskript.com/wp-content/uploads/2023/04/Screenshot-2023-04-04-at-12.40.41.jpg?resize=768%2C116&amp;ssl=1 768w, https://i0.wp.com/unskript.com/wp-content/uploads/2023/04/Screenshot-2023-04-04-at-12.40.41.jpg?resize=1116%2C168&amp;ssl=1 1116w, https://i0.wp.com/unskript.com/wp-content/uploads/2023/04/Screenshot-2023-04-04-at-12.40.41.jpg?resize=806%2C121&amp;ssl=1 806w, https://i0.wp.com/unskript.com/wp-content/uploads/2023/04/Screenshot-2023-04-04-at-12.40.41.jpg?resize=558%2C84&amp;ssl=1 558w, https://i0.wp.com/unskript.com/wp-content/uploads/2023/04/Screenshot-2023-04-04-at-12.40.41.jpg?resize=655%2C99&amp;ssl=1 655w, https://i0.wp.com/unskript.com/wp-content/uploads/2023/04/Screenshot-2023-04-04-at-12.40.41.jpg?resize=24%2C4&amp;ssl=1 24w" sizes="(max-width: 945px) 100vw, 945px" data-recalc-dims="1"></p>
<p>How do you keep your Github issues and Pull requests chugging along?  Do you have suggestions on how you might improve this RunBook?  We’d love to hear about it in the <a href="https://communityinviter.com/apps/cloud-ops-community/awesome-cloud-automation">unSkript Slack channel</a>. Interested in trying out Github nudges with your team?  All of the Actions described above are in our <a href="https://github.com/unskript/Awesome-CloudOps-Automation">Open source</a> (Docker instructions are in the readme), and in our <a href="https://us.app.unskript.io/">free Trial</a>.</p>