Archive for 2012

Manage GitHub Issues milestones in Trello

In doing product management on an engineering-led project, GitHub Issues rock. The killer features are that it’s a) really simple, b) tightly integrated with code (you can reference/close issues via commit messages), and c) facilitates discussion of issues just like it does of code.

What GitHub Issues suck at is being able to get a high-level view, where you can see more than 30 issues at a time, and broken out by milestone or by person. (You can only filter to see issues for one milestone or one person, but not easily move multiple issues between them.)

I’d really like to see a Trello-style interface for managing GitHub Issues. Some very limited integrations exist, but what I’m looking for would let you quickly move issues around between milestones. This would help plan a product roadmap and be able to visualize what the upcoming milestones look like in one place.

The closest thing I’ve seen is Huboard (GitHub, site, blog post), but it doesn’t do milestones currently [edit: now it does!].

[Edit again: Waffle.io and Gitlo look like more recent tools that would do a good job of this]

Zapier has some existing hooks for both GitHub Issues and Trello, but they seem to all be around creation, rather than a 2 way sync of moving around and editing. It’s possible that some improvements to the Zapier Apps would make the integration possible.

I’m thinking it would make a cool side project to use the Trello API and GitHub API to do this. Basically:

  • Look for all GH issues from a repo with specific labels (whether that be “trello”, “feature”, etc.) – but on big projects you likely don’t want to see every little bug in Trello.
  • To “link” a Trello card to a GH Issue to allow 2-way sync, you could just use the GH Issue # in the card name, like “Add Twitter integration (#187)”, unless Trello support saving some custom source key field.
  • If new cards are created in Trello, their titles should get updated with the GH Issue #, once saved.
  • If new issues are created in GitHub, have them show up in the Trello board in the list corresponding to the milestone or else “No Milestone”.
  • Moving a card from one list to another should change the GH issue milestone, and vice versa.
  • Creating a new list in the board would create a new milestone. Same renaming strategy for milestones as we have for cards/issues.
  • 2-way sync is always tricky and open to conflicts,  but we should be able to just take whichever action had a later updated date.

Anyone have a better idea? Or something I’m missing?

For completeness, there are two other semi-related projects. Hubboard (GitHub, site) seems inactive and also has the same limitation as Huboard. Also 280 North has a very nice looking GitHub Issues viewer (site, GitHub, blog post) but it looks to be completely abandoned and no longer working.

How to unit test AJAX Requests with QUnit and Sinon.JS

We write QUnit tests for Close.io, a big Backbone.js app, to help avoid introducing bugs. Pretty quickly when testing front-end JavaScript code you’ll have to deal with how to test asynchronous callbacks and especially code related to AJAX/XHR requests and how their responses are handled. Here are some basic examples of how to use Sinon.JS to handle this.

Mocking Responses

Have some code that relies on an API response coming back that you want to test? Here’s an example of mocking out the HTTP response to test a Backbone.js Model#fetch() method.

Testing Requests

But what about testing the actual request side of things? A lot of basic tutorials leave this side of the XHR out. When dealing with complicated code it can be non-trivial to determine how the AJAX request is formed, so of course you should test it!

Here’s an example testing that a Backbone.js Model#save() method produces the HTTP request that’s expected. In the real world, the Model would be much less trivial. It relies on the useFakeXMLHttpRequest feature of sinon.

To get more advanced, you can learn about mocks, stubs, and spys in the Sinon.JS documentation.

How to allow direct file uploads from JavaScript to Amazon S3 signed by Python

On Close.io we originally implemented Filepicker.io to allow for file uploads while sending emails. While it was a quick way to get started with file uploading initially, after several minutes of downtime of their API and then an unannounced change in their JSON response format, I was reminded once again that you shouldn’t to rely on small startups for critical parts of your tech infrastructure.

There’s nothing wrong with filepicker.io if you want to use a lot of their features, but in our case we just needed to allow simple uploading of files to our own AWS S3 bucket. Here’s how:

