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 buildi...
Search
Sponsored
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
Alex Gaynor
May 30, 2016
Programming
300
1
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
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
More Decks by Alex Gaynor
See All by Alex Gaynor
Quantifying Memory Unsafety and Reactions to It
alex
0
150
Learning from Failure: Post-mortems
alex
2
360
Techniques for Debugging Hard Problems
alex
1
660
Building Communities with Code Review
alex
4
340
Documenting Domain Specific Knowledge
alex
1
440
Pickles are for Delis, not for Software
alex
0
560
Code Review in Open Source Software
alex
4
820
Why Ruby isn't slow
alex
10
3.9k
PyPy + Swift
alex
2
590
Other Decks in Programming
See All in Programming
PyConJP2026_wat_Python × Signal Processing: How to Draw Pictures with Sound Using Spectrogram Art
wat
0
420
Press start. Python's next generation.
willingc
PRO
3
150
PostgreSQL 18で考えるUUID主キー
kazuhiro1982
0
500
DynamoDBの基礎を振り返りながらベクトル検索機能を理解する
musan
2
210
人間の目はかわらない、だからJPEGは30年もつ
yuzneri
12
19k
AIと壁打ちしながら進めるコスト管理
fufuhu
2
1.7k
「人を評価する AI」の設計と実装
ryoyanara
0
240
React本体のコードリーディング
high_g_engineer
1
160
AI Readyの正体はデータマネジメントだ メダリオン2.0の最前線
freee
PRO
0
390
ドリフトを絶対に許さない(?)CDK運用 / CDK Ops with Zero Tolerance for Drifts (?)
akihisaikeda
1
230
go-spidermonkeyでAIエージェントのCode Modeを実装する
syumai
2
1.2k
KotlinConf Extended South Korea 2026 Keynote
l2hyunwoo
0
120
Featured
See All Featured
Money Talks: Using Revenue to Get Sh*t Done
nikkihalliwell
0
470
brightonSEO & MeasureFest 2025 - Christian Goodrich - Winning strategies for Black Friday CRO & PPC
cargoodrich
3
790
Designing Powerful Visuals for Engaging Learning
tmiket
1
510
Performance Is Good for Brains [We Love Speed 2024]
tammyeverts
12
1.8k
Art, The Web, and Tiny UX
lynnandtonic
304
22k
Chrome DevTools: State of the Union 2024 - Debugging React & Beyond
addyosmani
10
1.3k
What's in a price? How to price your products and services
michaelherold
247
13k
Improving Core Web Vitals using Speculation Rules API
sergeychernyshev
21
1.6k
Building Experiences: Design Systems, User Experience, and Full Site Editing
marktimemedia
0
580
Being A Developer After 40
akosma
91
590k
Rails Girls Zürich Keynote
gr2m
96
14k
世界の人気アプリ100個を分析して見えたペイウォール設計の心得
akihiro_kokubo
PRO
73
41k
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