How We Learned To Stop Worrying And Love (Or At Least Live With) GitHub Open Source Bridge 2015 Jen Griffin (@kareila) Athena Yao (@afuna) Dreamwidth Studios (dreamwidth.org)
Aug 06, 2015
How We Learned To Stop Worrying And Love (Or At Least Live With) GitHub
Open Source Bridge 2015
Jen Griffin (@kareila)Athena Yao (@afuna)
Dreamwidth Studios (dreamwidth.org)
How We Learned To Stop Worrying And Love (Or At Least Live With)
GitHub
These slides may be downloaded from
http://slideshare.net/dreamwidth
Our code may be downloaded fromhttps://github.com/afuna/ghi-assist
What Is GitHub?
GitHub is the most widely used platform for managing open source projects. It provides:
• source code management• issue management (aka bug tracking)• collaboration tools
Anyone can easily sign up for a free account, modify a copy of an open source project, and request for their changes to be accepted.
Why Use GitHub?
Strengths Weaknesses
• popularity / ubiquity
• ease of use
• powerful features
• limited/difficult customization
• Git (SCM) is hard
• all-or-nothing permissions
It is possible to use GitHub as a basic code repository and use other products for the rest of your project’s workflow.
Case History: Dreamwidth
• 2008: self-hosted Mercurial + Bugzilla
• 2012: GitHub + Bugzilla
• 2014: GitHub only
Our code’s migration was planned and orderly.
Switching issue trackers was not.
Why Did We Wait?
• More Flexible, Powerful Metadata
• Easier Drop-In Contributions
• Better Permissions & Privacy
Bottom line: Bugzilla is a more fully featured bug tracker than GitHub Issues.
Considering Our Options
• Start again with Bugzilla - rejected because we didn’t want to continue self-hosting
• Use a different hosted bug tracker - rejected because we couldn’t find anything that fit our needs (YMMV)
• Set up an issues-only GitHub repo with admin access for all - rejected as messy and confusing
• What we finally decided - use GitHub Issues normally and do our best to work around rough spots
GitHub Permissions (For Teams)
• Anyone: can browse, create and comment on issues, fork the code, and submit pull requests.
• Members: can also have issues assigned to them by admins and be referenced by name in comments.
• Admins: can commit code changes and make changes to issues, including labels and assignments.
Permissions: What We Wanted
• Anyone: can browse, create and comment on issues, fork the code, and submit pull requests.
• Members: can also assign issues to themselves, be referenced by name in comments, and categorize existing issues with labels.
• Admins: can commit code changes and make changes to issues, including labels and assignments.
Enter The API
GitHub provides a programming interface for interacting with issues
and pull requests:https://developer.github.com/
Notifications are sent when items are opened, closed, or commented on. Since anyone can comment, anyone can trigger API actions via specially formatted comments!
How It Works
• The service is similar to a chatbot. It listens for GitHub API events and responds as desired.
• In order to execute the requested actions, it will need to be linked to a GitHub account that has access to commit the changes.
• You will probably want to give it a name that makes clear it is an automated process.
Currently Defined Actions
Assign Related Issue: If a pull request claims to fix an issue, assign the issue to the author
Claim Issue: Assign[*] issue to anyone who leaves a comment saying “claim”, “claiming” or “claimed”
Add Labels: Labels can be added via comments by prefixing the name of the label (##labelname)
Stop! Demo Time!
Flow of Control
Anatomy of a Webhook
1. Verify request came from GitHub2. Determine event type3. Do some action based on the
payload contents
def signature_valid(self, data=None, signed_data=None, digest=sha1):
mac = hmac.new(self.secret, msg=data,
digestmod=digest) try: return hmac.compare_digest(
mac.hexdigest(), signed_data)
except AttributeError: # < Python 2.7.7 return mac.hexdigest() == signed_data
signature_header = request.headers.get('X-Hub-Signature')
digest, signature = signature_header.split('=’)
if digest != "sha1": abort(501, "'%s' not supported." % digest)
if not webhook.signature_valid( data=request.body.read(),
signed_data=signature): abort(403, "Signature does not match expected value.")
Anatomy of a Webhook
1. Verify request came from GitHub2. Determine event type3. Do some action based on the
payload contents
event = request.headers.get('X-GitHub-
Event')
Anatomy of a Webhook
1. Verify request came from GitHub2. Determine event type3. Do some action based on the
payload contents
CLAIM_PATTERN = re.compile(r'\bclaim(?:ed|ing)?\b', re.I)
class ClaimHook(Hook): def should_perform_action(self, payload, api):
if payload["issue"]["assignee"] is None \
and CLAIM_PATTERN.search( payload["comment"]["body"]): return True else: return False
headers = { 'User-Agent': "GHI Assist Bot",
'Authorization': "token %s" % self.token, }response = requests.request("PATCH","https://api.github.com…",
headers=headers, data=json.dumps({"assignee": assignee}))
Resources
Code for our GitHub assistant:https://github.com/afuna/ghi-assist
GitHub’s API reference:https://developer.github.com/
Download link for our slides:http://slideshare.net/dreamwidth
Any Questions?
You can find us onDreamwidth, GitHub, and Twitter:
Jen Griffin ([email protected])Athena Yao ([email protected])
Thank you for coming!