Setup S3 Bucket with CORS Policy

Create an S3 bucket from the AWS Console (if you haven’t already). In its properties, click to Edit CORS Configuration:

This will allow cross-domain posting from the client.

Setup an IAM user
You can use your main AWS credentials, but I recommend generating keys with only the permissions that are necessary. In AWS, setup an IAM user with the following permissions policy.

Add the JavaScript
First grab the code and then implement it on your site:

Server endpoint for signing requests
To protect your AWS user credentials, we keep them on the server and then “sign” each upload right before sending it to S3. Here’s the endpoint in Python / Flask:

Here’s the gist with all the embedded code.

Thanks to CodeArtists for the original tutorial. I improved their code some and converted it to Python.

Guest post on TechCrunch: Full-Stack Web Team

I had my first guest post on TechCrunch last week! Here’s an excerpt:

There is often confusion about the various roles of a web engineering team. I have had to explain, even to technical recruiters, the differences between these roles and that the lines that separate them are often fuzzy. I thought I’d share the framework I like to use to evaluate whether someone is a good fit for a startup’s technical team.

In a startup, you can’t afford to have people who are only able to do one thing. Someone could be adept at writing HTML/CSS, but if they don’t have a great eye for design or know JavaScript well, it’s just not worth having them on the core team. Similarly, somebody who knows a little bit of everything but isn’t advanced in anything will just drag the team down.

The size of the company or startup will determine how many different hats each engineer must wear. Many startups get off the ground with a single founder who does a little bit of everything until he or she can grow the team. It’s also possible to outsource some roles completely. Just as cloud-hosting providers such as Amazon Web Services have drastically reduced the need for hardware/network engineers in web startups, platforms like Heroku take it further and (for a price) can reduce sysadmin and DevOps work almost entirely in the beginning.

In pretty much every case, when a startup grows, people will inevitably start specializing. Even those rare gems, who in the early days can spend the first half of the day in Photoshop and the second half scaling a database, will eventually specialize at least somewhat. If you’re hiring well, you’ll always find someone who can outperform you in at least one area.

I’m a big fan of “full stack” people and think specializing too much, too early, is a bad sign for startups. At Elastic, each of our engineers has written CSS and done database/server management. It’s good when a problem arises for there to be more than one person capable of fixing it. That said, I’m spending the bulk of my day writing in JavaScript/Backbone.js because I enjoy it much more than a coworker who’d rather be in Python as much as possible. That’s healthy and it works.

You can read the rest over there.

Launched Close.io – sales communication software

I just launched a website for Close.io, the product we’ve been working on at Elastic for the past few months.

Go check it out: http://close.io/

We’ve built this as “sales communication software”, which we believe didn’t really exist before. CRMs (salesforce.com, I’m looking at you!) are inadequate because they are more like databases of contacts than software that really helps you do the selling. We’ve trying to change that by making your sales phone calling and sales emailing experience tightly coupled with your lead data (CRM).

Would love to hear any feedback you have about the product!

Mac Software I Use

I just got a sweet new MacBook Pro Retina – way faster than my old MBP. I wanted to do a clean install rather than restoring from a TimeMachine backup, which meant reinstalling software and manually transferring stuff over that I really needed. I kept a list…

Misc apps:

  • Set Screenshot location – store screenshots off desktop
    defaults write com.apple.screencapture location ~/Screenshots/; killall SystemUIServer
  • Window Wrangler – move+resize windows from keyboard
  • Dock Dodger – to keep things like Window Wrangler out of the dock
  • DNSCrypt – encrypted DNS
  • SelfControl – stop myself from getting distracted
  • VLC – play any files. less annoying full-screen mode with multiple monitors.
  • KeyRemap4MacBook – make F4 do Dashboard rather than LaunchPad – I use calculator & calendar a lot
  • CloudApp – easy screenshot + file sharing
  • 1Password – password management
  • Spotify – music

Dev stuff:

Quick notes from Startup School 2012

