Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
The cobbler's children have no shoes, or building better tools for ourselves
Search
Alex Gaynor
May 30, 2016
Programming
1
220
The cobbler's children have no shoes, or building better tools for ourselves
As delivered at PyCon 2016 in Portland, OR.
Alex Gaynor
May 30, 2016
Tweet
Share
More Decks by Alex Gaynor
See All by Alex Gaynor
Quantifying Memory Unsafety and Reactions to It
alex
0
67
Learning from Failure: Post-mortems
alex
2
260
Techniques for Debugging Hard Problems
alex
1
450
Building Communities with Code Review
alex
4
220
Documenting Domain Specific Knowledge
alex
1
260
Pickles are for Delis, not for Software
alex
0
270
Code Review in Open Source Software
alex
4
700
Why Ruby isn't slow
alex
10
3.6k
PyPy + Swift
alex
2
490
Other Decks in Programming
See All in Programming
try! Swift Tokyo 2024 参加報告 / try! Swift Tokyo 2024 Report
hironytic
0
220
GitHub Copilotのススメ
marcy731
1
220
スクラムガイドのスプリントレトロスペクティブを改めて読みかえしてみた / Re-reading the Sprint Retrospective Section in the Scrum Guide
mackey0225
3
480
PHP8.3の機能を振り返る / Review of PHP 8.3 features
seike460
PRO
1
120
Fast JSX: Don't clone props object #28768
yossydev
1
180
Three ways to use AI on Android: The Good, the Bad and the Ugly
marxallski
0
110
業務ツールとして使うPostman
msys75
0
100
StoreKit2によるiOSのアプリ内課金のリニューアル
kangnux
0
120
SwiftUIで使いやすいToastの作り方 / How to build a Toast system which is easy to use in SwiftUI
lovee
3
170
Tailwind CSSを本気でカスタマイズする方法
fsubal
14
5.5k
R言語の環境構築と基礎 Tokyo.R 112
bob3bob3
0
280
Goのmultiple errorsについて (2024年4月版)
syumai
4
1.2k
Featured
See All Featured
Building Your Own Lightsaber
phodgson
100
5.7k
It's Worth the Effort
3n
180
27k
The MySQL Ecosystem @ GitHub 2015
samlambert
244
12k
ParisWeb 2013: Learning to Love: Crash Course in Emotional UX Design
dotmariusz
104
6.6k
WebSockets: Embracing the real-time Web
robhawkes
59
7k
Adopting Sorbet at Scale
ufuk
69
8.6k
The Invisible Side of Design
smashingmag
294
49k
Documentation Writing (for coders)
carmenintech
60
4k
Facilitating Awesome Meetings
lara
43
5.6k
Scaling GitHub
holman
457
140k
Docker and Python
trallard
35
2.7k
A Tale of Four Properties
chriscoyier
152
22k
Transcript
The cobbler's children have no shoes, or building better tools
for ourselves Alex Gaynor - PyCon 2016
About me • Director of the Python Software Foundation •
Open source contributor • Django, PyPy, CPython, pyca/cryptography, etc. • Washington, D.C. resident • Bagel and deli enthusiast • US Digital Service employee
A short history of tools
$ git init
None
Code review
Deployment automation
Emerging trends
CI for PRs
Linting (flake8, bandit, flake8-import-order, etc.)
Coverage Tracking
livegrep.com
github.com/facebook/mention-bot
Workflow
Build more tailored tools
Automation > Process
APIs!
Issues • Create an issue • Add/remove labels • Add
a comment • Assign to someone
Pull requests • Send a PR • Assign a PR
• Add/remove labels • Leave a code review • Add a commit status
Examples
$ pip install github3.py
import github3 gh_client = github3.login( os.environ["GITHUB_USERNAME"], os.environ["GITHUB_PASSWORD"], )
repo = gh_client.repository("django", "django")
HTTPS certificate expiration
def get_expiration_date(host): ssl_context = ssl.create_default_context() with closing(socket.socket(socket.AF_INET, socket.SOCK_STREAM)) as sock:
sock = ssl_context.wrap_socket(sock, server_hostname=host) sock.connect((host, 443)) expiration = ssl.cert_time_to_seconds(sock.getpeercert()["notAfter"]) return datetime.datetime.fromtimestamp(expiration)
while True: for host in MY_DOMAINS: expiration = get_expiration_date(host) if
expiration - datetime.datetime.now() < CUTOFF: file_an_issue(gh_client, host, expiration) time.sleep(3600)
def file_an_issue(gh_client, host, expiration): gh_client.create_issue( "django", "django", "Cert expiring soon:
{}".format(host), "The cert for `{}` expires on {}, get a new one!".format( host, expiration ), "alex", labels=["ssl-cert"] )
Auto-labeling
Web hooks
def github_webhook(request): event = request.headers.get("X-Github-Event") if event != "pull_request": return
Response(status=200) body = json.load(request.stream) if body.get("action") not in {"opened", "reopened", "synchronize"}: return Response(status=200)
issue = repo.issue(body["number"]) pr = repo.pull_request(issue.number) changed_files = (f.filename for
f in pr.iter_files()) if "django/utils/crypto.py" in changed_files: issue.add_labels("security")
Other ideas
requirements.txt bumper
UI change reviewer
Github Web hook UI Reviewer Comment Screenshots
Approval process commit status
Thanks! Questions? https://github.com/alex https://speakerdeck.com/alex