how we learned to stop worrying and love (or at least live with) github
TRANSCRIPT
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!