I got to go to Y Combinator’s Startup School this year and had a great time. Between the reception dinner the night before and the day of event I got to meet a lot of great people and reconnect with some I’d met in the past or only talked to online. Most of the speakers were really good.

I took some very brief notes during some of the talks of the 1 or 2 things that stuck out to me as either surprising, motivational, or instructional.

Zuckerberg: He never thought they’d be the people to build what they knew would eventually exist. They expected someone huge to build it, but it turned out none of them cared as much.

Uber: Doesn’t own any cars or employee any drivers, or spend any marketing money. Avg customer spending $105/mo. 50% of all riders have ridden in the last 30 days.

Jessica Livingson: The keys are determination (resilience + drive), rejection, build something people want

Patrick / Stripe: Trying to be the economic infrastructure of the Internet. Build something that enables others and you’ll succeed. Both are addictive: the day to day debates and the high level strategy stuff.

Horowitz: Create something people don’t even know they want that eventually they will need.

Companies follow extreme power law curve
– Needs to generate $100M in annual revenue
– breakthrough idea
– founder with the courage and skill to build the great idea into a great company
– leadership vs management – can you articulate a vision, get people to work for you, and the confidence to make it all believable

Pinterest: 3000 users within first couple months after launch (but most weren’t very active). However, it was XX months to get there before launching.

Joel Spolsky: Do not straddle the line between get huge fast and bootstrapping. But both are good strategies.

Weebly: Worked on it for 20 months before seeing first real traction! Working business model took 3 years.

Stripe CTF 2.0 – Web Security

I did Stripe’s Capture the Flag 2.0 this year, “a security contest where you can try your hand at discovering and exploiting vulnerabilities in mock web applications”.

It was a lot of fun. Some of the levels were quite challenging and I had to figure out how to actually implement an exploit vulnerability that I’d only read about in passing before. Each level makes you both a) figure out what the vulnerability is, and b) actually exploit it. One thing that the Stripe guys did a nice job at was spreading out the challenges between PHP, browser JavaScript, node.js, Python, and Ruby, so that developers from any one language wouldn’t have an advantage.

I did it during the week and spent a couple hours per night on it. There was SQL injection, unrestricted uploads, XSS attacks, and more. For one level I actually (found out later) solved it in a different way than was intended. I noticed that their client-side sessions/cookies weren’t actually secure because an error debug page leaked their secret token. So I got to dig into some source code and learn a little Ruby.

The last level was definitely the trickiest. My source code solution is below. I got it running locally and it ran fairly quickly — I knew I had the correct solution. But that was only half the battle since, on production, there was a lot more “jitter”. My first solution ran all night and never finished. So I made some tweaks, and eventually turned on HTTP Keep-Alives, which made a huge difference and my solution ran in a much shorter time.

Finally, I captured the flag! I was the 202nd person to complete it. By the end only 978 of about 16,000 participants completed it at all, so I will gladly be wearing my free t-shirt!

Objective Process for Product Reviews

I watched Jeff Veen’s “Designing for Disaster” talk (below) and took away a couple of parts that I thought were really good. Some notes:

How to do Product Reviews (can be design, product, process, anything) — making an objective process out of something that is very subjective.

  • Optional attendance, but mandatory participation (keeps everyone focused)
  • Not a forum for expressing opinions
  • Rather, a place to solve problems.
  • Define in the beginning if session is supposed to be divergent or convergent.
    • Divergent –  I want as many ideas to solve this problem as possible – let’s talk about everything; brainstorming
    • Convergent – Evaluating feasibility, acknowledge constrains. Drive towards consensus.

Driven by Purpose

  • Measure momentum in days (weekly checkup of progress)
  • Measure projects in weeks (figure out pace, when we will go out with the next thing)
  • Measure priorities in months (“we’re going to focus on performance and distribution in Q2”)
  • Measure vision in years (“organize the world’s information and make it universally accessible”)

Uploading static assets (CSS/JS) to S3 for CloudFront CDN

For a new Backbone.js + Flask project I’m using grunt + grunt-contrib, RequireJS’s r.js, Flask-Assets / webassets for static file (LESS/CSS, JS) compilation. But I needed a good way to get my nicely optimized static files onto a CDN and serving proper HTTP headers.

Using the excellent s3cmd tool, here’s what I came up with.

This example will break for browsers/proxies that don’t support gzip, but this is fine for my needs. Any other solution would either require a custom origin web server or writing different filenames in HTML depending on the request coming in. But since I want to use S3 as my origin this is the easiest/simplest solution.

Since all assets are “built” with a md5 version number hash in the file name, I want far futures headers to cache permanently.

PhilFreo.com v3 (and past versions)

I setup my first personal webpage (philfreo.com) in 2004 when I was in high school. It’s had some server-side includes and a tiny amount of logic written in ASP. It looked like this:

I redesigned it once in 2006 during my Yahoo! internship, and it looked like this:

And there my website sat from 2006 until 2012. That’s forever in internet years!

So here we are in the summer of 2012 – time for a redesign! Nothing too fancy, just clean up the styles to be more modern and representative of the current web. It should tell people about the 2012 Phil Freo rather than the high school or college version of me. It should no longer focused on my freelance website design (where I once dominated SEO for terms like “gainesville web design” and “jacksonville web design”) and now more focused on my work with startups, modern full-stack web development, and my blog.

You’re probably looking at the new site now, but for archival purposes, here are some screenshots:

Homepage:

Blog article page:

How to upgrade MacPorts to OS X 10.8 Mountain Lion

This weekend I upgraded OS X from Lion to Mountain Lion. Documenting steps I had to do to get all my development environments working with MacPorts.

Steps:

  • First installed the latest XCode via the Mac App Store
  • Downloaded/Installed Mountain Lion
  • Launched XCode one to so I could agree to license, etc.
  • MacPorts also requires the XCode Command Line tools which are a separate install. Inside XCode preferences: “Instead, they can be installed optionally using the Components tab of the Downloads preferences panel as shown in” (source)
  • Had to run “sudo xcodebuild -license” after getting “Error: org.macports.build for port libunwind-headers returned: command execution failed”. Run this, scroll down, type agree.
  • sudo port selfupdate
  • sudo port upgrade outdated
  • Everything finished and worked properly except MongoDB. Currently there’s a bug and the easiest/best work around seems to be just manually installing the latest stable OS X version from http://www.mongodb.org/downloads and manually copying the binaries into /opt/local

Why is this so hard… Apple

It’s 2012 and the web and mobile devices are capable of amazing things, which is why it’s so surprising to me that some of the simplest things are still so hard.

I’ve got the latest iPhone with its 8MP camera and HD video camera, complete with iOS 5 and I pay for extra storage on iCloud. Apple’s supposed to be the best at designing simple user experiences across hardware and software – and I believe they are.

So when I want to take a bunch of photos and videos that I took from my iPhone and share those with some family members, it should be simple right?

Yet it’s not. Sure, there are some solutions:

  • The “Share” button in iOS that only lets you send one video at a time.
  • Facebook app so you can worry about privacy and exclude your family who’s not on Facebook. And still not easy to upload a bunch of photos/videos.
  • Dropbox app is alright for uploading but then you’re worrying about how much space you’re using (those were HD videos, after all, and you don’t want to reduce quality), you have to wait for uploading, you can’t browse your photos/videos by thumbnails – only filename, and worst of all there’s no easy way to share several photos/videos at once to somebody.
  • Kicksend – getting closer, but can’t send both photos and videos together, can’t compress or send while the app’s not open, and the recipient has to download the files to their computer and open them one at a time. Seems simple enough but that is tough for some people – why can’t there just be a simple way to look at them online?

Even dragging out the USB cord to plug my phone into my MacBook Pro doesn’t yield a simple solution. Open iTunes, iPhoto, etc. – haven’t found the answer. Dropbox comes the closest with its new “Camera Uploads” feature (which has been out less than 1 year) but still doesn’t cut it when it comes to sharing specific photos/videos after uploading.

Here’s what I would hope for from Apple in 2012:

  • Buy latest iPhone.
  • Take photos and videos on iPhone.
  • Tap a couple buttons to select photos and videos to share.
  • Choose who to share them with, press Send.
  • My family gets sent an email link to a webpage with thumbnails of the photos and videos sent, with a one-click way to view each of them. Could even be a native app experience if the recipient is a Mac or iOS user.

What’s important are the things that shouldn’t have to be a part of the process:

  • No large email attachments or file downloading required for the recipients – a web browser can be a great way to browse media and is certainly the simplest, and Apple has already been killing the file metaphor on mobile.
  • No long on-screen waiting for uploading or compressing – Apple is already uploading my stuff in the background for Photo Stream so this should be simple.
  • No special apps to download – Apple has always been a “we take care of all of the basics ourselves” type of company.
  • No worrying about storage space in the cloud – this is 2012 and disk space is super cheap, and I’m already making Apple gobs of money on the hardware. Fine, I’ll pay extra for iCloud even but it shouldn’t be something I could fill up easily like Dropbox. It should feel unlimited.

As a developer and product designer, I recognize that pulling this off is no trivial task. You’d have to design a whole web app for viewing this media, build a super scalable backend to handle it, make iOS changes, etc. Hardest of all you’d have to make sure this fits into a larger product vision.

But surely Apple with its nearly unlimited resources and great talent should be able to. Sadly, as plenty of people have pointed out, they still don’t get the web like they get hardware and software.

That leaves a big hole for other players to fill. Dropbox, Google, Facebook – you’ve been given a big wide open opportunity to shine, but so far have not impressed. So listen up entrepreneurs, Apple executives, and young dreamers: the field is wide open for better products – have at it!

Two Years at Quizlet

The last two years (2010-2011) I spent working at Quizlet were an incredible learning experience.

Like I did in Jan 2010, I wanted to reflect on some of the technologies I learned and things I did over the last 2 years…

Backend:

  • Learned tons about scalability! Scaled Quizlet to serve 11 million visits per months (60 million pageviews, 5 million uniques), serving mostly UGC content with an average page response time of < 50ms.
  • Got very comfortable with understanding and tweaking advanced configuration options of Apache, PHP, & MySQL for desired functionality and scalability requirements
  • Went from a command line beginner to feeling very comfortable in Linux and Solaris, frequently writing bash/shell scripts for common sysadmin tasks, and trying to automate as much as possible.
  • Worked with large data sets: our database had several hundred million rows and was in the dozens of gigabytes in size.
  • Played a dev-ops role and helped transition all production servers to use Puppet for configuration management. Focused on having a process for all server related changes and created the ability to have over a dozen different servers recreate-able in very little time.
  • Learned how to make MySQL fast on a high-trafficked and large database, do replication and have a quick recovery plan. Dealt with configuring databases, designing schemas, and optimizing SQL statements. Also managed our relationship with Percona’s consultants (leading MySQL experts) and learned from them.
  • Automated backups and ensured we had quick access to them in the right places plus securely storing them off-site to Amazon S3 for safety. We had people relying on their data being accessible for studying and thankfully were able to recover quickly from incidents without losing any data.
  • Sphinx Search is a very powerful open source search server good for indexing and quickly searching over MySQL. I learned how to configure it for our purposes and use its various features to power search on millions of rows of Quizlet content in a couple hundred milliseconds.
  • Implemented and used several performance monitoring tools to keep tabs on a heavily trafficked website: Nagios, Munin, New Relic, etc.
  • Learned all about (and implemented) email deliverability best practices: SPF records, DKIM, rDNS, Feedback Loops, IP address reputation, etc.
  • Used several cloud service providers (Joyent, Slicehost, Amazon AWS). Setup reverse proxy CDNs for optimal performance of static files.

Frontend:

  • Major focus on serious performance optimizations across entire stack. Spent time obsessing over how to get an extra 20ms out of a page load from our backend while keeping code clean. Resulted in an average page load of < 50ms across Quizlet.
  • Also became extremely good at front-end performance; Did JavaScript profiling, proper handling of static files, caching headers, etc. Attended Velocity Conferences; Kept tabs on PageSpeed and WebpageTest waterfall results.
  • Used Google Analytics Event Tracking for tracking client-side user events via JavaScript. Good for error detection and user behavior analysis.
  • I already knew PHP well, but I’d say now I’m more of an expert at properly structuring object-oriented PHP5 on a large codebase.
  • Learned all about and then implemented website localization & internationalization (i18n) for Quizlet, helping create a framework for user-generated translation submissions that launched in 7 languages.
  • Got deep into Unicode and character encodings and implemented a language detection system in PHP based on n-grams and character encodings.
  • Spent time optimizing with AdSense – A/B tested with different ad placement, targeting, and IAB ad sizes for better inventory.
  • Wrote a very fast A/B testing framework and used it to optimize our upgrade page for better monetization
  • Went very deep on the MooTools JavaScript library using it to build complex study games. In the past, jQuery has been my JS library of choice, but MooTools is very nice at being object-oriented and not afraid to extend native objects.
  • Used Google Maps & Geocoding  API heavily (JavaScript and PHP) to build an events directory on CollectorsWeekly.
  • Used the Stripe API to accept credit card payments (replacing our previous PayPal solution).
  • Lots of cross-browser CSS – making things look good in browsers both old and new.

Dev Processes:

  • Helped lead the development team with best practices and good processes for coding and communication.
  • Became really good at Git and transitioned our team from SVN/Trac to Git/GitHub. Used git submodules to manage many of our dependancies and became a better open source citizen by submitting pull requests and bug reports in more projects.
  • Did a lot of code reviewing on trac and GitHub with peers and new hires / interns.
  • Introduced unit testing in both PHP (via PHPUnit) and JavaScript (via Jasmine); did some test-driven-development (TDD).
  • Created a safer deployment process which first runs unit tests, PHP Lint, and other sanity checks before deploying.
  • Started daily standups with the eng team to keep everyone up-to-date and on track.

Product:

  • Along with development work, I was doing a lot of Product Management: feature triage and prioritization, tracking roadmaps, deciding among tradeoffs, etc.
  • Huge focus on the user interface: tried to make every new feature high quality and easy to use. Spent a lot of time redoing the user flow of features that already existed to improve their ease of use. Removed clutter and made features that “just work”.
  • Used Photoshop to work on visual improvements — designing or redesigning almost all the main pages and many shared UI components on Quizlet.
  • Brainstormed and implemented game mechanics and other ways to make studying on Quizlet more fun and social.

Business+Management

  • Focused heavily on recruiting other developers, helped create a process for finding potential candidates and putting them through a funnel. Did a lot of technical interviewing by phone/Skype and in-person. Helped build a great team of full-time people and interns.
  • Team building. Helped manage and guide new employees, getting them up to speed and supporting their projects.
  • Did a fair amount of biz dev as well. Negotiated deals for licensing software, worked out details of contracts. Talked with potential partners.
  • Managed projects that other developers were working on, pushing for both code quality, fast completion, and a high quality user experience.
  • Wrote a bunch of Quizlet blog posts about product announcements.

I’m sure I’m missing lots of stuff, and I should probably take even more time to write down some higher level lessons learned about startups. But for now this will do: startups are awesome and the best way to learn a lot of stuff really quickly by doing it. And if you’re lucky like I’ve been, it will be with an awesome team working on a great product used by tons of people.

I’ve recently moved onto a new opportunity that I’m very excited about. But I’m really glad to have been at Quizlet the last two years and I look forward to seeing it continuing to succeed widely!

(P.S., they’re hiring…)